Verification run #1, ipi and no-ipi results
authorMathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Sat, 30 May 2009 22:31:09 +0000 (18:31 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Sat, 30 May 2009 22:31:09 +0000 (18:31 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
129 files changed:
formal-model/results/urcu-controldataflow-ipi/.input.spin [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/DEFINES [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/Makefile [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/asserts.log [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/asserts.spin.input [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/references.txt [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu.sh [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu.spin [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu.spin.bkp.b4ptr [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_free.log [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_free.ltl [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_free.spin.input [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_free.spin.input.trail [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_free_nested.define [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_free_no_mb.define [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_free_no_mb.log [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_free_no_mb.spin.input [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_free_no_mb.spin.input.trail [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_free_no_rmb.define [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_free_no_rmb.log [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_free_no_rmb.spin.input [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_free_no_rmb.spin.input.trail [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_free_no_wmb.define [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_free_no_wmb.log [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_free_no_wmb.spin.input [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_free_no_wmb.spin.input.trail [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_free_single_flip.define [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_free_single_flip.log [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_free_single_flip.spin.input [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_free_single_flip.spin.input.trail [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_progress.ltl [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_progress_reader.define [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_progress_reader.log [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_progress_reader.spin.input [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_progress_reader.spin.input.trail [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_progress_writer.define [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_progress_writer.log [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_progress_writer.spin.input [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_progress_writer.spin.input.trail [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_progress_writer_error.define [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_progress_writer_error.log [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_progress_writer_error.spin.input [new file with mode: 0644]
formal-model/results/urcu-controldataflow-ipi/urcu_progress_writer_error.spin.input.trail [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/.input.spin [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/DEFINES [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/Makefile [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/asserts.log [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/asserts.spin.input [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/references.txt [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/DEFINES [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/Makefile [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/references.txt [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/result-ipi-urcu_free/DEFINES [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/result-ipi-urcu_free/Makefile [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/result-ipi-urcu_free/asserts.log [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/result-ipi-urcu_free/asserts.spin.input [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/result-ipi-urcu_free/references.txt [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu.sh [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu.spin [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu.spin.bkp.b4ptr [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free.log [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free.ltl [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free.spin.input [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free.spin.input.trail [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_nested.define [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_mb.define [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_mb.log [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_mb.spin.input [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_mb.spin.input.trail [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_rmb.define [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_rmb.log [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_rmb.spin.input [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_rmb.spin.input.trail [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_wmb.define [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_wmb.log [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_wmb.spin.input [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_wmb.spin.input.trail [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_single_flip.define [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_single_flip.log [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_single_flip.spin.input [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_single_flip.spin.input.trail [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress.ltl [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_reader.define [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_reader.log [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_reader.spin.input [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_reader.spin.input.trail [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_writer.define [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_writer.log [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_writer.spin.input [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_writer.spin.input.trail [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_writer_error.define [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_writer_error.log [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_writer_error.spin.input [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_writer_error.spin.input.trail [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/todo.sh [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu.sh [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu.spin [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu.spin.bkp.b4ptr [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu_free.log [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu_free.ltl [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu_free.spin.input [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu_free_nested.define [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_mb.define [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_mb.log [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_mb.spin.input [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_mb.spin.input.trail [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_rmb.define [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_rmb.log [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_rmb.spin.input [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_rmb.spin.input.trail [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_wmb.define [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_wmb.log [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_wmb.spin.input [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_wmb.spin.input.trail [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu_free_single_flip.define [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu_free_single_flip.log [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu_free_single_flip.spin.input [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu_free_single_flip.spin.input.trail [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu_progress.ltl [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu_progress_reader.define [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu_progress_reader.log [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu_progress_reader.spin.input [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu_progress_writer.define [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu_progress_writer.log [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu_progress_writer.spin.input [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu_progress_writer_error.define [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu_progress_writer_error.log [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu_progress_writer_error.spin.input [new file with mode: 0644]
formal-model/results/urcu-controldataflow-no-ipi/urcu_progress_writer_error.spin.input.trail [new file with mode: 0644]

diff --git a/formal-model/results/urcu-controldataflow-ipi/.input.spin b/formal-model/results/urcu-controldataflow-ipi/.input.spin
new file mode 100644 (file)
index 0000000..4640ac9
--- /dev/null
@@ -0,0 +1,1239 @@
+
+// Poison value for freed memory
+#define POISON 1
+// Memory with correct data
+#define WINE 0
+#define SLAB_SIZE 2
+
+#define read_poison    (data_read_first[0] == POISON || data_read_second[0] == POISON)
+
+#define RCU_GP_CTR_BIT (1 << 7)
+#define RCU_GP_CTR_NEST_MASK (RCU_GP_CTR_BIT - 1)
+
+//disabled
+#define REMOTE_BARRIERS
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+typedef per_proc_bit {
+       bit val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bitfield {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bitfield cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               /*
+                * 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, j);
+               reader_barrier[get_readerid()] = 0;
+       :: 1 ->
+               /*
+                * 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)
+//#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);                                                           \
+       i = 0;                                                                  \
+       do                                                                      \
+       :: i < NR_READERS ->                                                    \
+               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.                                            \
+                */                                                             \
+               do                                                              \
+               :: (reader_barrier[i] == 1) ->                                  \
+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(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, smp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only one reader */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* RCU data */
+DECLARE_CACHED_VAR(bit, rcu_data[SLAB_SIZE]);
+
+/* RCU pointer */
+#if (SLAB_SIZE == 2)
+DECLARE_CACHED_VAR(bit, rcu_ptr);
+bit ptr_read_first[NR_READERS];
+bit ptr_read_second[NR_READERS];
+#else
+DECLARE_CACHED_VAR(byte, rcu_ptr);
+byte ptr_read_first[NR_READERS];
+byte ptr_read_second[NR_READERS];
+#endif
+
+bit data_read_first[NR_READERS];
+bit data_read_second[NR_READERS];
+
+bit init_done = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               ptr_read_first[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb1;
+rmb1_end:
+                               data_read_first[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_first[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               ptr_read_second[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb2;
+rmb2_end:
+                               data_read_second[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_second[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+rmb1:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb1_end;
+rmb2:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_DATA                     (1 << 1)
+#define WRITE_PROC_WMB                 (1 << 2)
+#define WRITE_XCHG_PTR                 (1 << 3)
+
+#define WRITE_PROC_FIRST_MB            (1 << 4)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 5)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 6)
+#define WRITE_PROC_FIRST_WAIT          (1 << 7)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 8)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 9)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 10)
+#define WRITE_PROC_SECOND_WAIT         (1 << 11)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 12)
+
+#define WRITE_PROC_SECOND_MB           (1 << 13)
+
+#define WRITE_FREE                     (1 << 14)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_DATA                    \
+                                       | WRITE_PROC_WMB                \
+                                       | WRITE_XCHG_PTR                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB          \
+                                       | WRITE_FREE)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 15) - 1)
+
+/*
+ * Mutexes are implied around writer execution. A single writer at a time.
+ */
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte cur_data = 0, old_data, loop_nr = 0;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (loop_nr < 3) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               loop_nr = loop_nr + 1;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_WMB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+#endif
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_DATA) ->
+                       ooo_mem(i);
+                       cur_data = (cur_data + 1) % SLAB_SIZE;
+                       WRITE_CACHED_VAR(rcu_data[cur_data], WINE);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_DATA);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA,
+                                 WRITE_PROC_WMB) ->
+                       smp_wmb(i, j);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_WMB,
+                                 WRITE_XCHG_PTR) ->
+                       /* rcu_xchg_pointer() */
+                       atomic {
+                               old_data = READ_CACHED_VAR(rcu_ptr);
+                               WRITE_CACHED_VAR(rcu_ptr, cur_data);
+                       }
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_XCHG_PTR);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_WMB      /* No dependency on
+                                                        * WRITE_DATA because we
+                                                        * write to a
+                                                        * different location. */
+                                 | WRITE_PROC_SECOND_MB
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_FREE) ->
+                       WRITE_CACHED_VAR(rcu_data[old_data], POISON);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_FREE);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+               /*
+                * Note : Promela model adds implicit serialization of the
+                * WRITE_FREE instruction. Normally, it would be permitted to
+                * spill on the next loop execution. Given the validation we do
+                * checks for the data entry read to be poisoned, it's ok if
+                * we do not check "late arriving" memory poisoning.
+                */
+       :: 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
+#ifdef READER_PROGRESS
+               /*
+                * Make sure we don't block the reader's progress.
+                */
+               smp_mb_send(i, j, 5);
+#endif
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(rcu_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       ptr_read_first[i] = 1;
+                       ptr_read_second[i] = 1;
+                       data_read_first[i] = WINE;
+                       data_read_second[i] = WINE;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               INIT_CACHED_VAR(rcu_data[0], WINE, j);
+               i = 1;
+               do
+               :: i < SLAB_SIZE ->
+                       INIT_CACHED_VAR(rcu_data[i], POISON, j);
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-ipi/DEFINES b/formal-model/results/urcu-controldataflow-ipi/DEFINES
new file mode 100644 (file)
index 0000000..980fad6
--- /dev/null
@@ -0,0 +1,14 @@
+
+// Poison value for freed memory
+#define POISON 1
+// Memory with correct data
+#define WINE 0
+#define SLAB_SIZE 2
+
+#define read_poison    (data_read_first[0] == POISON || data_read_second[0] == POISON)
+
+#define RCU_GP_CTR_BIT (1 << 7)
+#define RCU_GP_CTR_NEST_MASK (RCU_GP_CTR_BIT - 1)
+
+//disabled
+#define REMOTE_BARRIERS
diff --git a/formal-model/results/urcu-controldataflow-ipi/Makefile b/formal-model/results/urcu-controldataflow-ipi/Makefile
new file mode 100644 (file)
index 0000000..de47dff
--- /dev/null
@@ -0,0 +1,170 @@
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Copyright (C) Mathieu Desnoyers, 2009
+#
+# Authors: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+
+#CFLAGS=-DSAFETY
+#for multi-core verif, 15.5GB shared mem, use files if full
+#CFLAGS=-DHASH64 -DMEMLIM=15500 -DNCORE=2
+#CFLAGS=-DHASH64 -DCOLLAPSE -DMA=88 -DMEMLIM=15500 -DNCORE=8
+
+#liveness
+#CFLAGS=-DHASH64 -DCOLLAPSE -DMA=88
+CFLAGS=-DHASH64
+
+SPINFILE=urcu.spin
+
+default:
+       make urcu_free | tee urcu_free.log
+       make urcu_free_no_mb | tee urcu_free_no_mb.log
+       make urcu_free_no_rmb | tee urcu_free_no_rmb.log
+       make urcu_free_no_wmb | tee urcu_free_no_wmb.log
+       make urcu_free_single_flip | tee urcu_free_single_flip.log
+       make urcu_progress_writer | tee urcu_progress_writer.log
+       make urcu_progress_reader | tee urcu_progress_reader.log
+       make urcu_progress_writer_error | tee urcu_progress_writer_error.log
+       make asserts | tee asserts.log
+       make summary
+
+#show trail : spin -v -t -N pan.ltl input.spin
+# after each individual make.
+
+summary:
+       @echo
+       @echo "Verification summary"
+       @grep errors: *.log
+
+asserts: clean
+       cat DEFINES > .input.spin
+       cat ${SPINFILE} >> .input.spin
+       rm -f .input.spin.trail
+       spin -a -X .input.spin
+       gcc -O2 -w ${CFLAGS} -DSAFETY -o pan pan.c
+       ./pan -v -c1 -X -m10000000 -w20
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_free: clean urcu_free_ltl run
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_free_nested: clean urcu_free_ltl urcu_free_nested_define run
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_free_nested_define:
+       cp urcu_free_nested.define .input.define
+
+urcu_free_no_rmb: clean urcu_free_ltl urcu_free_no_rmb_define run
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_free_no_rmb_define:
+       cp urcu_free_no_rmb.define .input.define
+
+urcu_free_no_wmb: clean urcu_free_ltl urcu_free_no_wmb_define run
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_free_no_wmb_define:
+       cp urcu_free_no_wmb.define .input.define
+
+urcu_free_no_mb: clean urcu_free_ltl urcu_free_no_mb_define run
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_free_no_mb_define:
+       cp urcu_free_no_mb.define .input.define
+
+urcu_free_single_flip: clean urcu_free_ltl urcu_free_single_flip_define run
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_free_single_flip_define:
+       cp urcu_free_single_flip.define .input.define
+
+urcu_free_ltl:
+       touch .input.define
+       cat .input.define >> pan.ltl
+       cat DEFINES >> pan.ltl
+       spin -f "!(`cat urcu_free.ltl | grep -v ^//`)" >> pan.ltl
+
+# Progress checks
+
+urcu_progress_writer: clean urcu_progress_writer_ltl \
+               urcu_progress_writer_define run_weak_fair
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_progress_writer_define:
+       cp urcu_progress_writer.define .input.define
+
+urcu_progress_writer_ltl:
+       touch .input.define
+       cat .input.define > pan.ltl
+       cat DEFINES >> pan.ltl
+       spin -f "!(`cat urcu_progress.ltl | grep -v ^//`)" >> pan.ltl
+
+urcu_progress_reader: clean urcu_progress_reader_ltl \
+               urcu_progress_reader_define run_weak_fair
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_progress_reader_define:
+       cp urcu_progress_reader.define .input.define
+
+urcu_progress_reader_ltl:
+       touch .input.define
+       cat .input.define > pan.ltl
+       cat DEFINES >> pan.ltl
+       spin -f "!(`cat urcu_progress.ltl | grep -v ^//`)" >> pan.ltl
+
+urcu_progress_writer_error: clean urcu_progress_writer_error_ltl \
+               urcu_progress_writer_error_define run_weak_fair
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_progress_writer_error_define:
+       cp urcu_progress_writer_error.define .input.define
+
+urcu_progress_writer_error_ltl:
+       touch .input.define
+       cat .input.define > pan.ltl
+       cat DEFINES >> pan.ltl
+       spin -f "!(`cat urcu_progress.ltl | grep -v ^//`)" >> pan.ltl
+
+
+run_weak_fair: pan
+       ./pan -a -f -v -c1 -X -m10000000 -w20
+
+run: pan
+       ./pan -a -v -c1 -X -m10000000 -w20
+
+pan: pan.c
+       gcc -O2 -w ${CFLAGS} -o pan pan.c
+
+pan.c: pan.ltl ${SPINFILE}
+       cat .input.define > .input.spin
+       cat DEFINES >> .input.spin
+       cat ${SPINFILE} >> .input.spin
+       rm -f .input.spin.trail
+       spin -a -X -N pan.ltl .input.spin
+
+.PHONY: clean default distclean summary
+clean:
+       rm -f pan* trail.out .input.spin* *.spin.trail .input.define
+distclean:
+       rm -f *.trail *.input *.log
diff --git a/formal-model/results/urcu-controldataflow-ipi/asserts.log b/formal-model/results/urcu-controldataflow-ipi/asserts.log
new file mode 100644 (file)
index 0000000..98a269c
--- /dev/null
@@ -0,0 +1,522 @@
+rm -f pan* trail.out .input.spin* *.spin.trail .input.define
+cat DEFINES > .input.spin
+cat urcu.spin >> .input.spin
+rm -f .input.spin.trail
+spin -a -X .input.spin
+Exit-Status 0
+gcc -O2 -w -DHASH64 -DSAFETY -o pan pan.c
+./pan -v -c1 -X -m10000000 -w20
+Depth=    5832 States=    1e+06 Transitions= 1.25e+08 Memory=   542.717        t=    123 R=   8e+03
+Depth=    5832 States=    2e+06 Transitions= 4.09e+08 Memory=   618.986        t=    417 R=   5e+03
+Depth=    5832 States=    3e+06 Transitions= 6.64e+08 Memory=   695.256        t=    685 R=   4e+03
+pan: resizing hashtable to -w22..  done
+Depth=    5832 States=    4e+06 Transitions= 1.15e+09 Memory=   802.647        t= 1.2e+03 R=   3e+03
+Depth=    5832 States=    5e+06 Transitions= 1.46e+09 Memory=   878.916        t= 1.52e+03 R=   3e+03
+Depth=    5832 States=    6e+06 Transitions= 1.66e+09 Memory=   955.186        t= 1.72e+03 R=   3e+03
+Depth=    5832 States=    7e+06 Transitions= 1.86e+09 Memory=  1031.455        t= 1.93e+03 R=   4e+03
+Depth=    5832 States=    8e+06 Transitions= 2.13e+09 Memory=  1107.822        t= 2.22e+03 R=   4e+03
+Depth=    5832 States=    9e+06 Transitions= 2.38e+09 Memory=  1184.092        t= 2.49e+03 R=   4e+03
+pan: resizing hashtable to -w24..  done
+Depth=    5832 States=    1e+07 Transitions= 2.87e+09 Memory=  1384.455        t=  3e+03 R=   3e+03
+Depth=    5832 States=  1.1e+07 Transitions= 3.15e+09 Memory=  1460.725        t= 3.29e+03 R=   3e+03
+Depth=    5832 States=  1.2e+07 Transitions= 3.42e+09 Memory=  1536.994        t= 3.57e+03 R=   3e+03
+Depth=    5832 States=  1.3e+07 Transitions= 3.62e+09 Memory=  1613.361        t= 3.77e+03 R=   3e+03
+Depth=    5832 States=  1.4e+07 Transitions= 3.84e+09 Memory=  1689.631        t= 3.99e+03 R=   4e+03
+Depth=    5832 States=  1.5e+07 Transitions= 4.13e+09 Memory=  1765.901        t= 4.29e+03 R=   3e+03
+
+(Spin Version 5.1.7 -- 23 December 2008)
+       + Partial Order Reduction
+
+Full statespace search for:
+       never claim             - (none specified)
+       assertion violations    +
+       cycle checks            - (disabled by -DSAFETY)
+       invalid end states      +
+
+State-vector 72 byte, depth reached 5832, errors: 0
+ 15444143 states, stored
+4.2527754e+09 states, matched
+4.2682195e+09 transitions (= stored+matched)
+2.483245e+10 atomic steps
+hash conflicts: 2.790927e+09 (resolved)
+
+Stats on memory usage (in Megabytes):
+ 1472.868      equivalent memory usage for states (stored*(State-vector + overhead))
+ 1214.135      actual memory usage for states (compression: 82.43%)
+               state-vector as stored = 54 byte + 28 byte overhead
+  128.000      memory used for hash table (-w24)
+  457.764      memory used for DFS stack (-m10000000)
+ 1799.787      total actual memory usage
+
+unreached in proctype urcu_reader
+       line 249, ".input.spin", state 30, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 257, ".input.spin", state 52, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, ".input.spin", state 61, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, ".input.spin", state 77, "(1)"
+       line 230, ".input.spin", state 85, "(1)"
+       line 234, ".input.spin", state 97, "(1)"
+       line 238, ".input.spin", state 105, "(1)"
+       line 394, ".input.spin", state 131, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 163, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 177, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 196, "(1)"
+       line 420, ".input.spin", state 226, "(1)"
+       line 424, ".input.spin", state 239, "(1)"
+       line 669, ".input.spin", state 260, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<1))"
+       line 394, ".input.spin", state 267, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 299, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 313, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 332, "(1)"
+       line 420, ".input.spin", state 362, "(1)"
+       line 424, ".input.spin", state 375, "(1)"
+       line 394, ".input.spin", state 396, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 428, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 442, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 461, "(1)"
+       line 420, ".input.spin", state 491, "(1)"
+       line 424, ".input.spin", state 504, "(1)"
+       line 394, ".input.spin", state 527, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 394, ".input.spin", state 529, "(1)"
+       line 394, ".input.spin", state 530, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 394, ".input.spin", state 530, "else"
+       line 394, ".input.spin", state 533, "(1)"
+       line 398, ".input.spin", state 541, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 398, ".input.spin", state 543, "(1)"
+       line 398, ".input.spin", state 544, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 398, ".input.spin", state 544, "else"
+       line 398, ".input.spin", state 547, "(1)"
+       line 398, ".input.spin", state 548, "(1)"
+       line 398, ".input.spin", state 548, "(1)"
+       line 396, ".input.spin", state 553, "((i<1))"
+       line 396, ".input.spin", state 553, "((i>=1))"
+       line 403, ".input.spin", state 559, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 561, "(1)"
+       line 403, ".input.spin", state 562, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 403, ".input.spin", state 562, "else"
+       line 403, ".input.spin", state 565, "(1)"
+       line 403, ".input.spin", state 566, "(1)"
+       line 403, ".input.spin", state 566, "(1)"
+       line 407, ".input.spin", state 573, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 575, "(1)"
+       line 407, ".input.spin", state 576, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 407, ".input.spin", state 576, "else"
+       line 407, ".input.spin", state 579, "(1)"
+       line 407, ".input.spin", state 580, "(1)"
+       line 407, ".input.spin", state 580, "(1)"
+       line 405, ".input.spin", state 585, "((i<2))"
+       line 405, ".input.spin", state 585, "((i>=2))"
+       line 411, ".input.spin", state 592, "(1)"
+       line 411, ".input.spin", state 593, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 411, ".input.spin", state 593, "else"
+       line 411, ".input.spin", state 596, "(1)"
+       line 411, ".input.spin", state 597, "(1)"
+       line 411, ".input.spin", state 597, "(1)"
+       line 415, ".input.spin", state 605, "(1)"
+       line 415, ".input.spin", state 606, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 415, ".input.spin", state 606, "else"
+       line 415, ".input.spin", state 609, "(1)"
+       line 415, ".input.spin", state 610, "(1)"
+       line 415, ".input.spin", state 610, "(1)"
+       line 413, ".input.spin", state 615, "((i<1))"
+       line 413, ".input.spin", state 615, "((i>=1))"
+       line 420, ".input.spin", state 622, "(1)"
+       line 420, ".input.spin", state 623, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 420, ".input.spin", state 623, "else"
+       line 420, ".input.spin", state 626, "(1)"
+       line 420, ".input.spin", state 627, "(1)"
+       line 420, ".input.spin", state 627, "(1)"
+       line 424, ".input.spin", state 635, "(1)"
+       line 424, ".input.spin", state 636, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 424, ".input.spin", state 636, "else"
+       line 424, ".input.spin", state 639, "(1)"
+       line 424, ".input.spin", state 640, "(1)"
+       line 424, ".input.spin", state 640, "(1)"
+       line 422, ".input.spin", state 645, "((i<2))"
+       line 422, ".input.spin", state 645, "((i>=2))"
+       line 429, ".input.spin", state 649, "(1)"
+       line 429, ".input.spin", state 649, "(1)"
+       line 669, ".input.spin", state 652, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 669, ".input.spin", state 653, "_proc_urcu_reader = (_proc_urcu_reader|(1<<5))"
+       line 669, ".input.spin", state 654, "(1)"
+       line 394, ".input.spin", state 661, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 693, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 707, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 726, "(1)"
+       line 420, ".input.spin", state 756, "(1)"
+       line 424, ".input.spin", state 769, "(1)"
+       line 394, ".input.spin", state 797, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 394, ".input.spin", state 799, "(1)"
+       line 394, ".input.spin", state 800, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 394, ".input.spin", state 800, "else"
+       line 394, ".input.spin", state 803, "(1)"
+       line 398, ".input.spin", state 811, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 398, ".input.spin", state 813, "(1)"
+       line 398, ".input.spin", state 814, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 398, ".input.spin", state 814, "else"
+       line 398, ".input.spin", state 817, "(1)"
+       line 398, ".input.spin", state 818, "(1)"
+       line 398, ".input.spin", state 818, "(1)"
+       line 396, ".input.spin", state 823, "((i<1))"
+       line 396, ".input.spin", state 823, "((i>=1))"
+       line 403, ".input.spin", state 829, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 831, "(1)"
+       line 403, ".input.spin", state 832, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 403, ".input.spin", state 832, "else"
+       line 403, ".input.spin", state 835, "(1)"
+       line 403, ".input.spin", state 836, "(1)"
+       line 403, ".input.spin", state 836, "(1)"
+       line 407, ".input.spin", state 843, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 845, "(1)"
+       line 407, ".input.spin", state 846, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 407, ".input.spin", state 846, "else"
+       line 407, ".input.spin", state 849, "(1)"
+       line 407, ".input.spin", state 850, "(1)"
+       line 407, ".input.spin", state 850, "(1)"
+       line 405, ".input.spin", state 855, "((i<2))"
+       line 405, ".input.spin", state 855, "((i>=2))"
+       line 411, ".input.spin", state 862, "(1)"
+       line 411, ".input.spin", state 863, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 411, ".input.spin", state 863, "else"
+       line 411, ".input.spin", state 866, "(1)"
+       line 411, ".input.spin", state 867, "(1)"
+       line 411, ".input.spin", state 867, "(1)"
+       line 415, ".input.spin", state 875, "(1)"
+       line 415, ".input.spin", state 876, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 415, ".input.spin", state 876, "else"
+       line 415, ".input.spin", state 879, "(1)"
+       line 415, ".input.spin", state 880, "(1)"
+       line 415, ".input.spin", state 880, "(1)"
+       line 413, ".input.spin", state 885, "((i<1))"
+       line 413, ".input.spin", state 885, "((i>=1))"
+       line 420, ".input.spin", state 892, "(1)"
+       line 420, ".input.spin", state 893, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 420, ".input.spin", state 893, "else"
+       line 420, ".input.spin", state 896, "(1)"
+       line 420, ".input.spin", state 897, "(1)"
+       line 420, ".input.spin", state 897, "(1)"
+       line 424, ".input.spin", state 905, "(1)"
+       line 424, ".input.spin", state 906, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 424, ".input.spin", state 906, "else"
+       line 424, ".input.spin", state 909, "(1)"
+       line 424, ".input.spin", state 910, "(1)"
+       line 424, ".input.spin", state 910, "(1)"
+       line 429, ".input.spin", state 919, "(1)"
+       line 429, ".input.spin", state 919, "(1)"
+       line 394, ".input.spin", state 926, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 394, ".input.spin", state 928, "(1)"
+       line 394, ".input.spin", state 929, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 394, ".input.spin", state 929, "else"
+       line 394, ".input.spin", state 932, "(1)"
+       line 398, ".input.spin", state 940, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 398, ".input.spin", state 942, "(1)"
+       line 398, ".input.spin", state 943, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 398, ".input.spin", state 943, "else"
+       line 398, ".input.spin", state 946, "(1)"
+       line 398, ".input.spin", state 947, "(1)"
+       line 398, ".input.spin", state 947, "(1)"
+       line 396, ".input.spin", state 952, "((i<1))"
+       line 396, ".input.spin", state 952, "((i>=1))"
+       line 403, ".input.spin", state 958, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 960, "(1)"
+       line 403, ".input.spin", state 961, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 403, ".input.spin", state 961, "else"
+       line 403, ".input.spin", state 964, "(1)"
+       line 403, ".input.spin", state 965, "(1)"
+       line 403, ".input.spin", state 965, "(1)"
+       line 407, ".input.spin", state 972, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 974, "(1)"
+       line 407, ".input.spin", state 975, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 407, ".input.spin", state 975, "else"
+       line 407, ".input.spin", state 978, "(1)"
+       line 407, ".input.spin", state 979, "(1)"
+       line 407, ".input.spin", state 979, "(1)"
+       line 405, ".input.spin", state 984, "((i<2))"
+       line 405, ".input.spin", state 984, "((i>=2))"
+       line 411, ".input.spin", state 991, "(1)"
+       line 411, ".input.spin", state 992, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 411, ".input.spin", state 992, "else"
+       line 411, ".input.spin", state 995, "(1)"
+       line 411, ".input.spin", state 996, "(1)"
+       line 411, ".input.spin", state 996, "(1)"
+       line 415, ".input.spin", state 1004, "(1)"
+       line 415, ".input.spin", state 1005, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 415, ".input.spin", state 1005, "else"
+       line 415, ".input.spin", state 1008, "(1)"
+       line 415, ".input.spin", state 1009, "(1)"
+       line 415, ".input.spin", state 1009, "(1)"
+       line 413, ".input.spin", state 1014, "((i<1))"
+       line 413, ".input.spin", state 1014, "((i>=1))"
+       line 420, ".input.spin", state 1021, "(1)"
+       line 420, ".input.spin", state 1022, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 420, ".input.spin", state 1022, "else"
+       line 420, ".input.spin", state 1025, "(1)"
+       line 420, ".input.spin", state 1026, "(1)"
+       line 420, ".input.spin", state 1026, "(1)"
+       line 424, ".input.spin", state 1034, "(1)"
+       line 424, ".input.spin", state 1035, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 424, ".input.spin", state 1035, "else"
+       line 424, ".input.spin", state 1038, "(1)"
+       line 424, ".input.spin", state 1039, "(1)"
+       line 424, ".input.spin", state 1039, "(1)"
+       line 422, ".input.spin", state 1044, "((i<2))"
+       line 422, ".input.spin", state 1044, "((i>=2))"
+       line 429, ".input.spin", state 1048, "(1)"
+       line 429, ".input.spin", state 1048, "(1)"
+       line 677, ".input.spin", state 1052, "_proc_urcu_reader = (_proc_urcu_reader|(1<<11))"
+       line 394, ".input.spin", state 1057, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 1089, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 1103, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 1122, "(1)"
+       line 420, ".input.spin", state 1152, "(1)"
+       line 424, ".input.spin", state 1165, "(1)"
+       line 394, ".input.spin", state 1189, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 1221, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 1235, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 1254, "(1)"
+       line 420, ".input.spin", state 1284, "(1)"
+       line 424, ".input.spin", state 1297, "(1)"
+       line 394, ".input.spin", state 1322, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 1354, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 1368, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 1387, "(1)"
+       line 420, ".input.spin", state 1417, "(1)"
+       line 424, ".input.spin", state 1430, "(1)"
+       line 394, ".input.spin", state 1451, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 1483, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 1497, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 1516, "(1)"
+       line 420, ".input.spin", state 1546, "(1)"
+       line 424, ".input.spin", state 1559, "(1)"
+       line 394, ".input.spin", state 1585, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 1617, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 1631, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 1650, "(1)"
+       line 420, ".input.spin", state 1680, "(1)"
+       line 424, ".input.spin", state 1693, "(1)"
+       line 394, ".input.spin", state 1714, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 1746, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 1760, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 1779, "(1)"
+       line 420, ".input.spin", state 1809, "(1)"
+       line 424, ".input.spin", state 1822, "(1)"
+       line 394, ".input.spin", state 1846, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 1878, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 1892, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 1911, "(1)"
+       line 420, ".input.spin", state 1941, "(1)"
+       line 424, ".input.spin", state 1954, "(1)"
+       line 716, ".input.spin", state 1975, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<19))"
+       line 394, ".input.spin", state 1982, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 2014, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 2028, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 2047, "(1)"
+       line 420, ".input.spin", state 2077, "(1)"
+       line 424, ".input.spin", state 2090, "(1)"
+       line 394, ".input.spin", state 2111, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 2143, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 2157, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 2176, "(1)"
+       line 420, ".input.spin", state 2206, "(1)"
+       line 424, ".input.spin", state 2219, "(1)"
+       line 394, ".input.spin", state 2242, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 394, ".input.spin", state 2244, "(1)"
+       line 394, ".input.spin", state 2245, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 394, ".input.spin", state 2245, "else"
+       line 394, ".input.spin", state 2248, "(1)"
+       line 398, ".input.spin", state 2256, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 398, ".input.spin", state 2258, "(1)"
+       line 398, ".input.spin", state 2259, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 398, ".input.spin", state 2259, "else"
+       line 398, ".input.spin", state 2262, "(1)"
+       line 398, ".input.spin", state 2263, "(1)"
+       line 398, ".input.spin", state 2263, "(1)"
+       line 396, ".input.spin", state 2268, "((i<1))"
+       line 396, ".input.spin", state 2268, "((i>=1))"
+       line 403, ".input.spin", state 2274, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 2276, "(1)"
+       line 403, ".input.spin", state 2277, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 403, ".input.spin", state 2277, "else"
+       line 403, ".input.spin", state 2280, "(1)"
+       line 403, ".input.spin", state 2281, "(1)"
+       line 403, ".input.spin", state 2281, "(1)"
+       line 407, ".input.spin", state 2288, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 2290, "(1)"
+       line 407, ".input.spin", state 2291, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 407, ".input.spin", state 2291, "else"
+       line 407, ".input.spin", state 2294, "(1)"
+       line 407, ".input.spin", state 2295, "(1)"
+       line 407, ".input.spin", state 2295, "(1)"
+       line 405, ".input.spin", state 2300, "((i<2))"
+       line 405, ".input.spin", state 2300, "((i>=2))"
+       line 411, ".input.spin", state 2307, "(1)"
+       line 411, ".input.spin", state 2308, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 411, ".input.spin", state 2308, "else"
+       line 411, ".input.spin", state 2311, "(1)"
+       line 411, ".input.spin", state 2312, "(1)"
+       line 411, ".input.spin", state 2312, "(1)"
+       line 415, ".input.spin", state 2320, "(1)"
+       line 415, ".input.spin", state 2321, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 415, ".input.spin", state 2321, "else"
+       line 415, ".input.spin", state 2324, "(1)"
+       line 415, ".input.spin", state 2325, "(1)"
+       line 415, ".input.spin", state 2325, "(1)"
+       line 413, ".input.spin", state 2330, "((i<1))"
+       line 413, ".input.spin", state 2330, "((i>=1))"
+       line 420, ".input.spin", state 2337, "(1)"
+       line 420, ".input.spin", state 2338, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 420, ".input.spin", state 2338, "else"
+       line 420, ".input.spin", state 2341, "(1)"
+       line 420, ".input.spin", state 2342, "(1)"
+       line 420, ".input.spin", state 2342, "(1)"
+       line 424, ".input.spin", state 2350, "(1)"
+       line 424, ".input.spin", state 2351, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 424, ".input.spin", state 2351, "else"
+       line 424, ".input.spin", state 2354, "(1)"
+       line 424, ".input.spin", state 2355, "(1)"
+       line 424, ".input.spin", state 2355, "(1)"
+       line 422, ".input.spin", state 2360, "((i<2))"
+       line 422, ".input.spin", state 2360, "((i>=2))"
+       line 429, ".input.spin", state 2364, "(1)"
+       line 429, ".input.spin", state 2364, "(1)"
+       line 716, ".input.spin", state 2367, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 716, ".input.spin", state 2368, "_proc_urcu_reader = (_proc_urcu_reader|(1<<23))"
+       line 716, ".input.spin", state 2369, "(1)"
+       line 394, ".input.spin", state 2376, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 2408, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 2422, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 2441, "(1)"
+       line 420, ".input.spin", state 2471, "(1)"
+       line 424, ".input.spin", state 2484, "(1)"
+       line 394, ".input.spin", state 2511, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 2543, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 2557, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 2576, "(1)"
+       line 420, ".input.spin", state 2606, "(1)"
+       line 424, ".input.spin", state 2619, "(1)"
+       line 394, ".input.spin", state 2640, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 2672, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 2686, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 2705, "(1)"
+       line 420, ".input.spin", state 2735, "(1)"
+       line 424, ".input.spin", state 2748, "(1)"
+       line 226, ".input.spin", state 2781, "(1)"
+       line 234, ".input.spin", state 2801, "(1)"
+       line 238, ".input.spin", state 2809, "(1)"
+       line 226, ".input.spin", state 2824, "(1)"
+       line 234, ".input.spin", state 2844, "(1)"
+       line 238, ".input.spin", state 2852, "(1)"
+       line 876, ".input.spin", state 2869, "-end-"
+       (278 of 2869 states)
+unreached in proctype urcu_writer
+       line 394, ".input.spin", state 18, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 398, ".input.spin", state 32, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 50, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 83, "(1)"
+       line 415, ".input.spin", state 96, "(1)"
+       line 420, ".input.spin", state 113, "(1)"
+       line 249, ".input.spin", state 149, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 253, ".input.spin", state 158, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, ".input.spin", state 171, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 394, ".input.spin", state 211, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 398, ".input.spin", state 225, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 243, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 257, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 276, "(1)"
+       line 415, ".input.spin", state 289, "(1)"
+       line 420, ".input.spin", state 306, "(1)"
+       line 424, ".input.spin", state 319, "(1)"
+       line 398, ".input.spin", state 356, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 374, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 388, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 415, ".input.spin", state 420, "(1)"
+       line 420, ".input.spin", state 437, "(1)"
+       line 424, ".input.spin", state 450, "(1)"
+       line 398, ".input.spin", state 494, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 512, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 526, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 415, ".input.spin", state 558, "(1)"
+       line 420, ".input.spin", state 575, "(1)"
+       line 424, ".input.spin", state 588, "(1)"
+       line 398, ".input.spin", state 623, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 641, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 655, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 415, ".input.spin", state 687, "(1)"
+       line 420, ".input.spin", state 704, "(1)"
+       line 424, ".input.spin", state 717, "(1)"
+       line 398, ".input.spin", state 754, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 772, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 786, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 415, ".input.spin", state 818, "(1)"
+       line 420, ".input.spin", state 835, "(1)"
+       line 424, ".input.spin", state 848, "(1)"
+       line 249, ".input.spin", state 903, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 253, ".input.spin", state 912, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, ".input.spin", state 927, "(1)"
+       line 261, ".input.spin", state 934, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, ".input.spin", state 950, "(1)"
+       line 230, ".input.spin", state 958, "(1)"
+       line 234, ".input.spin", state 970, "(1)"
+       line 238, ".input.spin", state 978, "(1)"
+       line 249, ".input.spin", state 1009, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 253, ".input.spin", state 1018, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, ".input.spin", state 1031, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, ".input.spin", state 1040, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, ".input.spin", state 1056, "(1)"
+       line 230, ".input.spin", state 1064, "(1)"
+       line 234, ".input.spin", state 1076, "(1)"
+       line 238, ".input.spin", state 1084, "(1)"
+       line 253, ".input.spin", state 1110, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, ".input.spin", state 1123, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, ".input.spin", state 1132, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, ".input.spin", state 1148, "(1)"
+       line 230, ".input.spin", state 1156, "(1)"
+       line 234, ".input.spin", state 1168, "(1)"
+       line 238, ".input.spin", state 1176, "(1)"
+       line 249, ".input.spin", state 1207, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 253, ".input.spin", state 1216, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, ".input.spin", state 1229, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, ".input.spin", state 1238, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, ".input.spin", state 1254, "(1)"
+       line 230, ".input.spin", state 1262, "(1)"
+       line 234, ".input.spin", state 1274, "(1)"
+       line 238, ".input.spin", state 1282, "(1)"
+       line 253, ".input.spin", state 1308, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, ".input.spin", state 1321, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, ".input.spin", state 1330, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, ".input.spin", state 1346, "(1)"
+       line 230, ".input.spin", state 1354, "(1)"
+       line 234, ".input.spin", state 1366, "(1)"
+       line 238, ".input.spin", state 1374, "(1)"
+       line 249, ".input.spin", state 1405, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 253, ".input.spin", state 1414, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, ".input.spin", state 1427, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, ".input.spin", state 1436, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, ".input.spin", state 1452, "(1)"
+       line 230, ".input.spin", state 1460, "(1)"
+       line 234, ".input.spin", state 1472, "(1)"
+       line 238, ".input.spin", state 1480, "(1)"
+       line 253, ".input.spin", state 1506, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, ".input.spin", state 1519, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, ".input.spin", state 1528, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, ".input.spin", state 1544, "(1)"
+       line 230, ".input.spin", state 1552, "(1)"
+       line 234, ".input.spin", state 1564, "(1)"
+       line 238, ".input.spin", state 1572, "(1)"
+       line 249, ".input.spin", state 1603, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 253, ".input.spin", state 1612, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, ".input.spin", state 1625, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, ".input.spin", state 1634, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, ".input.spin", state 1650, "(1)"
+       line 230, ".input.spin", state 1658, "(1)"
+       line 234, ".input.spin", state 1670, "(1)"
+       line 238, ".input.spin", state 1678, "(1)"
+       line 1203, ".input.spin", state 1694, "-end-"
+       (103 of 1694 states)
+unreached in proctype :init:
+       (0 of 78 states)
+
+pan: elapsed time 4.43e+03 seconds
+pan: rate 3486.0658 states/second
+pan: avg transition delay 1.038e-06 usec
+cp .input.spin asserts.spin.input
+cp .input.spin.trail asserts.spin.input.trail
diff --git a/formal-model/results/urcu-controldataflow-ipi/asserts.spin.input b/formal-model/results/urcu-controldataflow-ipi/asserts.spin.input
new file mode 100644 (file)
index 0000000..4640ac9
--- /dev/null
@@ -0,0 +1,1239 @@
+
+// Poison value for freed memory
+#define POISON 1
+// Memory with correct data
+#define WINE 0
+#define SLAB_SIZE 2
+
+#define read_poison    (data_read_first[0] == POISON || data_read_second[0] == POISON)
+
+#define RCU_GP_CTR_BIT (1 << 7)
+#define RCU_GP_CTR_NEST_MASK (RCU_GP_CTR_BIT - 1)
+
+//disabled
+#define REMOTE_BARRIERS
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+typedef per_proc_bit {
+       bit val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bitfield {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bitfield cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               /*
+                * 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, j);
+               reader_barrier[get_readerid()] = 0;
+       :: 1 ->
+               /*
+                * 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)
+//#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);                                                           \
+       i = 0;                                                                  \
+       do                                                                      \
+       :: i < NR_READERS ->                                                    \
+               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.                                            \
+                */                                                             \
+               do                                                              \
+               :: (reader_barrier[i] == 1) ->                                  \
+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(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, smp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only one reader */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* RCU data */
+DECLARE_CACHED_VAR(bit, rcu_data[SLAB_SIZE]);
+
+/* RCU pointer */
+#if (SLAB_SIZE == 2)
+DECLARE_CACHED_VAR(bit, rcu_ptr);
+bit ptr_read_first[NR_READERS];
+bit ptr_read_second[NR_READERS];
+#else
+DECLARE_CACHED_VAR(byte, rcu_ptr);
+byte ptr_read_first[NR_READERS];
+byte ptr_read_second[NR_READERS];
+#endif
+
+bit data_read_first[NR_READERS];
+bit data_read_second[NR_READERS];
+
+bit init_done = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               ptr_read_first[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb1;
+rmb1_end:
+                               data_read_first[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_first[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               ptr_read_second[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb2;
+rmb2_end:
+                               data_read_second[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_second[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+rmb1:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb1_end;
+rmb2:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_DATA                     (1 << 1)
+#define WRITE_PROC_WMB                 (1 << 2)
+#define WRITE_XCHG_PTR                 (1 << 3)
+
+#define WRITE_PROC_FIRST_MB            (1 << 4)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 5)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 6)
+#define WRITE_PROC_FIRST_WAIT          (1 << 7)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 8)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 9)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 10)
+#define WRITE_PROC_SECOND_WAIT         (1 << 11)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 12)
+
+#define WRITE_PROC_SECOND_MB           (1 << 13)
+
+#define WRITE_FREE                     (1 << 14)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_DATA                    \
+                                       | WRITE_PROC_WMB                \
+                                       | WRITE_XCHG_PTR                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB          \
+                                       | WRITE_FREE)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 15) - 1)
+
+/*
+ * Mutexes are implied around writer execution. A single writer at a time.
+ */
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte cur_data = 0, old_data, loop_nr = 0;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (loop_nr < 3) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               loop_nr = loop_nr + 1;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_WMB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+#endif
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_DATA) ->
+                       ooo_mem(i);
+                       cur_data = (cur_data + 1) % SLAB_SIZE;
+                       WRITE_CACHED_VAR(rcu_data[cur_data], WINE);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_DATA);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA,
+                                 WRITE_PROC_WMB) ->
+                       smp_wmb(i, j);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_WMB,
+                                 WRITE_XCHG_PTR) ->
+                       /* rcu_xchg_pointer() */
+                       atomic {
+                               old_data = READ_CACHED_VAR(rcu_ptr);
+                               WRITE_CACHED_VAR(rcu_ptr, cur_data);
+                       }
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_XCHG_PTR);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_WMB      /* No dependency on
+                                                        * WRITE_DATA because we
+                                                        * write to a
+                                                        * different location. */
+                                 | WRITE_PROC_SECOND_MB
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_FREE) ->
+                       WRITE_CACHED_VAR(rcu_data[old_data], POISON);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_FREE);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+               /*
+                * Note : Promela model adds implicit serialization of the
+                * WRITE_FREE instruction. Normally, it would be permitted to
+                * spill on the next loop execution. Given the validation we do
+                * checks for the data entry read to be poisoned, it's ok if
+                * we do not check "late arriving" memory poisoning.
+                */
+       :: 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
+#ifdef READER_PROGRESS
+               /*
+                * Make sure we don't block the reader's progress.
+                */
+               smp_mb_send(i, j, 5);
+#endif
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(rcu_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       ptr_read_first[i] = 1;
+                       ptr_read_second[i] = 1;
+                       data_read_first[i] = WINE;
+                       data_read_second[i] = WINE;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               INIT_CACHED_VAR(rcu_data[0], WINE, j);
+               i = 1;
+               do
+               :: i < SLAB_SIZE ->
+                       INIT_CACHED_VAR(rcu_data[i], POISON, j);
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-ipi/references.txt b/formal-model/results/urcu-controldataflow-ipi/references.txt
new file mode 100644 (file)
index 0000000..72c67a2
--- /dev/null
@@ -0,0 +1,13 @@
+http://spinroot.com/spin/Man/ltl.html
+http://en.wikipedia.org/wiki/Linear_temporal_logic
+http://www.dcs.gla.ac.uk/~muffy/MRS4-2002/lect11.ppt
+
+http://www.lsv.ens-cachan.fr/~gastin/ltl2ba/index.php
+http://spinroot.com/spin/Man/index.html
+http://spinroot.com/spin/Man/promela.html
+
+LTL vs CTL :
+
+http://spinroot.com/spin/Doc/course/lecture12.pdf p. 9, p. 15, p. 18
+http://www-i2.informatik.rwth-aachen.de/i2/fileadmin/user_upload/documents/Introduction_to_Model_Checking/mc_lec18.pdf
+  (downloaded)
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu.sh b/formal-model/results/urcu-controldataflow-ipi/urcu.sh
new file mode 100644 (file)
index 0000000..65ff517
--- /dev/null
@@ -0,0 +1,29 @@
+#!/bin/sh
+#
+# Compiles and runs the urcu.spin Promela model.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Copyright (C) IBM Corporation, 2009
+#               Mathieu Desnoyers, 2009
+#
+# Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+#          Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+
+# Basic execution, without LTL clauses. See Makefile.
+
+spin -a urcu.spin
+cc -DSAFETY -o pan pan.c
+./pan -v -c1 -X -m10000000 -w21
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu.spin b/formal-model/results/urcu-controldataflow-ipi/urcu.spin
new file mode 100644 (file)
index 0000000..4fe6b9e
--- /dev/null
@@ -0,0 +1,1225 @@
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+typedef per_proc_bit {
+       bit val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bitfield {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bitfield cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               /*
+                * 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, j);
+               reader_barrier[get_readerid()] = 0;
+       :: 1 ->
+               /*
+                * 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)
+//#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);                                                           \
+       i = 0;                                                                  \
+       do                                                                      \
+       :: i < NR_READERS ->                                                    \
+               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.                                            \
+                */                                                             \
+               do                                                              \
+               :: (reader_barrier[i] == 1) ->                                  \
+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(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, smp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only one reader */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* RCU data */
+DECLARE_CACHED_VAR(bit, rcu_data[SLAB_SIZE]);
+
+/* RCU pointer */
+#if (SLAB_SIZE == 2)
+DECLARE_CACHED_VAR(bit, rcu_ptr);
+bit ptr_read_first[NR_READERS];
+bit ptr_read_second[NR_READERS];
+#else
+DECLARE_CACHED_VAR(byte, rcu_ptr);
+byte ptr_read_first[NR_READERS];
+byte ptr_read_second[NR_READERS];
+#endif
+
+bit data_read_first[NR_READERS];
+bit data_read_second[NR_READERS];
+
+bit init_done = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               ptr_read_first[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb1;
+rmb1_end:
+                               data_read_first[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_first[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               ptr_read_second[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb2;
+rmb2_end:
+                               data_read_second[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_second[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+rmb1:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb1_end;
+rmb2:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_DATA                     (1 << 1)
+#define WRITE_PROC_WMB                 (1 << 2)
+#define WRITE_XCHG_PTR                 (1 << 3)
+
+#define WRITE_PROC_FIRST_MB            (1 << 4)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 5)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 6)
+#define WRITE_PROC_FIRST_WAIT          (1 << 7)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 8)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 9)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 10)
+#define WRITE_PROC_SECOND_WAIT         (1 << 11)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 12)
+
+#define WRITE_PROC_SECOND_MB           (1 << 13)
+
+#define WRITE_FREE                     (1 << 14)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_DATA                    \
+                                       | WRITE_PROC_WMB                \
+                                       | WRITE_XCHG_PTR                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB          \
+                                       | WRITE_FREE)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 15) - 1)
+
+/*
+ * Mutexes are implied around writer execution. A single writer at a time.
+ */
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte cur_data = 0, old_data, loop_nr = 0;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (loop_nr < 3) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               loop_nr = loop_nr + 1;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_WMB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+#endif
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_DATA) ->
+                       ooo_mem(i);
+                       cur_data = (cur_data + 1) % SLAB_SIZE;
+                       WRITE_CACHED_VAR(rcu_data[cur_data], WINE);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_DATA);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA,
+                                 WRITE_PROC_WMB) ->
+                       smp_wmb(i, j);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_WMB,
+                                 WRITE_XCHG_PTR) ->
+                       /* rcu_xchg_pointer() */
+                       atomic {
+                               old_data = READ_CACHED_VAR(rcu_ptr);
+                               WRITE_CACHED_VAR(rcu_ptr, cur_data);
+                       }
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_XCHG_PTR);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_WMB      /* No dependency on
+                                                        * WRITE_DATA because we
+                                                        * write to a
+                                                        * different location. */
+                                 | WRITE_PROC_SECOND_MB
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_FREE) ->
+                       WRITE_CACHED_VAR(rcu_data[old_data], POISON);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_FREE);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+               /*
+                * Note : Promela model adds implicit serialization of the
+                * WRITE_FREE instruction. Normally, it would be permitted to
+                * spill on the next loop execution. Given the validation we do
+                * checks for the data entry read to be poisoned, it's ok if
+                * we do not check "late arriving" memory poisoning.
+                */
+       :: 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
+#ifdef READER_PROGRESS
+               /*
+                * Make sure we don't block the reader's progress.
+                */
+               smp_mb_send(i, j, 5);
+#endif
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(rcu_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       ptr_read_first[i] = 1;
+                       ptr_read_second[i] = 1;
+                       data_read_first[i] = WINE;
+                       data_read_second[i] = WINE;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               INIT_CACHED_VAR(rcu_data[0], WINE, j);
+               i = 1;
+               do
+               :: i < SLAB_SIZE ->
+                       INIT_CACHED_VAR(rcu_data[i], POISON, j);
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu.spin.bkp.b4ptr b/formal-model/results/urcu-controldataflow-ipi/urcu.spin.bkp.b4ptr
new file mode 100644 (file)
index 0000000..6670f3e
--- /dev/null
@@ -0,0 +1,1123 @@
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bit {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bit cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(generation_ptr, get_pid());
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(generation_ptr, get_pid());
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               smp_mb(i, j);
+               reader_barrier[get_readerid()] = 0;
+       :: 1 ->
+       /*
+        * Busy-looping waiting for other barrier requests is not considered as
+        * non-progress.
+        */
+#ifdef READER_PROGRESS
+progress_reader2:
+#endif
+#ifdef WRITER_PROGRESS
+//progress_writer_from_reader1:
+#endif
+               skip;
+       :: 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_reader2:
+#endif
+               break;
+       od;
+}
+
+#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;                                          \
+               /*                                                              \
+                * 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)                                                     \
+               do                                                              \
+               :: (reader_barrier[i] == 1) -> skip;                            \
+               :: (reader_barrier[i] == 0) -> break;                           \
+               od;                                                             \
+               i++;                                                            \
+       :: i >= NR_READERS ->                                                   \
+               break                                                           \
+       od;                                                                     \
+       smp_mb(i, j);                                                           \
+}
+
+#else
+
+#define smp_mb_send(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, wmp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only two readers */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* pointer generation */
+DECLARE_CACHED_VAR(byte, generation_ptr);
+
+byte last_free_gen = 0;
+bit free_done = 0;
+byte read_generation[NR_READERS];
+bit data_access[NR_READERS];
+
+bit write_lock = 0;
+
+bit init_done = 0;
+
+bit sighand_exec = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(generation_ptr, get_pid());
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(generation_ptr, get_pid());
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               :: 1 -> skip;
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               read_generation[get_readerid()] =
+                                       READ_CACHED_VAR(generation_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               ooo_mem(i);
+                               goto non_atomic;
+non_atomic_end:
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               read_generation[get_readerid()] =
+                                       READ_CACHED_VAR(generation_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               goto non_atomic2;
+non_atomic2_end:
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+non_atomic:
+       data_access[get_readerid()] = 1;
+       data_access[get_readerid()] = 0;
+       goto non_atomic_end;
+non_atomic2:
+       data_access[get_readerid()] = 1;
+       data_access[get_readerid()] = 0;
+       goto non_atomic2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_PROC_FIRST_MB            (1 << 1)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 2)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 3)
+#define WRITE_PROC_FIRST_WAIT          (1 << 4)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 5)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 6)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 7)
+#define WRITE_PROC_SECOND_WAIT         (1 << 8)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 9)
+
+#define WRITE_PROC_SECOND_MB           (1 << 10)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 11) - 1)
+
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte old_gen;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (READ_CACHED_VAR(generation_ptr) < 5) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               ooo_mem(i);
+               atomic {
+                       old_gen = READ_CACHED_VAR(generation_ptr);
+                       WRITE_CACHED_VAR(generation_ptr, old_gen + 1);
+               }
+               ooo_mem(i);
+
+               do
+               :: 1 ->
+                       atomic {
+                               if
+                               :: write_lock == 0 ->
+                                       write_lock = 1;
+                                       break;
+                               :: else ->
+                                       skip;
+                               fi;
+                       }
+               od;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+
+               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
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(generation_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       read_generation[i] = 1;
+                       data_access[i] = 0;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_free.log b/formal-model/results/urcu-controldataflow-ipi/urcu_free.log
new file mode 100644 (file)
index 0000000..bcad427
--- /dev/null
@@ -0,0 +1,533 @@
+rm -f pan* trail.out .input.spin* *.spin.trail .input.define
+touch .input.define
+cat .input.define >> pan.ltl
+cat DEFINES >> pan.ltl
+spin -f "!(`cat urcu_free.ltl | grep -v ^//`)" >> pan.ltl
+cat .input.define > .input.spin
+cat DEFINES >> .input.spin
+cat urcu.spin >> .input.spin
+rm -f .input.spin.trail
+spin -a -X -N pan.ltl .input.spin
+Exit-Status 0
+gcc -O2 -w -DHASH64 -o pan pan.c
+./pan -a -v -c1 -X -m10000000 -w20
+warning: for p.o. reduction to be valid the never claim must be stutter-invariant
+(never claims generated from LTL formulae are stutter-invariant)
+depth 0: Claim reached state 5 (line 1257)
+Depth=    7192 States=    1e+06 Transitions= 1.25e+08 Memory=   550.432        t=    156 R=   6e+03
+Depth=    7192 States=    2e+06 Transitions=  4.1e+08 Memory=   634.318        t=    524 R=   4e+03
+Depth=    7192 States=    3e+06 Transitions= 6.64e+08 Memory=   718.303        t=    857 R=   3e+03
+pan: resizing hashtable to -w22..  done
+Depth=    7192 States=    4e+06 Transitions= 1.15e+09 Memory=   833.311        t= 1.5e+03 R=   3e+03
+Depth=    7192 States=    5e+06 Transitions= 1.46e+09 Memory=   917.295        t= 1.9e+03 R=   3e+03
+Depth=    7192 States=    6e+06 Transitions= 1.66e+09 Memory=  1001.279        t= 2.15e+03 R=   3e+03
+Depth=    7192 States=    7e+06 Transitions= 1.86e+09 Memory=  1085.264        t= 2.42e+03 R=   3e+03
+Depth=    7192 States=    8e+06 Transitions= 2.13e+09 Memory=  1169.151        t= 2.78e+03 R=   3e+03
+Depth=    7192 States=    9e+06 Transitions= 2.38e+09 Memory=  1253.135        t= 3.1e+03 R=   3e+03
+pan: resizing hashtable to -w24..  done
+Depth=    7192 States=    1e+07 Transitions= 2.87e+09 Memory=  1461.115        t= 3.74e+03 R=   3e+03
+Depth=    7192 States=  1.1e+07 Transitions= 3.15e+09 Memory=  1545.100        t= 4.1e+03 R=   3e+03
+Depth=    7192 States=  1.2e+07 Transitions= 3.42e+09 Memory=  1629.084        t= 4.46e+03 R=   3e+03
+Depth=    7192 States=  1.3e+07 Transitions= 3.62e+09 Memory=  1713.068        t= 4.71e+03 R=   3e+03
+Depth=    7192 States=  1.4e+07 Transitions= 3.84e+09 Memory=  1797.053        t= 4.98e+03 R=   3e+03
+Depth=    7192 States=  1.5e+07 Transitions= 4.13e+09 Memory=  1881.037        t= 5.36e+03 R=   3e+03
+
+(Spin Version 5.1.7 -- 23 December 2008)
+       + Partial Order Reduction
+
+Full statespace search for:
+       never claim             +
+       assertion violations    + (if within scope of claim)
+       acceptance   cycles     + (fairness disabled)
+       invalid end states      - (disabled by never claim)
+
+State-vector 88 byte, depth reached 7192, errors: 0
+ 15444143 states, stored
+4.2528076e+09 states, matched
+4.2682517e+09 transitions (= stored+matched)
+2.483245e+10 atomic steps
+hash conflicts: 2.7880402e+09 (resolved)
+
+Stats on memory usage (in Megabytes):
+ 1708.527      equivalent memory usage for states (stored*(State-vector + overhead))
+ 1333.263      actual memory usage for states (compression: 78.04%)
+               state-vector as stored = 63 byte + 28 byte overhead
+  128.000      memory used for hash table (-w24)
+  457.764      memory used for DFS stack (-m10000000)
+ 1918.244      total actual memory usage
+
+unreached in proctype urcu_reader
+       line 249, "pan.___", state 30, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 257, "pan.___", state 52, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, "pan.___", state 61, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, "pan.___", state 77, "(1)"
+       line 230, "pan.___", state 85, "(1)"
+       line 234, "pan.___", state 97, "(1)"
+       line 238, "pan.___", state 105, "(1)"
+       line 394, "pan.___", state 131, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 163, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 177, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 196, "(1)"
+       line 420, "pan.___", state 226, "(1)"
+       line 424, "pan.___", state 239, "(1)"
+       line 669, "pan.___", state 260, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<1))"
+       line 394, "pan.___", state 267, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 299, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 313, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 332, "(1)"
+       line 420, "pan.___", state 362, "(1)"
+       line 424, "pan.___", state 375, "(1)"
+       line 394, "pan.___", state 396, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 428, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 442, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 461, "(1)"
+       line 420, "pan.___", state 491, "(1)"
+       line 424, "pan.___", state 504, "(1)"
+       line 394, "pan.___", state 527, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 394, "pan.___", state 529, "(1)"
+       line 394, "pan.___", state 530, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 394, "pan.___", state 530, "else"
+       line 394, "pan.___", state 533, "(1)"
+       line 398, "pan.___", state 541, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 398, "pan.___", state 543, "(1)"
+       line 398, "pan.___", state 544, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 398, "pan.___", state 544, "else"
+       line 398, "pan.___", state 547, "(1)"
+       line 398, "pan.___", state 548, "(1)"
+       line 398, "pan.___", state 548, "(1)"
+       line 396, "pan.___", state 553, "((i<1))"
+       line 396, "pan.___", state 553, "((i>=1))"
+       line 403, "pan.___", state 559, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 561, "(1)"
+       line 403, "pan.___", state 562, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 403, "pan.___", state 562, "else"
+       line 403, "pan.___", state 565, "(1)"
+       line 403, "pan.___", state 566, "(1)"
+       line 403, "pan.___", state 566, "(1)"
+       line 407, "pan.___", state 573, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 575, "(1)"
+       line 407, "pan.___", state 576, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 407, "pan.___", state 576, "else"
+       line 407, "pan.___", state 579, "(1)"
+       line 407, "pan.___", state 580, "(1)"
+       line 407, "pan.___", state 580, "(1)"
+       line 405, "pan.___", state 585, "((i<2))"
+       line 405, "pan.___", state 585, "((i>=2))"
+       line 411, "pan.___", state 592, "(1)"
+       line 411, "pan.___", state 593, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 411, "pan.___", state 593, "else"
+       line 411, "pan.___", state 596, "(1)"
+       line 411, "pan.___", state 597, "(1)"
+       line 411, "pan.___", state 597, "(1)"
+       line 415, "pan.___", state 605, "(1)"
+       line 415, "pan.___", state 606, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 415, "pan.___", state 606, "else"
+       line 415, "pan.___", state 609, "(1)"
+       line 415, "pan.___", state 610, "(1)"
+       line 415, "pan.___", state 610, "(1)"
+       line 413, "pan.___", state 615, "((i<1))"
+       line 413, "pan.___", state 615, "((i>=1))"
+       line 420, "pan.___", state 622, "(1)"
+       line 420, "pan.___", state 623, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 420, "pan.___", state 623, "else"
+       line 420, "pan.___", state 626, "(1)"
+       line 420, "pan.___", state 627, "(1)"
+       line 420, "pan.___", state 627, "(1)"
+       line 424, "pan.___", state 635, "(1)"
+       line 424, "pan.___", state 636, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 424, "pan.___", state 636, "else"
+       line 424, "pan.___", state 639, "(1)"
+       line 424, "pan.___", state 640, "(1)"
+       line 424, "pan.___", state 640, "(1)"
+       line 422, "pan.___", state 645, "((i<2))"
+       line 422, "pan.___", state 645, "((i>=2))"
+       line 429, "pan.___", state 649, "(1)"
+       line 429, "pan.___", state 649, "(1)"
+       line 669, "pan.___", state 652, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 669, "pan.___", state 653, "_proc_urcu_reader = (_proc_urcu_reader|(1<<5))"
+       line 669, "pan.___", state 654, "(1)"
+       line 394, "pan.___", state 661, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 693, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 707, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 726, "(1)"
+       line 420, "pan.___", state 756, "(1)"
+       line 424, "pan.___", state 769, "(1)"
+       line 394, "pan.___", state 797, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 394, "pan.___", state 799, "(1)"
+       line 394, "pan.___", state 800, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 394, "pan.___", state 800, "else"
+       line 394, "pan.___", state 803, "(1)"
+       line 398, "pan.___", state 811, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 398, "pan.___", state 813, "(1)"
+       line 398, "pan.___", state 814, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 398, "pan.___", state 814, "else"
+       line 398, "pan.___", state 817, "(1)"
+       line 398, "pan.___", state 818, "(1)"
+       line 398, "pan.___", state 818, "(1)"
+       line 396, "pan.___", state 823, "((i<1))"
+       line 396, "pan.___", state 823, "((i>=1))"
+       line 403, "pan.___", state 829, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 831, "(1)"
+       line 403, "pan.___", state 832, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 403, "pan.___", state 832, "else"
+       line 403, "pan.___", state 835, "(1)"
+       line 403, "pan.___", state 836, "(1)"
+       line 403, "pan.___", state 836, "(1)"
+       line 407, "pan.___", state 843, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 845, "(1)"
+       line 407, "pan.___", state 846, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 407, "pan.___", state 846, "else"
+       line 407, "pan.___", state 849, "(1)"
+       line 407, "pan.___", state 850, "(1)"
+       line 407, "pan.___", state 850, "(1)"
+       line 405, "pan.___", state 855, "((i<2))"
+       line 405, "pan.___", state 855, "((i>=2))"
+       line 411, "pan.___", state 862, "(1)"
+       line 411, "pan.___", state 863, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 411, "pan.___", state 863, "else"
+       line 411, "pan.___", state 866, "(1)"
+       line 411, "pan.___", state 867, "(1)"
+       line 411, "pan.___", state 867, "(1)"
+       line 415, "pan.___", state 875, "(1)"
+       line 415, "pan.___", state 876, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 415, "pan.___", state 876, "else"
+       line 415, "pan.___", state 879, "(1)"
+       line 415, "pan.___", state 880, "(1)"
+       line 415, "pan.___", state 880, "(1)"
+       line 413, "pan.___", state 885, "((i<1))"
+       line 413, "pan.___", state 885, "((i>=1))"
+       line 420, "pan.___", state 892, "(1)"
+       line 420, "pan.___", state 893, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 420, "pan.___", state 893, "else"
+       line 420, "pan.___", state 896, "(1)"
+       line 420, "pan.___", state 897, "(1)"
+       line 420, "pan.___", state 897, "(1)"
+       line 424, "pan.___", state 905, "(1)"
+       line 424, "pan.___", state 906, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 424, "pan.___", state 906, "else"
+       line 424, "pan.___", state 909, "(1)"
+       line 424, "pan.___", state 910, "(1)"
+       line 424, "pan.___", state 910, "(1)"
+       line 429, "pan.___", state 919, "(1)"
+       line 429, "pan.___", state 919, "(1)"
+       line 394, "pan.___", state 926, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 394, "pan.___", state 928, "(1)"
+       line 394, "pan.___", state 929, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 394, "pan.___", state 929, "else"
+       line 394, "pan.___", state 932, "(1)"
+       line 398, "pan.___", state 940, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 398, "pan.___", state 942, "(1)"
+       line 398, "pan.___", state 943, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 398, "pan.___", state 943, "else"
+       line 398, "pan.___", state 946, "(1)"
+       line 398, "pan.___", state 947, "(1)"
+       line 398, "pan.___", state 947, "(1)"
+       line 396, "pan.___", state 952, "((i<1))"
+       line 396, "pan.___", state 952, "((i>=1))"
+       line 403, "pan.___", state 958, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 960, "(1)"
+       line 403, "pan.___", state 961, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 403, "pan.___", state 961, "else"
+       line 403, "pan.___", state 964, "(1)"
+       line 403, "pan.___", state 965, "(1)"
+       line 403, "pan.___", state 965, "(1)"
+       line 407, "pan.___", state 972, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 974, "(1)"
+       line 407, "pan.___", state 975, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 407, "pan.___", state 975, "else"
+       line 407, "pan.___", state 978, "(1)"
+       line 407, "pan.___", state 979, "(1)"
+       line 407, "pan.___", state 979, "(1)"
+       line 405, "pan.___", state 984, "((i<2))"
+       line 405, "pan.___", state 984, "((i>=2))"
+       line 411, "pan.___", state 991, "(1)"
+       line 411, "pan.___", state 992, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 411, "pan.___", state 992, "else"
+       line 411, "pan.___", state 995, "(1)"
+       line 411, "pan.___", state 996, "(1)"
+       line 411, "pan.___", state 996, "(1)"
+       line 415, "pan.___", state 1004, "(1)"
+       line 415, "pan.___", state 1005, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 415, "pan.___", state 1005, "else"
+       line 415, "pan.___", state 1008, "(1)"
+       line 415, "pan.___", state 1009, "(1)"
+       line 415, "pan.___", state 1009, "(1)"
+       line 413, "pan.___", state 1014, "((i<1))"
+       line 413, "pan.___", state 1014, "((i>=1))"
+       line 420, "pan.___", state 1021, "(1)"
+       line 420, "pan.___", state 1022, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 420, "pan.___", state 1022, "else"
+       line 420, "pan.___", state 1025, "(1)"
+       line 420, "pan.___", state 1026, "(1)"
+       line 420, "pan.___", state 1026, "(1)"
+       line 424, "pan.___", state 1034, "(1)"
+       line 424, "pan.___", state 1035, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 424, "pan.___", state 1035, "else"
+       line 424, "pan.___", state 1038, "(1)"
+       line 424, "pan.___", state 1039, "(1)"
+       line 424, "pan.___", state 1039, "(1)"
+       line 422, "pan.___", state 1044, "((i<2))"
+       line 422, "pan.___", state 1044, "((i>=2))"
+       line 429, "pan.___", state 1048, "(1)"
+       line 429, "pan.___", state 1048, "(1)"
+       line 677, "pan.___", state 1052, "_proc_urcu_reader = (_proc_urcu_reader|(1<<11))"
+       line 394, "pan.___", state 1057, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 1089, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 1103, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 1122, "(1)"
+       line 420, "pan.___", state 1152, "(1)"
+       line 424, "pan.___", state 1165, "(1)"
+       line 394, "pan.___", state 1189, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 1221, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 1235, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 1254, "(1)"
+       line 420, "pan.___", state 1284, "(1)"
+       line 424, "pan.___", state 1297, "(1)"
+       line 394, "pan.___", state 1322, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 1354, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 1368, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 1387, "(1)"
+       line 420, "pan.___", state 1417, "(1)"
+       line 424, "pan.___", state 1430, "(1)"
+       line 394, "pan.___", state 1451, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 1483, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 1497, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 1516, "(1)"
+       line 420, "pan.___", state 1546, "(1)"
+       line 424, "pan.___", state 1559, "(1)"
+       line 394, "pan.___", state 1585, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 1617, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 1631, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 1650, "(1)"
+       line 420, "pan.___", state 1680, "(1)"
+       line 424, "pan.___", state 1693, "(1)"
+       line 394, "pan.___", state 1714, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 1746, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 1760, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 1779, "(1)"
+       line 420, "pan.___", state 1809, "(1)"
+       line 424, "pan.___", state 1822, "(1)"
+       line 394, "pan.___", state 1846, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 1878, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 1892, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 1911, "(1)"
+       line 420, "pan.___", state 1941, "(1)"
+       line 424, "pan.___", state 1954, "(1)"
+       line 716, "pan.___", state 1975, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<19))"
+       line 394, "pan.___", state 1982, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 2014, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 2028, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 2047, "(1)"
+       line 420, "pan.___", state 2077, "(1)"
+       line 424, "pan.___", state 2090, "(1)"
+       line 394, "pan.___", state 2111, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 2143, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 2157, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 2176, "(1)"
+       line 420, "pan.___", state 2206, "(1)"
+       line 424, "pan.___", state 2219, "(1)"
+       line 394, "pan.___", state 2242, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 394, "pan.___", state 2244, "(1)"
+       line 394, "pan.___", state 2245, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 394, "pan.___", state 2245, "else"
+       line 394, "pan.___", state 2248, "(1)"
+       line 398, "pan.___", state 2256, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 398, "pan.___", state 2258, "(1)"
+       line 398, "pan.___", state 2259, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 398, "pan.___", state 2259, "else"
+       line 398, "pan.___", state 2262, "(1)"
+       line 398, "pan.___", state 2263, "(1)"
+       line 398, "pan.___", state 2263, "(1)"
+       line 396, "pan.___", state 2268, "((i<1))"
+       line 396, "pan.___", state 2268, "((i>=1))"
+       line 403, "pan.___", state 2274, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 2276, "(1)"
+       line 403, "pan.___", state 2277, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 403, "pan.___", state 2277, "else"
+       line 403, "pan.___", state 2280, "(1)"
+       line 403, "pan.___", state 2281, "(1)"
+       line 403, "pan.___", state 2281, "(1)"
+       line 407, "pan.___", state 2288, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 2290, "(1)"
+       line 407, "pan.___", state 2291, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 407, "pan.___", state 2291, "else"
+       line 407, "pan.___", state 2294, "(1)"
+       line 407, "pan.___", state 2295, "(1)"
+       line 407, "pan.___", state 2295, "(1)"
+       line 405, "pan.___", state 2300, "((i<2))"
+       line 405, "pan.___", state 2300, "((i>=2))"
+       line 411, "pan.___", state 2307, "(1)"
+       line 411, "pan.___", state 2308, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 411, "pan.___", state 2308, "else"
+       line 411, "pan.___", state 2311, "(1)"
+       line 411, "pan.___", state 2312, "(1)"
+       line 411, "pan.___", state 2312, "(1)"
+       line 415, "pan.___", state 2320, "(1)"
+       line 415, "pan.___", state 2321, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 415, "pan.___", state 2321, "else"
+       line 415, "pan.___", state 2324, "(1)"
+       line 415, "pan.___", state 2325, "(1)"
+       line 415, "pan.___", state 2325, "(1)"
+       line 413, "pan.___", state 2330, "((i<1))"
+       line 413, "pan.___", state 2330, "((i>=1))"
+       line 420, "pan.___", state 2337, "(1)"
+       line 420, "pan.___", state 2338, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 420, "pan.___", state 2338, "else"
+       line 420, "pan.___", state 2341, "(1)"
+       line 420, "pan.___", state 2342, "(1)"
+       line 420, "pan.___", state 2342, "(1)"
+       line 424, "pan.___", state 2350, "(1)"
+       line 424, "pan.___", state 2351, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 424, "pan.___", state 2351, "else"
+       line 424, "pan.___", state 2354, "(1)"
+       line 424, "pan.___", state 2355, "(1)"
+       line 424, "pan.___", state 2355, "(1)"
+       line 422, "pan.___", state 2360, "((i<2))"
+       line 422, "pan.___", state 2360, "((i>=2))"
+       line 429, "pan.___", state 2364, "(1)"
+       line 429, "pan.___", state 2364, "(1)"
+       line 716, "pan.___", state 2367, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 716, "pan.___", state 2368, "_proc_urcu_reader = (_proc_urcu_reader|(1<<23))"
+       line 716, "pan.___", state 2369, "(1)"
+       line 394, "pan.___", state 2376, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 2408, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 2422, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 2441, "(1)"
+       line 420, "pan.___", state 2471, "(1)"
+       line 424, "pan.___", state 2484, "(1)"
+       line 394, "pan.___", state 2511, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 2543, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 2557, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 2576, "(1)"
+       line 420, "pan.___", state 2606, "(1)"
+       line 424, "pan.___", state 2619, "(1)"
+       line 394, "pan.___", state 2640, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 2672, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 2686, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 2705, "(1)"
+       line 420, "pan.___", state 2735, "(1)"
+       line 424, "pan.___", state 2748, "(1)"
+       line 226, "pan.___", state 2781, "(1)"
+       line 234, "pan.___", state 2801, "(1)"
+       line 238, "pan.___", state 2809, "(1)"
+       line 226, "pan.___", state 2824, "(1)"
+       line 234, "pan.___", state 2844, "(1)"
+       line 238, "pan.___", state 2852, "(1)"
+       line 876, "pan.___", state 2869, "-end-"
+       (278 of 2869 states)
+unreached in proctype urcu_writer
+       line 394, "pan.___", state 18, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 398, "pan.___", state 32, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 50, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 83, "(1)"
+       line 415, "pan.___", state 96, "(1)"
+       line 420, "pan.___", state 113, "(1)"
+       line 249, "pan.___", state 149, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 253, "pan.___", state 158, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, "pan.___", state 171, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 394, "pan.___", state 211, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 398, "pan.___", state 225, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 243, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 257, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 276, "(1)"
+       line 415, "pan.___", state 289, "(1)"
+       line 420, "pan.___", state 306, "(1)"
+       line 424, "pan.___", state 319, "(1)"
+       line 398, "pan.___", state 356, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 374, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 388, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 415, "pan.___", state 420, "(1)"
+       line 420, "pan.___", state 437, "(1)"
+       line 424, "pan.___", state 450, "(1)"
+       line 398, "pan.___", state 494, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 512, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 526, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 415, "pan.___", state 558, "(1)"
+       line 420, "pan.___", state 575, "(1)"
+       line 424, "pan.___", state 588, "(1)"
+       line 398, "pan.___", state 623, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 641, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 655, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 415, "pan.___", state 687, "(1)"
+       line 420, "pan.___", state 704, "(1)"
+       line 424, "pan.___", state 717, "(1)"
+       line 398, "pan.___", state 754, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 772, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 786, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 415, "pan.___", state 818, "(1)"
+       line 420, "pan.___", state 835, "(1)"
+       line 424, "pan.___", state 848, "(1)"
+       line 249, "pan.___", state 903, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 253, "pan.___", state 912, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, "pan.___", state 927, "(1)"
+       line 261, "pan.___", state 934, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, "pan.___", state 950, "(1)"
+       line 230, "pan.___", state 958, "(1)"
+       line 234, "pan.___", state 970, "(1)"
+       line 238, "pan.___", state 978, "(1)"
+       line 249, "pan.___", state 1009, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 253, "pan.___", state 1018, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, "pan.___", state 1031, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, "pan.___", state 1040, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, "pan.___", state 1056, "(1)"
+       line 230, "pan.___", state 1064, "(1)"
+       line 234, "pan.___", state 1076, "(1)"
+       line 238, "pan.___", state 1084, "(1)"
+       line 253, "pan.___", state 1110, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, "pan.___", state 1123, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, "pan.___", state 1132, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, "pan.___", state 1148, "(1)"
+       line 230, "pan.___", state 1156, "(1)"
+       line 234, "pan.___", state 1168, "(1)"
+       line 238, "pan.___", state 1176, "(1)"
+       line 249, "pan.___", state 1207, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 253, "pan.___", state 1216, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, "pan.___", state 1229, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, "pan.___", state 1238, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, "pan.___", state 1254, "(1)"
+       line 230, "pan.___", state 1262, "(1)"
+       line 234, "pan.___", state 1274, "(1)"
+       line 238, "pan.___", state 1282, "(1)"
+       line 253, "pan.___", state 1308, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, "pan.___", state 1321, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, "pan.___", state 1330, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, "pan.___", state 1346, "(1)"
+       line 230, "pan.___", state 1354, "(1)"
+       line 234, "pan.___", state 1366, "(1)"
+       line 238, "pan.___", state 1374, "(1)"
+       line 249, "pan.___", state 1405, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 253, "pan.___", state 1414, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, "pan.___", state 1427, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, "pan.___", state 1436, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, "pan.___", state 1452, "(1)"
+       line 230, "pan.___", state 1460, "(1)"
+       line 234, "pan.___", state 1472, "(1)"
+       line 238, "pan.___", state 1480, "(1)"
+       line 253, "pan.___", state 1506, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, "pan.___", state 1519, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, "pan.___", state 1528, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, "pan.___", state 1544, "(1)"
+       line 230, "pan.___", state 1552, "(1)"
+       line 234, "pan.___", state 1564, "(1)"
+       line 238, "pan.___", state 1572, "(1)"
+       line 249, "pan.___", state 1603, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 253, "pan.___", state 1612, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, "pan.___", state 1625, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, "pan.___", state 1634, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, "pan.___", state 1650, "(1)"
+       line 230, "pan.___", state 1658, "(1)"
+       line 234, "pan.___", state 1670, "(1)"
+       line 238, "pan.___", state 1678, "(1)"
+       line 1203, "pan.___", state 1694, "-end-"
+       (103 of 1694 states)
+unreached in proctype :init:
+       (0 of 78 states)
+unreached in proctype :never:
+       line 1262, "pan.___", state 8, "-end-"
+       (1 of 8 states)
+
+pan: elapsed time 5.54e+03 seconds
+pan: rate 2789.4684 states/second
+pan: avg transition delay 1.2972e-06 usec
+cp .input.spin urcu_free.spin.input
+cp .input.spin.trail urcu_free.spin.input.trail
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_free.ltl b/formal-model/results/urcu-controldataflow-ipi/urcu_free.ltl
new file mode 100644 (file)
index 0000000..6be1be9
--- /dev/null
@@ -0,0 +1 @@
+[] (!read_poison)
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_free.spin.input b/formal-model/results/urcu-controldataflow-ipi/urcu_free.spin.input
new file mode 100644 (file)
index 0000000..4640ac9
--- /dev/null
@@ -0,0 +1,1239 @@
+
+// Poison value for freed memory
+#define POISON 1
+// Memory with correct data
+#define WINE 0
+#define SLAB_SIZE 2
+
+#define read_poison    (data_read_first[0] == POISON || data_read_second[0] == POISON)
+
+#define RCU_GP_CTR_BIT (1 << 7)
+#define RCU_GP_CTR_NEST_MASK (RCU_GP_CTR_BIT - 1)
+
+//disabled
+#define REMOTE_BARRIERS
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+typedef per_proc_bit {
+       bit val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bitfield {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bitfield cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               /*
+                * 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, j);
+               reader_barrier[get_readerid()] = 0;
+       :: 1 ->
+               /*
+                * 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)
+//#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);                                                           \
+       i = 0;                                                                  \
+       do                                                                      \
+       :: i < NR_READERS ->                                                    \
+               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.                                            \
+                */                                                             \
+               do                                                              \
+               :: (reader_barrier[i] == 1) ->                                  \
+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(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, smp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only one reader */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* RCU data */
+DECLARE_CACHED_VAR(bit, rcu_data[SLAB_SIZE]);
+
+/* RCU pointer */
+#if (SLAB_SIZE == 2)
+DECLARE_CACHED_VAR(bit, rcu_ptr);
+bit ptr_read_first[NR_READERS];
+bit ptr_read_second[NR_READERS];
+#else
+DECLARE_CACHED_VAR(byte, rcu_ptr);
+byte ptr_read_first[NR_READERS];
+byte ptr_read_second[NR_READERS];
+#endif
+
+bit data_read_first[NR_READERS];
+bit data_read_second[NR_READERS];
+
+bit init_done = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               ptr_read_first[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb1;
+rmb1_end:
+                               data_read_first[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_first[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               ptr_read_second[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb2;
+rmb2_end:
+                               data_read_second[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_second[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+rmb1:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb1_end;
+rmb2:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_DATA                     (1 << 1)
+#define WRITE_PROC_WMB                 (1 << 2)
+#define WRITE_XCHG_PTR                 (1 << 3)
+
+#define WRITE_PROC_FIRST_MB            (1 << 4)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 5)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 6)
+#define WRITE_PROC_FIRST_WAIT          (1 << 7)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 8)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 9)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 10)
+#define WRITE_PROC_SECOND_WAIT         (1 << 11)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 12)
+
+#define WRITE_PROC_SECOND_MB           (1 << 13)
+
+#define WRITE_FREE                     (1 << 14)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_DATA                    \
+                                       | WRITE_PROC_WMB                \
+                                       | WRITE_XCHG_PTR                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB          \
+                                       | WRITE_FREE)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 15) - 1)
+
+/*
+ * Mutexes are implied around writer execution. A single writer at a time.
+ */
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte cur_data = 0, old_data, loop_nr = 0;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (loop_nr < 3) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               loop_nr = loop_nr + 1;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_WMB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+#endif
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_DATA) ->
+                       ooo_mem(i);
+                       cur_data = (cur_data + 1) % SLAB_SIZE;
+                       WRITE_CACHED_VAR(rcu_data[cur_data], WINE);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_DATA);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA,
+                                 WRITE_PROC_WMB) ->
+                       smp_wmb(i, j);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_WMB,
+                                 WRITE_XCHG_PTR) ->
+                       /* rcu_xchg_pointer() */
+                       atomic {
+                               old_data = READ_CACHED_VAR(rcu_ptr);
+                               WRITE_CACHED_VAR(rcu_ptr, cur_data);
+                       }
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_XCHG_PTR);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_WMB      /* No dependency on
+                                                        * WRITE_DATA because we
+                                                        * write to a
+                                                        * different location. */
+                                 | WRITE_PROC_SECOND_MB
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_FREE) ->
+                       WRITE_CACHED_VAR(rcu_data[old_data], POISON);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_FREE);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+               /*
+                * Note : Promela model adds implicit serialization of the
+                * WRITE_FREE instruction. Normally, it would be permitted to
+                * spill on the next loop execution. Given the validation we do
+                * checks for the data entry read to be poisoned, it's ok if
+                * we do not check "late arriving" memory poisoning.
+                */
+       :: 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
+#ifdef READER_PROGRESS
+               /*
+                * Make sure we don't block the reader's progress.
+                */
+               smp_mb_send(i, j, 5);
+#endif
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(rcu_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       ptr_read_first[i] = 1;
+                       ptr_read_second[i] = 1;
+                       data_read_first[i] = WINE;
+                       data_read_second[i] = WINE;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               INIT_CACHED_VAR(rcu_data[0], WINE, j);
+               i = 1;
+               do
+               :: i < SLAB_SIZE ->
+                       INIT_CACHED_VAR(rcu_data[i], POISON, j);
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_free.spin.input.trail b/formal-model/results/urcu-controldataflow-ipi/urcu_free.spin.input.trail
new file mode 100644 (file)
index 0000000..011045f
--- /dev/null
@@ -0,0 +1,2598 @@
+-2:3:-2
+-4:-4:-4
+1:0:4863
+2:3:4786
+3:3:4789
+4:3:4789
+5:3:4792
+6:3:4800
+7:3:4800
+8:3:4803
+9:3:4809
+10:3:4813
+11:3:4813
+12:3:4816
+13:3:4823
+14:3:4831
+15:3:4831
+16:3:4834
+17:3:4840
+18:3:4844
+19:3:4844
+20:3:4847
+21:3:4853
+22:3:4857
+23:3:4858
+24:0:4863
+25:3:4860
+26:0:4863
+27:2:3279
+28:0:4863
+29:2:3285
+30:0:4863
+31:2:3286
+32:0:4863
+33:2:3289
+34:2:3293
+35:2:3294
+36:2:3302
+37:2:3303
+38:2:3307
+39:2:3308
+40:2:3316
+41:2:3321
+42:2:3325
+43:2:3326
+44:2:3334
+45:2:3335
+46:2:3339
+47:2:3340
+48:2:3334
+49:2:3335
+50:2:3339
+51:2:3340
+52:2:3348
+53:2:3353
+54:2:3354
+55:2:3365
+56:2:3366
+57:2:3367
+58:2:3378
+59:2:3383
+60:2:3384
+61:2:3395
+62:2:3396
+63:2:3397
+64:2:3395
+65:2:3396
+66:2:3397
+67:2:3408
+68:2:3412
+69:0:4863
+70:2:3415
+71:0:4863
+72:2:3421
+73:2:3422
+74:2:3426
+75:2:3430
+76:2:3431
+77:2:3435
+78:2:3443
+79:2:3444
+80:2:3448
+81:2:3452
+82:2:3453
+83:2:3448
+84:2:3449
+85:2:3457
+86:2:3461
+87:0:4863
+88:2:3464
+89:0:4863
+90:2:3465
+91:2:3469
+92:2:3470
+93:2:3478
+94:2:3479
+95:2:3483
+96:2:3484
+97:2:3492
+98:2:3497
+99:2:3501
+100:2:3502
+101:2:3510
+102:2:3511
+103:2:3515
+104:2:3516
+105:2:3510
+106:2:3511
+107:2:3515
+108:2:3516
+109:2:3524
+110:2:3529
+111:2:3530
+112:2:3541
+113:2:3542
+114:2:3543
+115:2:3554
+116:2:3559
+117:2:3560
+118:2:3571
+119:2:3572
+120:2:3573
+121:2:3571
+122:2:3572
+123:2:3573
+124:2:3584
+125:2:3588
+126:0:4863
+127:2:3591
+128:0:4863
+129:2:3594
+130:2:3598
+131:2:3599
+132:2:3607
+133:2:3608
+134:2:3612
+135:2:3613
+136:2:3621
+137:2:3626
+138:2:3627
+139:2:3639
+140:2:3640
+141:2:3644
+142:2:3645
+143:2:3639
+144:2:3640
+145:2:3644
+146:2:3645
+147:2:3653
+148:2:3658
+149:2:3659
+150:2:3670
+151:2:3671
+152:2:3672
+153:2:3683
+154:2:3688
+155:2:3689
+156:2:3700
+157:2:3701
+158:2:3702
+159:2:3700
+160:2:3701
+161:2:3702
+162:2:3713
+163:2:3717
+164:0:4863
+165:2:3720
+166:0:4863
+167:2:3721
+168:0:4863
+169:2:3722
+170:0:4863
+171:2:4423
+172:2:4424
+173:2:4428
+174:2:4432
+175:2:4433
+176:2:4437
+177:2:4445
+178:2:4446
+179:2:4450
+180:2:4454
+181:2:4455
+182:2:4450
+183:2:4454
+184:2:4455
+185:2:4459
+186:2:4466
+187:2:4473
+188:2:4474
+189:2:4481
+190:2:4486
+191:2:4493
+192:2:4494
+193:2:4493
+194:2:4494
+195:2:4501
+196:2:4505
+197:0:4863
+198:2:3724
+199:2:4401
+200:0:4863
+201:2:3721
+202:0:4863
+203:2:3725
+204:0:4863
+205:2:3721
+206:0:4863
+207:2:3728
+208:2:3729
+209:2:3733
+210:2:3734
+211:2:3742
+212:2:3743
+213:2:3747
+214:2:3748
+215:2:3756
+216:2:3761
+217:2:3765
+218:2:3766
+219:2:3774
+220:2:3775
+221:2:3779
+222:2:3780
+223:2:3774
+224:2:3775
+225:2:3779
+226:2:3780
+227:2:3788
+228:2:3793
+229:2:3794
+230:2:3805
+231:2:3806
+232:2:3807
+233:2:3818
+234:2:3823
+235:2:3824
+236:2:3835
+237:2:3836
+238:2:3837
+239:2:3835
+240:2:3836
+241:2:3837
+242:2:3848
+243:2:3855
+244:0:4863
+245:2:3721
+246:0:4863
+247:2:3859
+248:2:3860
+249:2:3861
+250:2:3873
+251:2:3874
+252:2:3878
+253:2:3879
+254:2:3887
+255:2:3892
+256:2:3896
+257:2:3897
+258:2:3905
+259:2:3906
+260:2:3910
+261:2:3911
+262:2:3905
+263:2:3906
+264:2:3910
+265:2:3911
+266:2:3919
+267:2:3924
+268:2:3925
+269:2:3936
+270:2:3937
+271:2:3938
+272:2:3949
+273:2:3954
+274:2:3955
+275:2:3966
+276:2:3967
+277:2:3968
+278:2:3966
+279:2:3967
+280:2:3968
+281:2:3979
+282:2:3990
+283:2:3991
+284:0:4863
+285:2:3721
+286:0:4863
+287:2:3997
+288:2:3998
+289:2:4002
+290:2:4003
+291:2:4011
+292:2:4012
+293:2:4016
+294:2:4017
+295:2:4025
+296:2:4030
+297:2:4034
+298:2:4035
+299:2:4043
+300:2:4044
+301:2:4048
+302:2:4049
+303:2:4043
+304:2:4044
+305:2:4048
+306:2:4049
+307:2:4057
+308:2:4062
+309:2:4063
+310:2:4074
+311:2:4075
+312:2:4076
+313:2:4087
+314:2:4092
+315:2:4093
+316:2:4104
+317:2:4105
+318:2:4106
+319:2:4104
+320:2:4105
+321:2:4106
+322:2:4117
+323:0:4863
+324:2:3721
+325:0:4863
+326:2:4126
+327:2:4127
+328:2:4131
+329:2:4132
+330:2:4140
+331:2:4141
+332:2:4145
+333:2:4146
+334:2:4154
+335:2:4159
+336:2:4163
+337:2:4164
+338:2:4172
+339:2:4173
+340:2:4177
+341:2:4178
+342:2:4172
+343:2:4173
+344:2:4177
+345:2:4178
+346:2:4186
+347:2:4191
+348:2:4192
+349:2:4203
+350:2:4204
+351:2:4205
+352:2:4216
+353:2:4221
+354:2:4222
+355:2:4233
+356:2:4234
+357:2:4235
+358:2:4233
+359:2:4234
+360:2:4235
+361:2:4246
+362:2:4253
+363:0:4863
+364:2:3721
+365:0:4863
+366:2:4257
+367:2:4258
+368:2:4259
+369:2:4271
+370:2:4272
+371:2:4276
+372:2:4277
+373:2:4285
+374:2:4290
+375:2:4294
+376:2:4295
+377:2:4303
+378:2:4304
+379:2:4308
+380:2:4309
+381:2:4303
+382:2:4304
+383:2:4308
+384:2:4309
+385:2:4317
+386:2:4322
+387:2:4323
+388:2:4334
+389:2:4335
+390:2:4336
+391:2:4347
+392:2:4352
+393:2:4353
+394:2:4364
+395:2:4365
+396:2:4366
+397:2:4364
+398:2:4365
+399:2:4366
+400:2:4377
+401:2:4387
+402:2:4388
+403:0:4863
+404:2:3721
+405:0:4863
+406:2:4394
+407:0:4863
+408:2:4696
+409:2:4697
+410:2:4701
+411:2:4705
+412:2:4706
+413:2:4710
+414:2:4718
+415:2:4719
+416:2:4723
+417:2:4727
+418:2:4728
+419:2:4723
+420:2:4727
+421:2:4728
+422:2:4732
+423:2:4739
+424:2:4746
+425:2:4747
+426:2:4754
+427:2:4759
+428:2:4766
+429:2:4767
+430:2:4766
+431:2:4767
+432:2:4774
+433:2:4778
+434:0:4863
+435:2:4396
+436:2:4401
+437:0:4863
+438:2:3721
+439:0:4863
+440:2:4397
+441:0:4863
+442:2:4405
+443:0:4863
+444:2:4406
+445:0:4863
+446:2:3286
+447:0:4863
+448:2:3289
+449:2:3293
+450:2:3294
+451:2:3302
+452:2:3303
+453:2:3307
+454:2:3308
+455:2:3316
+456:2:3321
+457:2:3325
+458:2:3326
+459:2:3334
+460:2:3335
+461:2:3336
+462:2:3334
+463:2:3335
+464:2:3339
+465:2:3340
+466:2:3348
+467:2:3353
+468:2:3354
+469:2:3365
+470:2:3366
+471:2:3367
+472:2:3378
+473:2:3383
+474:2:3384
+475:2:3395
+476:2:3396
+477:2:3397
+478:2:3395
+479:2:3396
+480:2:3397
+481:2:3408
+482:2:3412
+483:0:4863
+484:2:3415
+485:0:4863
+486:2:3421
+487:2:3422
+488:2:3426
+489:2:3430
+490:2:3431
+491:2:3435
+492:2:3443
+493:2:3444
+494:2:3448
+495:2:3449
+496:2:3448
+497:2:3452
+498:2:3453
+499:2:3457
+500:2:3461
+501:0:4863
+502:2:3464
+503:0:4863
+504:2:3465
+505:2:3469
+506:2:3470
+507:2:3478
+508:2:3479
+509:2:3483
+510:2:3484
+511:2:3492
+512:2:3497
+513:2:3501
+514:2:3502
+515:2:3510
+516:2:3511
+517:2:3515
+518:2:3516
+519:2:3510
+520:2:3511
+521:2:3515
+522:2:3516
+523:2:3524
+524:2:3529
+525:2:3530
+526:2:3541
+527:2:3542
+528:2:3543
+529:2:3554
+530:2:3559
+531:2:3560
+532:2:3571
+533:2:3572
+534:2:3573
+535:2:3571
+536:2:3572
+537:2:3573
+538:2:3584
+539:2:3588
+540:0:4863
+541:2:3591
+542:0:4863
+543:2:3594
+544:2:3598
+545:2:3599
+546:2:3607
+547:2:3608
+548:2:3612
+549:2:3613
+550:2:3621
+551:2:3626
+552:2:3627
+553:2:3639
+554:2:3640
+555:2:3644
+556:2:3645
+557:2:3639
+558:2:3640
+559:2:3644
+560:2:3645
+561:2:3653
+562:2:3658
+563:2:3659
+564:2:3670
+565:2:3671
+566:2:3672
+567:2:3683
+568:2:3688
+569:2:3689
+570:2:3700
+571:2:3701
+572:2:3702
+573:2:3700
+574:2:3701
+575:2:3702
+576:2:3713
+577:2:3717
+578:0:4863
+579:2:3720
+580:0:4863
+581:2:3721
+582:0:4863
+583:2:3722
+584:0:4863
+585:2:4423
+586:2:4424
+587:2:4428
+588:2:4432
+589:2:4433
+590:2:4437
+591:2:4445
+592:2:4446
+593:2:4450
+594:2:4454
+595:2:4455
+596:2:4450
+597:2:4454
+598:2:4455
+599:2:4459
+600:2:4466
+601:2:4473
+602:2:4474
+603:2:4481
+604:2:4486
+605:2:4493
+606:2:4494
+607:2:4493
+608:2:4494
+609:2:4501
+610:2:4505
+611:0:4863
+612:2:3724
+613:2:4401
+614:0:4863
+615:2:3721
+616:0:4863
+617:2:3725
+618:0:4863
+619:2:3721
+620:0:4863
+621:2:3728
+622:2:3729
+623:2:3733
+624:2:3734
+625:2:3742
+626:2:3743
+627:2:3747
+628:2:3748
+629:2:3756
+630:2:3761
+631:2:3765
+632:2:3766
+633:2:3774
+634:2:3775
+635:2:3779
+636:2:3780
+637:2:3774
+638:2:3775
+639:2:3779
+640:2:3780
+641:2:3788
+642:2:3793
+643:2:3794
+644:2:3805
+645:2:3806
+646:2:3807
+647:2:3818
+648:2:3823
+649:2:3824
+650:2:3835
+651:2:3836
+652:2:3837
+653:2:3835
+654:2:3836
+655:2:3837
+656:2:3848
+657:2:3855
+658:0:4863
+659:2:3721
+660:0:4863
+661:2:3859
+662:2:3860
+663:2:3861
+664:2:3873
+665:2:3874
+666:2:3878
+667:2:3879
+668:2:3887
+669:2:3892
+670:2:3896
+671:2:3897
+672:2:3905
+673:2:3906
+674:2:3910
+675:2:3911
+676:2:3905
+677:2:3906
+678:2:3910
+679:2:3911
+680:2:3919
+681:2:3924
+682:2:3925
+683:2:3936
+684:2:3937
+685:2:3938
+686:2:3949
+687:2:3954
+688:2:3955
+689:2:3966
+690:2:3967
+691:2:3968
+692:2:3966
+693:2:3967
+694:2:3968
+695:2:3979
+696:2:3990
+697:2:3991
+698:0:4863
+699:2:3721
+700:0:4863
+701:2:3997
+702:2:3998
+703:2:4002
+704:2:4003
+705:2:4011
+706:2:4012
+707:2:4016
+708:2:4017
+709:2:4025
+710:2:4030
+711:2:4034
+712:2:4035
+713:2:4043
+714:2:4044
+715:2:4048
+716:2:4049
+717:2:4043
+718:2:4044
+719:2:4048
+720:2:4049
+721:2:4057
+722:2:4062
+723:2:4063
+724:2:4074
+725:2:4075
+726:2:4076
+727:2:4087
+728:2:4092
+729:2:4093
+730:2:4104
+731:2:4105
+732:2:4106
+733:2:4104
+734:2:4105
+735:2:4106
+736:2:4117
+737:0:4863
+738:2:3721
+739:0:4863
+740:2:4126
+741:2:4127
+742:2:4131
+743:2:4132
+744:2:4140
+745:2:4141
+746:2:4145
+747:2:4146
+748:2:4154
+749:2:4159
+750:2:4163
+751:2:4164
+752:2:4172
+753:2:4173
+754:2:4177
+755:2:4178
+756:2:4172
+757:2:4173
+758:2:4177
+759:2:4178
+760:2:4186
+761:2:4191
+762:2:4192
+763:2:4203
+764:2:4204
+765:2:4205
+766:2:4216
+767:2:4221
+768:2:4222
+769:2:4233
+770:2:4234
+771:2:4235
+772:2:4233
+773:2:4234
+774:2:4235
+775:2:4246
+776:2:4253
+777:0:4863
+778:2:3721
+779:0:4863
+780:2:4257
+781:2:4258
+782:2:4259
+783:2:4271
+784:2:4272
+785:2:4276
+786:2:4277
+787:2:4285
+788:2:4290
+789:2:4294
+790:2:4295
+791:2:4303
+792:2:4304
+793:2:4308
+794:2:4309
+795:2:4303
+796:2:4304
+797:2:4308
+798:2:4309
+799:2:4317
+800:2:4322
+801:2:4323
+802:2:4334
+803:2:4335
+804:2:4336
+805:2:4347
+806:2:4352
+807:2:4353
+808:2:4364
+809:2:4365
+810:2:4366
+811:2:4364
+812:2:4365
+813:2:4366
+814:2:4377
+815:2:4387
+816:2:4388
+817:0:4863
+818:2:3721
+819:0:4863
+820:2:4394
+821:0:4863
+822:2:4696
+823:2:4697
+824:2:4701
+825:2:4705
+826:2:4706
+827:2:4710
+828:2:4718
+829:2:4719
+830:2:4723
+831:2:4727
+832:2:4728
+833:2:4723
+834:2:4727
+835:2:4728
+836:2:4732
+837:2:4739
+838:2:4746
+839:2:4747
+840:2:4754
+841:2:4759
+842:2:4766
+843:2:4767
+844:2:4766
+845:2:4767
+846:2:4774
+847:2:4778
+848:0:4863
+849:2:4396
+850:2:4401
+851:0:4863
+852:2:3721
+853:0:4863
+854:2:4397
+855:0:4863
+856:2:4405
+857:0:4863
+858:2:4406
+859:0:4863
+860:2:3286
+861:0:4863
+862:2:3289
+863:2:3293
+864:2:3294
+865:2:3302
+866:2:3303
+867:2:3307
+868:2:3308
+869:2:3316
+870:2:3321
+871:2:3325
+872:2:3326
+873:2:3334
+874:2:3335
+875:2:3339
+876:2:3340
+877:2:3334
+878:2:3335
+879:2:3336
+880:2:3348
+881:2:3353
+882:2:3354
+883:2:3365
+884:2:3366
+885:2:3367
+886:2:3378
+887:2:3383
+888:2:3384
+889:2:3395
+890:2:3396
+891:2:3397
+892:2:3395
+893:2:3396
+894:2:3397
+895:2:3408
+896:2:3412
+897:0:4863
+898:2:3415
+899:0:4863
+900:2:3421
+901:2:3422
+902:2:3426
+903:2:3430
+904:2:3431
+905:2:3435
+906:2:3443
+907:2:3444
+908:2:3448
+909:2:3452
+910:2:3453
+911:2:3448
+912:2:3449
+913:2:3457
+914:2:3461
+915:0:4863
+916:2:3464
+917:0:4863
+918:2:3465
+919:2:3469
+920:2:3470
+921:2:3478
+922:2:3479
+923:2:3483
+924:2:3484
+925:2:3492
+926:2:3497
+927:2:3501
+928:2:3502
+929:2:3510
+930:2:3511
+931:2:3515
+932:2:3516
+933:2:3510
+934:2:3511
+935:2:3515
+936:2:3516
+937:2:3524
+938:2:3529
+939:2:3530
+940:2:3541
+941:2:3542
+942:2:3543
+943:2:3554
+944:2:3559
+945:2:3560
+946:2:3571
+947:2:3572
+948:2:3573
+949:2:3571
+950:2:3572
+951:2:3573
+952:2:3584
+953:2:3588
+954:0:4863
+955:2:3591
+956:0:4863
+957:2:3594
+958:2:3598
+959:2:3599
+960:2:3607
+961:2:3608
+962:2:3612
+963:2:3613
+964:2:3621
+965:2:3626
+966:2:3627
+967:2:3639
+968:2:3640
+969:2:3644
+970:2:3645
+971:2:3639
+972:2:3640
+973:2:3644
+974:2:3645
+975:2:3653
+976:2:3658
+977:2:3659
+978:2:3670
+979:2:3671
+980:2:3672
+981:2:3683
+982:2:3688
+983:2:3689
+984:2:3700
+985:2:3701
+986:2:3702
+987:2:3700
+988:2:3701
+989:2:3702
+990:2:3713
+991:2:3717
+992:0:4863
+993:2:3720
+994:0:4863
+995:2:3721
+996:0:4863
+997:2:3722
+998:0:4863
+999:2:4423
+1000:2:4424
+1001:2:4428
+1002:2:4432
+1003:2:4433
+1004:2:4437
+1005:2:4445
+1006:2:4446
+1007:2:4450
+1008:2:4454
+1009:2:4455
+1010:2:4450
+1011:2:4454
+1012:2:4455
+1013:2:4459
+1014:2:4466
+1015:2:4473
+1016:2:4474
+1017:2:4481
+1018:2:4486
+1019:2:4493
+1020:2:4494
+1021:2:4493
+1022:2:4494
+1023:2:4501
+1024:2:4505
+1025:0:4863
+1026:2:3724
+1027:2:4401
+1028:0:4863
+1029:2:3721
+1030:0:4863
+1031:2:3725
+1032:0:4863
+1033:2:3721
+1034:0:4863
+1035:2:3728
+1036:2:3729
+1037:2:3733
+1038:2:3734
+1039:2:3742
+1040:2:3743
+1041:2:3747
+1042:2:3748
+1043:2:3756
+1044:2:3761
+1045:2:3765
+1046:2:3766
+1047:2:3774
+1048:2:3775
+1049:2:3779
+1050:2:3780
+1051:2:3774
+1052:2:3775
+1053:2:3779
+1054:2:3780
+1055:2:3788
+1056:2:3793
+1057:2:3794
+1058:2:3805
+1059:2:3806
+1060:2:3807
+1061:2:3818
+1062:2:3823
+1063:2:3824
+1064:2:3835
+1065:2:3836
+1066:2:3837
+1067:2:3835
+1068:2:3836
+1069:2:3837
+1070:2:3848
+1071:2:3855
+1072:0:4863
+1073:2:3721
+1074:0:4863
+1075:2:3859
+1076:2:3860
+1077:2:3861
+1078:2:3873
+1079:2:3874
+1080:2:3878
+1081:2:3879
+1082:2:3887
+1083:2:3892
+1084:2:3896
+1085:2:3897
+1086:2:3905
+1087:2:3906
+1088:2:3910
+1089:2:3911
+1090:2:3905
+1091:2:3906
+1092:2:3910
+1093:2:3911
+1094:2:3919
+1095:2:3924
+1096:2:3925
+1097:2:3936
+1098:2:3937
+1099:2:3938
+1100:2:3949
+1101:2:3954
+1102:2:3955
+1103:2:3966
+1104:2:3967
+1105:2:3968
+1106:2:3966
+1107:2:3967
+1108:2:3968
+1109:2:3979
+1110:2:3990
+1111:2:3991
+1112:0:4863
+1113:2:3721
+1114:0:4863
+1115:2:3997
+1116:2:3998
+1117:2:4002
+1118:2:4003
+1119:2:4011
+1120:2:4012
+1121:2:4016
+1122:2:4017
+1123:2:4025
+1124:2:4030
+1125:2:4034
+1126:2:4035
+1127:2:4043
+1128:2:4044
+1129:2:4048
+1130:2:4049
+1131:2:4043
+1132:2:4044
+1133:2:4048
+1134:2:4049
+1135:2:4057
+1136:2:4062
+1137:2:4063
+1138:2:4074
+1139:2:4075
+1140:2:4076
+1141:2:4087
+1142:2:4092
+1143:2:4093
+1144:2:4104
+1145:2:4105
+1146:2:4106
+1147:2:4104
+1148:2:4105
+1149:2:4106
+1150:2:4117
+1151:0:4863
+1152:2:3721
+1153:0:4863
+1154:2:4126
+1155:2:4127
+1156:2:4131
+1157:2:4132
+1158:2:4140
+1159:2:4141
+1160:2:4145
+1161:2:4146
+1162:2:4154
+1163:2:4159
+1164:2:4163
+1165:2:4164
+1166:2:4172
+1167:2:4173
+1168:2:4177
+1169:2:4178
+1170:2:4172
+1171:2:4173
+1172:2:4177
+1173:2:4178
+1174:2:4186
+1175:2:4191
+1176:2:4192
+1177:2:4203
+1178:2:4204
+1179:2:4205
+1180:2:4216
+1181:2:4221
+1182:2:4222
+1183:2:4233
+1184:2:4234
+1185:2:4235
+1186:2:4233
+1187:2:4234
+1188:2:4235
+1189:2:4246
+1190:2:4253
+1191:0:4863
+1192:2:3721
+1193:0:4863
+1194:2:4257
+1195:2:4258
+1196:2:4259
+1197:2:4271
+1198:2:4272
+1199:2:4276
+1200:2:4277
+1201:2:4285
+1202:2:4290
+1203:2:4294
+1204:2:4295
+1205:2:4303
+1206:2:4304
+1207:2:4308
+1208:2:4309
+1209:2:4303
+1210:2:4304
+1211:2:4308
+1212:2:4309
+1213:2:4317
+1214:2:4322
+1215:2:4323
+1216:2:4334
+1217:2:4335
+1218:2:4336
+1219:2:4347
+1220:2:4352
+1221:2:4353
+1222:2:4364
+1223:2:4365
+1224:2:4366
+1225:2:4364
+1226:2:4365
+1227:2:4366
+1228:2:4377
+1229:2:4387
+1230:2:4388
+1231:0:4863
+1232:2:3721
+1233:0:4863
+1234:2:4394
+1235:0:4863
+1236:2:4696
+1237:2:4697
+1238:2:4701
+1239:2:4705
+1240:2:4706
+1241:2:4710
+1242:2:4718
+1243:2:4719
+1244:2:4723
+1245:2:4727
+1246:2:4728
+1247:2:4723
+1248:2:4727
+1249:2:4728
+1250:2:4732
+1251:2:4739
+1252:2:4746
+1253:2:4747
+1254:2:4754
+1255:2:4759
+1256:2:4766
+1257:2:4767
+1258:2:4766
+1259:2:4767
+1260:2:4774
+1261:2:4778
+1262:0:4863
+1263:2:4396
+1264:2:4401
+1265:0:4863
+1266:2:3721
+1267:0:4863
+1268:2:4397
+1269:0:4863
+1270:2:4405
+1271:0:4863
+1272:2:4406
+1273:0:4863
+1274:2:3286
+1275:0:4863
+1276:2:3289
+1277:2:3293
+1278:2:3294
+1279:2:3302
+1280:2:3303
+1281:2:3307
+1282:2:3308
+1283:2:3316
+1284:2:3321
+1285:2:3325
+1286:2:3326
+1287:2:3334
+1288:2:3335
+1289:2:3336
+1290:2:3334
+1291:2:3335
+1292:2:3339
+1293:2:3340
+1294:2:3348
+1295:2:3353
+1296:2:3354
+1297:2:3365
+1298:2:3366
+1299:2:3367
+1300:2:3378
+1301:2:3383
+1302:2:3384
+1303:2:3395
+1304:2:3396
+1305:2:3397
+1306:2:3395
+1307:2:3396
+1308:2:3397
+1309:2:3408
+1310:2:3412
+1311:0:4863
+1312:2:3415
+1313:0:4863
+1314:2:3421
+1315:2:3422
+1316:2:3426
+1317:2:3430
+1318:2:3431
+1319:2:3435
+1320:2:3443
+1321:2:3444
+1322:2:3448
+1323:2:3449
+1324:2:3448
+1325:2:3452
+1326:2:3453
+1327:2:3457
+1328:2:3461
+1329:0:4863
+1330:2:3464
+1331:0:4863
+1332:2:3465
+1333:2:3469
+1334:2:3470
+1335:2:3478
+1336:2:3479
+1337:2:3483
+1338:2:3484
+1339:2:3492
+1340:2:3497
+1341:2:3501
+1342:2:3502
+1343:2:3510
+1344:2:3511
+1345:2:3515
+1346:2:3516
+1347:2:3510
+1348:2:3511
+1349:2:3515
+1350:2:3516
+1351:2:3524
+1352:2:3529
+1353:2:3530
+1354:2:3541
+1355:2:3542
+1356:2:3543
+1357:2:3554
+1358:2:3559
+1359:2:3560
+1360:2:3571
+1361:2:3572
+1362:2:3573
+1363:2:3571
+1364:2:3572
+1365:2:3573
+1366:2:3584
+1367:2:3588
+1368:0:4863
+1369:2:3591
+1370:0:4863
+1371:2:3594
+1372:2:3598
+1373:2:3599
+1374:2:3607
+1375:2:3608
+1376:2:3612
+1377:2:3613
+1378:2:3621
+1379:2:3626
+1380:2:3627
+1381:2:3639
+1382:2:3640
+1383:2:3644
+1384:2:3645
+1385:2:3639
+1386:2:3640
+1387:2:3644
+1388:2:3645
+1389:2:3653
+1390:2:3658
+1391:2:3659
+1392:2:3670
+1393:2:3671
+1394:2:3672
+1395:2:3683
+1396:2:3688
+1397:2:3689
+1398:2:3700
+1399:2:3701
+1400:2:3702
+1401:2:3700
+1402:2:3701
+1403:2:3702
+1404:2:3713
+1405:2:3717
+1406:0:4863
+1407:2:3720
+1408:0:4863
+1409:2:3721
+1410:0:4863
+1411:2:3722
+1412:0:4863
+1413:2:4423
+1414:2:4424
+1415:2:4428
+1416:2:4432
+1417:2:4433
+1418:2:4437
+1419:2:4445
+1420:2:4446
+1421:2:4450
+1422:2:4454
+1423:2:4455
+1424:2:4450
+1425:2:4454
+1426:2:4455
+1427:2:4459
+1428:2:4466
+1429:2:4473
+1430:2:4474
+1431:2:4481
+1432:2:4486
+1433:2:4493
+1434:2:4494
+1435:2:4493
+1436:2:4494
+1437:2:4501
+1438:2:4505
+1439:0:4863
+1440:2:3724
+1441:2:4401
+1442:0:4863
+1443:2:3721
+1444:0:4863
+1445:2:3725
+1446:0:4863
+1447:2:3721
+1448:0:4863
+1449:2:3728
+1450:2:3729
+1451:2:3733
+1452:2:3734
+1453:2:3742
+1454:2:3743
+1455:2:3747
+1456:2:3748
+1457:2:3756
+1458:2:3761
+1459:2:3765
+1460:2:3766
+1461:2:3774
+1462:2:3775
+1463:2:3779
+1464:2:3780
+1465:2:3774
+1466:2:3775
+1467:2:3779
+1468:2:3780
+1469:2:3788
+1470:2:3793
+1471:2:3794
+1472:2:3805
+1473:2:3806
+1474:2:3807
+1475:2:3818
+1476:2:3823
+1477:2:3824
+1478:2:3835
+1479:2:3836
+1480:2:3837
+1481:2:3835
+1482:2:3836
+1483:2:3837
+1484:2:3848
+1485:2:3855
+1486:0:4863
+1487:2:3721
+1488:0:4863
+1489:2:3859
+1490:2:3860
+1491:2:3861
+1492:2:3873
+1493:2:3874
+1494:2:3878
+1495:2:3879
+1496:2:3887
+1497:2:3892
+1498:2:3896
+1499:2:3897
+1500:2:3905
+1501:2:3906
+1502:2:3910
+1503:2:3911
+1504:2:3905
+1505:2:3906
+1506:2:3910
+1507:2:3911
+1508:2:3919
+1509:2:3924
+1510:2:3925
+1511:2:3936
+1512:2:3937
+1513:2:3938
+1514:2:3949
+1515:2:3954
+1516:2:3955
+1517:2:3966
+1518:2:3967
+1519:2:3968
+1520:2:3966
+1521:2:3967
+1522:2:3968
+1523:2:3979
+1524:2:3990
+1525:2:3991
+1526:0:4863
+1527:2:3721
+1528:0:4863
+1529:2:3997
+1530:2:3998
+1531:2:4002
+1532:2:4003
+1533:2:4011
+1534:2:4012
+1535:2:4016
+1536:2:4017
+1537:2:4025
+1538:2:4030
+1539:2:4034
+1540:2:4035
+1541:2:4043
+1542:2:4044
+1543:2:4048
+1544:2:4049
+1545:2:4043
+1546:2:4044
+1547:2:4048
+1548:2:4049
+1549:2:4057
+1550:2:4062
+1551:2:4063
+1552:2:4074
+1553:2:4075
+1554:2:4076
+1555:2:4087
+1556:2:4092
+1557:2:4093
+1558:2:4104
+1559:2:4105
+1560:2:4106
+1561:2:4104
+1562:2:4105
+1563:2:4106
+1564:2:4117
+1565:0:4863
+1566:2:3721
+1567:0:4863
+1568:2:4126
+1569:2:4127
+1570:2:4131
+1571:2:4132
+1572:2:4140
+1573:2:4141
+1574:2:4145
+1575:2:4146
+1576:2:4154
+1577:2:4159
+1578:2:4163
+1579:2:4164
+1580:2:4172
+1581:2:4173
+1582:2:4177
+1583:2:4178
+1584:2:4172
+1585:2:4173
+1586:2:4177
+1587:2:4178
+1588:2:4186
+1589:2:4191
+1590:2:4192
+1591:2:4203
+1592:2:4204
+1593:2:4205
+1594:2:4216
+1595:2:4221
+1596:2:4222
+1597:2:4233
+1598:2:4234
+1599:2:4235
+1600:2:4233
+1601:2:4234
+1602:2:4235
+1603:2:4246
+1604:2:4253
+1605:0:4863
+1606:2:3721
+1607:0:4863
+1608:2:4257
+1609:2:4258
+1610:2:4259
+1611:2:4271
+1612:2:4272
+1613:2:4276
+1614:2:4277
+1615:2:4285
+1616:2:4290
+1617:2:4294
+1618:2:4295
+1619:2:4303
+1620:2:4304
+1621:2:4308
+1622:2:4309
+1623:2:4303
+1624:2:4304
+1625:2:4308
+1626:2:4309
+1627:2:4317
+1628:2:4322
+1629:2:4323
+1630:2:4334
+1631:2:4335
+1632:2:4336
+1633:2:4347
+1634:2:4352
+1635:2:4353
+1636:2:4364
+1637:2:4365
+1638:2:4366
+1639:2:4364
+1640:2:4365
+1641:2:4366
+1642:2:4377
+1643:2:4387
+1644:2:4388
+1645:0:4863
+1646:2:3721
+1647:0:4863
+1648:2:4394
+1649:0:4863
+1650:2:4696
+1651:2:4697
+1652:2:4701
+1653:2:4705
+1654:2:4706
+1655:2:4710
+1656:2:4718
+1657:2:4719
+1658:2:4723
+1659:2:4727
+1660:2:4728
+1661:2:4723
+1662:2:4727
+1663:2:4728
+1664:2:4732
+1665:2:4739
+1666:2:4746
+1667:2:4747
+1668:2:4754
+1669:2:4759
+1670:2:4766
+1671:2:4767
+1672:2:4766
+1673:2:4767
+1674:2:4774
+1675:2:4778
+1676:0:4863
+1677:2:4396
+1678:2:4401
+1679:0:4863
+1680:2:3721
+1681:0:4863
+1682:2:4397
+1683:0:4863
+1684:2:4405
+1685:0:4863
+1686:2:4406
+1687:0:4863
+1688:2:3286
+1689:0:4863
+1690:2:3289
+1691:2:3293
+1692:2:3294
+1693:2:3302
+1694:2:3303
+1695:2:3307
+1696:2:3308
+1697:2:3316
+1698:2:3321
+1699:2:3325
+1700:2:3326
+1701:2:3334
+1702:2:3335
+1703:2:3339
+1704:2:3340
+1705:2:3334
+1706:2:3335
+1707:2:3336
+1708:2:3348
+1709:2:3353
+1710:2:3354
+1711:2:3365
+1712:2:3366
+1713:2:3367
+1714:2:3378
+1715:2:3383
+1716:2:3384
+1717:2:3395
+1718:2:3396
+1719:2:3397
+1720:2:3395
+1721:2:3396
+1722:2:3397
+1723:2:3408
+1724:2:3412
+1725:0:4863
+1726:2:3415
+1727:0:4863
+1728:1:2
+1729:0:4863
+1730:1:8
+1731:0:4863
+1732:1:9
+1733:0:4863
+1734:1:10
+1735:0:4863
+1736:1:11
+1737:0:4863
+1738:1:12
+1739:1:13
+1740:1:17
+1741:1:18
+1742:1:26
+1743:1:27
+1744:1:31
+1745:1:32
+1746:1:40
+1747:1:45
+1748:1:49
+1749:1:50
+1750:1:58
+1751:1:59
+1752:1:63
+1753:1:64
+1754:1:58
+1755:1:59
+1756:1:63
+1757:1:64
+1758:1:72
+1759:1:77
+1760:1:78
+1761:1:89
+1762:1:90
+1763:1:91
+1764:1:102
+1765:1:107
+1766:1:108
+1767:1:119
+1768:1:120
+1769:1:121
+1770:1:119
+1771:1:120
+1772:1:121
+1773:1:132
+1774:0:4863
+1775:1:11
+1776:0:4863
+1777:1:141
+1778:1:142
+1779:0:4863
+1780:1:11
+1781:0:4863
+1782:1:148
+1783:1:149
+1784:1:153
+1785:1:154
+1786:1:162
+1787:1:163
+1788:1:167
+1789:1:168
+1790:1:176
+1791:1:181
+1792:1:185
+1793:1:186
+1794:1:194
+1795:1:195
+1796:1:199
+1797:1:200
+1798:1:194
+1799:1:195
+1800:1:199
+1801:1:200
+1802:1:208
+1803:1:213
+1804:1:214
+1805:1:225
+1806:1:226
+1807:1:227
+1808:1:238
+1809:1:243
+1810:1:244
+1811:1:255
+1812:1:256
+1813:1:257
+1814:1:255
+1815:1:256
+1816:1:257
+1817:1:268
+1818:0:4863
+1819:1:11
+1820:0:4863
+1821:1:277
+1822:1:278
+1823:1:282
+1824:1:283
+1825:1:291
+1826:1:292
+1827:1:296
+1828:1:297
+1829:1:305
+1830:1:310
+1831:1:314
+1832:1:315
+1833:1:323
+1834:1:324
+1835:1:328
+1836:1:329
+1837:1:323
+1838:1:324
+1839:1:328
+1840:1:329
+1841:1:337
+1842:1:342
+1843:1:343
+1844:1:354
+1845:1:355
+1846:1:356
+1847:1:367
+1848:1:372
+1849:1:373
+1850:1:384
+1851:1:385
+1852:1:386
+1853:1:384
+1854:1:385
+1855:1:386
+1856:1:397
+1857:1:404
+1858:0:4863
+1859:1:11
+1860:0:4863
+1861:1:540
+1862:1:544
+1863:1:545
+1864:1:549
+1865:1:550
+1866:1:558
+1867:1:566
+1868:1:567
+1869:1:571
+1870:1:575
+1871:1:576
+1872:1:571
+1873:1:575
+1874:1:576
+1875:1:580
+1876:1:587
+1877:1:594
+1878:1:595
+1879:1:602
+1880:1:607
+1881:1:614
+1882:1:615
+1883:1:614
+1884:1:615
+1885:1:622
+1886:0:4863
+1887:1:11
+1888:0:4863
+1889:2:3421
+1890:2:3422
+1891:2:3426
+1892:2:3430
+1893:2:3431
+1894:2:3435
+1895:2:3443
+1896:2:3444
+1897:2:3448
+1898:2:3452
+1899:2:3453
+1900:2:3448
+1901:2:3449
+1902:2:3457
+1903:2:3461
+1904:0:4863
+1905:2:3464
+1906:0:4863
+1907:2:3465
+1908:2:3469
+1909:2:3470
+1910:2:3478
+1911:2:3479
+1912:2:3483
+1913:2:3484
+1914:2:3492
+1915:2:3497
+1916:2:3501
+1917:2:3502
+1918:2:3510
+1919:2:3511
+1920:2:3515
+1921:2:3516
+1922:2:3510
+1923:2:3511
+1924:2:3515
+1925:2:3516
+1926:2:3524
+1927:2:3529
+1928:2:3530
+1929:2:3541
+1930:2:3542
+1931:2:3543
+1932:2:3554
+1933:2:3559
+1934:2:3560
+1935:2:3571
+1936:2:3572
+1937:2:3573
+1938:2:3571
+1939:2:3572
+1940:2:3573
+1941:2:3584
+1942:2:3588
+1943:0:4863
+1944:2:3591
+1945:0:4863
+1946:2:3594
+1947:2:3598
+1948:2:3599
+1949:2:3607
+1950:2:3608
+1951:2:3612
+1952:2:3613
+1953:2:3621
+1954:2:3626
+1955:2:3627
+1956:2:3639
+1957:2:3640
+1958:2:3644
+1959:2:3645
+1960:2:3639
+1961:2:3640
+1962:2:3644
+1963:2:3645
+1964:2:3653
+1965:2:3658
+1966:2:3659
+1967:2:3670
+1968:2:3671
+1969:2:3672
+1970:2:3683
+1971:2:3688
+1972:2:3689
+1973:2:3700
+1974:2:3701
+1975:2:3702
+1976:2:3700
+1977:2:3701
+1978:2:3702
+1979:2:3713
+1980:2:3717
+1981:0:4863
+1982:2:3720
+1983:0:4863
+1984:2:3721
+1985:0:4863
+1986:2:3722
+1987:0:4863
+1988:2:4423
+1989:2:4424
+1990:2:4428
+1991:2:4432
+1992:2:4433
+1993:2:4437
+1994:2:4445
+1995:2:4446
+1996:2:4450
+1997:2:4454
+1998:2:4455
+1999:2:4450
+2000:2:4454
+2001:2:4455
+2002:2:4459
+2003:2:4466
+2004:2:4473
+2005:2:4474
+2006:2:4481
+2007:2:4486
+2008:2:4493
+2009:2:4494
+2010:2:4493
+2011:2:4494
+2012:2:4501
+2013:2:4505
+2014:0:4863
+2015:2:3724
+2016:2:4401
+2017:0:4863
+2018:2:3721
+2019:0:4863
+2020:2:3725
+2021:0:4863
+2022:2:3721
+2023:0:4863
+2024:2:3728
+2025:2:3729
+2026:2:3733
+2027:2:3734
+2028:2:3742
+2029:2:3743
+2030:2:3747
+2031:2:3748
+2032:2:3756
+2033:2:3761
+2034:2:3765
+2035:2:3766
+2036:2:3774
+2037:2:3775
+2038:2:3779
+2039:2:3780
+2040:2:3774
+2041:2:3775
+2042:2:3779
+2043:2:3780
+2044:2:3788
+2045:2:3793
+2046:2:3794
+2047:2:3805
+2048:2:3806
+2049:2:3807
+2050:2:3818
+2051:2:3823
+2052:2:3824
+2053:2:3835
+2054:2:3836
+2055:2:3837
+2056:2:3835
+2057:2:3836
+2058:2:3837
+2059:2:3848
+2060:2:3855
+2061:0:4863
+2062:2:3721
+2063:0:4863
+2064:2:3859
+2065:2:3860
+2066:2:3861
+2067:2:3873
+2068:2:3874
+2069:2:3878
+2070:2:3879
+2071:2:3887
+2072:2:3892
+2073:2:3896
+2074:2:3897
+2075:2:3905
+2076:2:3906
+2077:2:3910
+2078:2:3911
+2079:2:3905
+2080:2:3906
+2081:2:3910
+2082:2:3911
+2083:2:3919
+2084:2:3924
+2085:2:3925
+2086:2:3936
+2087:2:3937
+2088:2:3938
+2089:2:3949
+2090:2:3954
+2091:2:3955
+2092:2:3966
+2093:2:3967
+2094:2:3968
+2095:2:3966
+2096:2:3967
+2097:2:3968
+2098:2:3979
+2099:2:3988
+2100:0:4863
+2101:2:3721
+2102:0:4863
+2103:2:3994
+2104:0:4863
+2105:2:4514
+2106:2:4515
+2107:2:4519
+2108:2:4523
+2109:2:4524
+2110:2:4528
+2111:2:4536
+2112:2:4537
+2113:2:4541
+2114:2:4545
+2115:2:4546
+2116:2:4541
+2117:2:4545
+2118:2:4546
+2119:2:4550
+2120:2:4557
+2121:2:4564
+2122:2:4565
+2123:2:4572
+2124:2:4577
+2125:2:4584
+2126:2:4585
+2127:2:4584
+2128:2:4585
+2129:2:4592
+2130:2:4596
+2131:0:4863
+2132:2:3996
+2133:2:4401
+2134:0:4863
+2135:2:3721
+2136:0:4863
+2137:1:632
+2138:1:633
+2139:1:637
+2140:1:638
+2141:1:646
+2142:1:647
+2143:1:651
+2144:1:652
+2145:1:660
+2146:1:665
+2147:1:669
+2148:1:670
+2149:1:678
+2150:1:679
+2151:1:683
+2152:1:684
+2153:1:678
+2154:1:679
+2155:1:683
+2156:1:684
+2157:1:692
+2158:1:697
+2159:1:698
+2160:1:709
+2161:1:710
+2162:1:711
+2163:1:722
+2164:1:727
+2165:1:728
+2166:1:739
+2167:1:740
+2168:1:741
+2169:1:739
+2170:1:747
+2171:1:748
+2172:1:752
+2173:0:4863
+2174:1:11
+2175:0:4863
+2176:2:3859
+2177:2:3860
+2178:2:3864
+2179:2:3865
+2180:2:3873
+2181:2:3874
+2182:2:3878
+2183:2:3879
+2184:2:3887
+2185:2:3892
+2186:2:3896
+2187:2:3897
+2188:2:3905
+2189:2:3906
+2190:2:3910
+2191:2:3911
+2192:2:3905
+2193:2:3906
+2194:2:3910
+2195:2:3911
+2196:2:3919
+2197:2:3924
+2198:2:3925
+2199:2:3936
+2200:2:3937
+2201:2:3938
+2202:2:3949
+2203:2:3954
+2204:2:3955
+2205:2:3966
+2206:2:3967
+2207:2:3968
+2208:2:3966
+2209:2:3967
+2210:2:3968
+2211:2:3979
+2212:2:3988
+2213:0:4863
+2214:2:3721
+2215:0:4863
+2216:2:3994
+2217:0:4863
+2218:2:4514
+2219:2:4515
+2220:2:4519
+2221:2:4523
+2222:2:4524
+2223:2:4528
+2224:2:4536
+2225:2:4537
+2226:2:4541
+2227:2:4545
+2228:2:4546
+2229:2:4541
+2230:2:4545
+2231:2:4546
+2232:2:4550
+2233:2:4557
+2234:2:4564
+2235:2:4565
+2236:2:4572
+2237:2:4577
+2238:2:4584
+2239:2:4585
+2240:2:4584
+2241:2:4585
+2242:2:4592
+2243:2:4596
+2244:0:4863
+2245:2:3996
+2246:2:4401
+2247:0:4863
+2248:1:761
+2249:1:764
+2250:1:765
+2251:0:4863
+2252:2:3721
+2253:0:4863
+2254:1:11
+2255:0:4863
+2256:2:3859
+2257:2:3860
+2258:2:3864
+2259:2:3865
+2260:2:3873
+2261:2:3874
+2262:2:3878
+2263:2:3879
+2264:2:3887
+2265:2:3892
+2266:2:3896
+2267:2:3897
+2268:2:3905
+2269:2:3906
+2270:2:3910
+2271:2:3911
+2272:2:3905
+2273:2:3906
+2274:2:3910
+2275:2:3911
+2276:2:3919
+2277:2:3924
+2278:2:3925
+2279:2:3936
+2280:2:3937
+2281:2:3938
+2282:2:3949
+2283:2:3954
+2284:2:3955
+2285:2:3966
+2286:2:3967
+2287:2:3968
+2288:2:3966
+2289:2:3967
+2290:2:3968
+2291:2:3979
+2292:2:3988
+2293:0:4863
+2294:2:3721
+2295:0:4863
+2296:2:3994
+2297:0:4863
+2298:2:4514
+2299:2:4515
+2300:2:4519
+2301:2:4523
+2302:2:4524
+2303:2:4528
+2304:2:4536
+2305:2:4537
+2306:2:4541
+2307:2:4545
+2308:2:4546
+2309:2:4541
+2310:2:4545
+2311:2:4546
+2312:2:4550
+2313:2:4557
+2314:2:4564
+2315:2:4565
+2316:2:4572
+2317:2:4577
+2318:2:4584
+2319:2:4585
+2320:2:4584
+2321:2:4585
+2322:2:4592
+2323:2:4596
+2324:0:4863
+2325:2:3996
+2326:2:4401
+2327:0:4863
+2328:1:1028
+2329:1:1029
+2330:1:1033
+2331:1:1034
+2332:1:1042
+2333:1:1043
+2334:1:1047
+2335:1:1048
+2336:1:1056
+2337:1:1061
+2338:1:1065
+2339:1:1066
+2340:1:1074
+2341:1:1075
+2342:1:1079
+2343:1:1080
+2344:1:1074
+2345:1:1075
+2346:1:1079
+2347:1:1080
+2348:1:1088
+2349:1:1093
+2350:1:1094
+2351:1:1105
+2352:1:1106
+2353:1:1107
+2354:1:1118
+2355:1:1123
+2356:1:1124
+2357:1:1135
+2358:1:1136
+2359:1:1137
+2360:1:1135
+2361:1:1143
+2362:1:1144
+2363:1:1148
+2364:1:1155
+2365:1:1159
+2366:0:4863
+2367:2:3721
+2368:0:4863
+2369:1:11
+2370:0:4863
+2371:2:3859
+2372:2:3860
+2373:2:3864
+2374:2:3865
+2375:2:3873
+2376:2:3874
+2377:2:3878
+2378:2:3879
+2379:2:3887
+2380:2:3892
+2381:2:3896
+2382:2:3897
+2383:2:3905
+2384:2:3906
+2385:2:3910
+2386:2:3911
+2387:2:3905
+2388:2:3906
+2389:2:3910
+2390:2:3911
+2391:2:3919
+2392:2:3924
+2393:2:3925
+2394:2:3936
+2395:2:3937
+2396:2:3938
+2397:2:3949
+2398:2:3954
+2399:2:3955
+2400:2:3966
+2401:2:3967
+2402:2:3968
+2403:2:3966
+2404:2:3967
+2405:2:3968
+2406:2:3979
+2407:2:3988
+2408:0:4863
+2409:2:3721
+2410:0:4863
+2411:2:3994
+2412:0:4863
+2413:2:4514
+2414:2:4515
+2415:2:4519
+2416:2:4523
+2417:2:4524
+2418:2:4528
+2419:2:4536
+2420:2:4537
+2421:2:4541
+2422:2:4545
+2423:2:4546
+2424:2:4541
+2425:2:4545
+2426:2:4546
+2427:2:4550
+2428:2:4557
+2429:2:4564
+2430:2:4565
+2431:2:4572
+2432:2:4577
+2433:2:4584
+2434:2:4585
+2435:2:4584
+2436:2:4585
+2437:2:4592
+2438:2:4596
+2439:0:4863
+2440:2:3996
+2441:2:4401
+2442:0:4863
+2443:1:1160
+2444:1:1161
+2445:1:1165
+2446:1:1166
+2447:1:1174
+2448:1:1175
+2449:1:1176
+2450:1:1188
+2451:1:1193
+2452:1:1197
+2453:1:1198
+2454:1:1206
+2455:1:1207
+2456:1:1211
+2457:1:1212
+2458:1:1206
+2459:1:1207
+2460:1:1211
+2461:1:1212
+2462:1:1220
+2463:1:1225
+2464:1:1226
+2465:1:1237
+2466:1:1238
+2467:1:1239
+2468:1:1250
+2469:1:1255
+2470:1:1256
+2471:1:1267
+2472:1:1268
+2473:1:1269
+2474:1:1267
+2475:1:1275
+2476:1:1276
+2477:1:1280
+2478:0:4863
+2479:2:3721
+2480:0:4863
+2481:1:11
+2482:0:4863
+2483:2:3859
+2484:2:3860
+2485:2:3864
+2486:2:3865
+2487:2:3873
+2488:2:3874
+2489:2:3878
+2490:2:3879
+2491:2:3887
+2492:2:3892
+2493:2:3896
+2494:2:3897
+2495:2:3905
+2496:2:3906
+2497:2:3910
+2498:2:3911
+2499:2:3905
+2500:2:3906
+2501:2:3910
+2502:2:3911
+2503:2:3919
+2504:2:3924
+2505:2:3925
+2506:2:3936
+2507:2:3937
+2508:2:3938
+2509:2:3949
+2510:2:3954
+2511:2:3955
+2512:2:3966
+2513:2:3967
+2514:2:3968
+2515:2:3966
+2516:2:3967
+2517:2:3968
+2518:2:3979
+2519:2:3988
+2520:0:4863
+2521:2:3721
+2522:0:4863
+2523:2:3994
+2524:0:4863
+2525:2:4514
+2526:2:4515
+2527:2:4519
+2528:2:4523
+2529:2:4524
+2530:2:4528
+2531:2:4536
+2532:2:4537
+2533:2:4541
+2534:2:4545
+2535:2:4546
+2536:2:4541
+2537:2:4545
+2538:2:4546
+2539:2:4550
+2540:2:4557
+2541:2:4564
+2542:2:4565
+2543:2:4572
+2544:2:4577
+2545:2:4584
+2546:2:4585
+2547:2:4584
+2548:2:4585
+2549:2:4592
+2550:2:4596
+2551:0:4863
+2552:2:3996
+2553:2:4401
+2554:0:4863
+2555:2:3721
+2556:0:4863
+2557:1:1289
+2558:1:1290
+2559:1:1294
+2560:1:1295
+2561:1:1303
+2562:1:1304
+2563:1:1308
+2564:1:1309
+2565:1:1317
+2566:1:1322
+2567:1:1326
+2568:1:1327
+2569:1:1335
+2570:1:1336
+2571:1:1340
+2572:1:1341
+2573:1:1335
+2574:1:1336
+2575:1:1340
+2576:1:1341
+2577:1:1349
+2578:1:1354
+2579:1:1355
+2580:1:1366
+2581:1:1367
+2582:1:1368
+2583:1:1379
+2584:1:1384
+2585:1:1385
+2586:1:1396
+2587:1:1397
+2588:1:1398
+2589:1:1396
+2590:1:1404
+2591:1:1405
+2592:1:1409
+2593:0:4861
+2594:1:11
+2595:0:4867
+2596:0:4863
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_free_nested.define b/formal-model/results/urcu-controldataflow-ipi/urcu_free_nested.define
new file mode 100644 (file)
index 0000000..0fb59bd
--- /dev/null
@@ -0,0 +1 @@
+#define READER_NEST_LEVEL 2
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_free_no_mb.define b/formal-model/results/urcu-controldataflow-ipi/urcu_free_no_mb.define
new file mode 100644 (file)
index 0000000..d99d793
--- /dev/null
@@ -0,0 +1 @@
+#define NO_MB
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_free_no_mb.log b/formal-model/results/urcu-controldataflow-ipi/urcu_free_no_mb.log
new file mode 100644 (file)
index 0000000..1446ff9
--- /dev/null
@@ -0,0 +1,874 @@
+rm -f pan* trail.out .input.spin* *.spin.trail .input.define
+touch .input.define
+cat .input.define >> pan.ltl
+cat DEFINES >> pan.ltl
+spin -f "!(`cat urcu_free.ltl | grep -v ^//`)" >> pan.ltl
+cp urcu_free_no_mb.define .input.define
+cat .input.define > .input.spin
+cat DEFINES >> .input.spin
+cat urcu.spin >> .input.spin
+rm -f .input.spin.trail
+spin -a -X -N pan.ltl .input.spin
+Exit-Status 0
+gcc -O2 -w -DHASH64 -o pan pan.c
+./pan -a -v -c1 -X -m10000000 -w20
+warning: for p.o. reduction to be valid the never claim must be stutter-invariant
+(never claims generated from LTL formulae are stutter-invariant)
+depth 0: Claim reached state 5 (line 1258)
+pan: claim violated! (at depth 1420)
+pan: wrote .input.spin.trail
+
+(Spin Version 5.1.7 -- 23 December 2008)
+Warning: Search not completed
+       + Partial Order Reduction
+
+Full statespace search for:
+       never claim             +
+       assertion violations    + (if within scope of claim)
+       acceptance   cycles     + (fairness disabled)
+       invalid end states      - (disabled by never claim)
+
+State-vector 88 byte, depth reached 5697, errors: 1
+   552184 states, stored
+ 73251405 states, matched
+ 73803589 transitions (= stored+matched)
+4.1259494e+08 atomic steps
+hash conflicts:   9982809 (resolved)
+
+Stats on memory usage (in Megabytes):
+   61.086      equivalent memory usage for states (stored*(State-vector + overhead))
+   47.033      actual memory usage for states (compression: 76.99%)
+               state-vector as stored = 61 byte + 28 byte overhead
+    8.000      memory used for hash table (-w20)
+  457.764      memory used for DFS stack (-m10000000)
+  512.736      total actual memory usage
+
+unreached in proctype urcu_reader
+       line 250, "pan.___", state 34, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 56, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 65, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 81, "(1)"
+       line 231, "pan.___", state 89, "(1)"
+       line 235, "pan.___", state 101, "(1)"
+       line 239, "pan.___", state 109, "(1)"
+       line 395, "pan.___", state 135, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 167, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 181, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 200, "(1)"
+       line 421, "pan.___", state 230, "(1)"
+       line 425, "pan.___", state 243, "(1)"
+       line 679, "pan.___", state 264, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<1))"
+       line 395, "pan.___", state 271, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 303, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 317, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 336, "(1)"
+       line 421, "pan.___", state 366, "(1)"
+       line 425, "pan.___", state 379, "(1)"
+       line 395, "pan.___", state 400, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 432, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 446, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 465, "(1)"
+       line 421, "pan.___", state 495, "(1)"
+       line 425, "pan.___", state 508, "(1)"
+       line 395, "pan.___", state 531, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 533, "(1)"
+       line 395, "pan.___", state 534, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 534, "else"
+       line 395, "pan.___", state 537, "(1)"
+       line 399, "pan.___", state 545, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 547, "(1)"
+       line 399, "pan.___", state 548, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 548, "else"
+       line 399, "pan.___", state 551, "(1)"
+       line 399, "pan.___", state 552, "(1)"
+       line 399, "pan.___", state 552, "(1)"
+       line 397, "pan.___", state 557, "((i<1))"
+       line 397, "pan.___", state 557, "((i>=1))"
+       line 404, "pan.___", state 563, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 565, "(1)"
+       line 404, "pan.___", state 566, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 566, "else"
+       line 404, "pan.___", state 569, "(1)"
+       line 404, "pan.___", state 570, "(1)"
+       line 404, "pan.___", state 570, "(1)"
+       line 408, "pan.___", state 577, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 579, "(1)"
+       line 408, "pan.___", state 580, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 580, "else"
+       line 408, "pan.___", state 583, "(1)"
+       line 408, "pan.___", state 584, "(1)"
+       line 408, "pan.___", state 584, "(1)"
+       line 406, "pan.___", state 589, "((i<2))"
+       line 406, "pan.___", state 589, "((i>=2))"
+       line 412, "pan.___", state 596, "(1)"
+       line 412, "pan.___", state 597, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 597, "else"
+       line 412, "pan.___", state 600, "(1)"
+       line 412, "pan.___", state 601, "(1)"
+       line 412, "pan.___", state 601, "(1)"
+       line 416, "pan.___", state 609, "(1)"
+       line 416, "pan.___", state 610, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 610, "else"
+       line 416, "pan.___", state 613, "(1)"
+       line 416, "pan.___", state 614, "(1)"
+       line 416, "pan.___", state 614, "(1)"
+       line 414, "pan.___", state 619, "((i<1))"
+       line 414, "pan.___", state 619, "((i>=1))"
+       line 421, "pan.___", state 626, "(1)"
+       line 421, "pan.___", state 627, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 627, "else"
+       line 421, "pan.___", state 630, "(1)"
+       line 421, "pan.___", state 631, "(1)"
+       line 421, "pan.___", state 631, "(1)"
+       line 425, "pan.___", state 639, "(1)"
+       line 425, "pan.___", state 640, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 640, "else"
+       line 425, "pan.___", state 643, "(1)"
+       line 425, "pan.___", state 644, "(1)"
+       line 425, "pan.___", state 644, "(1)"
+       line 423, "pan.___", state 649, "((i<2))"
+       line 423, "pan.___", state 649, "((i>=2))"
+       line 430, "pan.___", state 653, "(1)"
+       line 430, "pan.___", state 653, "(1)"
+       line 679, "pan.___", state 656, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 679, "pan.___", state 657, "_proc_urcu_reader = (_proc_urcu_reader|(1<<5))"
+       line 679, "pan.___", state 658, "(1)"
+       line 395, "pan.___", state 665, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 697, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 711, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 730, "(1)"
+       line 421, "pan.___", state 760, "(1)"
+       line 425, "pan.___", state 773, "(1)"
+       line 395, "pan.___", state 801, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 803, "(1)"
+       line 395, "pan.___", state 804, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 804, "else"
+       line 395, "pan.___", state 807, "(1)"
+       line 399, "pan.___", state 815, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 817, "(1)"
+       line 399, "pan.___", state 818, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 818, "else"
+       line 399, "pan.___", state 821, "(1)"
+       line 399, "pan.___", state 822, "(1)"
+       line 399, "pan.___", state 822, "(1)"
+       line 397, "pan.___", state 827, "((i<1))"
+       line 397, "pan.___", state 827, "((i>=1))"
+       line 404, "pan.___", state 833, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 835, "(1)"
+       line 404, "pan.___", state 836, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 836, "else"
+       line 404, "pan.___", state 839, "(1)"
+       line 404, "pan.___", state 840, "(1)"
+       line 404, "pan.___", state 840, "(1)"
+       line 408, "pan.___", state 847, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 849, "(1)"
+       line 408, "pan.___", state 850, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 850, "else"
+       line 408, "pan.___", state 853, "(1)"
+       line 408, "pan.___", state 854, "(1)"
+       line 408, "pan.___", state 854, "(1)"
+       line 406, "pan.___", state 859, "((i<2))"
+       line 406, "pan.___", state 859, "((i>=2))"
+       line 412, "pan.___", state 866, "(1)"
+       line 412, "pan.___", state 867, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 867, "else"
+       line 412, "pan.___", state 870, "(1)"
+       line 412, "pan.___", state 871, "(1)"
+       line 412, "pan.___", state 871, "(1)"
+       line 416, "pan.___", state 879, "(1)"
+       line 416, "pan.___", state 880, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 880, "else"
+       line 416, "pan.___", state 883, "(1)"
+       line 416, "pan.___", state 884, "(1)"
+       line 416, "pan.___", state 884, "(1)"
+       line 414, "pan.___", state 889, "((i<1))"
+       line 414, "pan.___", state 889, "((i>=1))"
+       line 421, "pan.___", state 896, "(1)"
+       line 421, "pan.___", state 897, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 897, "else"
+       line 421, "pan.___", state 900, "(1)"
+       line 421, "pan.___", state 901, "(1)"
+       line 421, "pan.___", state 901, "(1)"
+       line 425, "pan.___", state 909, "(1)"
+       line 425, "pan.___", state 910, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 910, "else"
+       line 425, "pan.___", state 913, "(1)"
+       line 425, "pan.___", state 914, "(1)"
+       line 425, "pan.___", state 914, "(1)"
+       line 430, "pan.___", state 923, "(1)"
+       line 430, "pan.___", state 923, "(1)"
+       line 395, "pan.___", state 930, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 932, "(1)"
+       line 395, "pan.___", state 933, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 933, "else"
+       line 395, "pan.___", state 936, "(1)"
+       line 399, "pan.___", state 944, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 946, "(1)"
+       line 399, "pan.___", state 947, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 947, "else"
+       line 399, "pan.___", state 950, "(1)"
+       line 399, "pan.___", state 951, "(1)"
+       line 399, "pan.___", state 951, "(1)"
+       line 397, "pan.___", state 956, "((i<1))"
+       line 397, "pan.___", state 956, "((i>=1))"
+       line 404, "pan.___", state 962, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 964, "(1)"
+       line 404, "pan.___", state 965, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 965, "else"
+       line 404, "pan.___", state 968, "(1)"
+       line 404, "pan.___", state 969, "(1)"
+       line 404, "pan.___", state 969, "(1)"
+       line 408, "pan.___", state 976, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 978, "(1)"
+       line 408, "pan.___", state 979, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 979, "else"
+       line 408, "pan.___", state 982, "(1)"
+       line 408, "pan.___", state 983, "(1)"
+       line 408, "pan.___", state 983, "(1)"
+       line 406, "pan.___", state 988, "((i<2))"
+       line 406, "pan.___", state 988, "((i>=2))"
+       line 412, "pan.___", state 995, "(1)"
+       line 412, "pan.___", state 996, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 996, "else"
+       line 412, "pan.___", state 999, "(1)"
+       line 412, "pan.___", state 1000, "(1)"
+       line 412, "pan.___", state 1000, "(1)"
+       line 416, "pan.___", state 1008, "(1)"
+       line 416, "pan.___", state 1009, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 1009, "else"
+       line 416, "pan.___", state 1012, "(1)"
+       line 416, "pan.___", state 1013, "(1)"
+       line 416, "pan.___", state 1013, "(1)"
+       line 414, "pan.___", state 1018, "((i<1))"
+       line 414, "pan.___", state 1018, "((i>=1))"
+       line 421, "pan.___", state 1025, "(1)"
+       line 421, "pan.___", state 1026, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 1026, "else"
+       line 421, "pan.___", state 1029, "(1)"
+       line 421, "pan.___", state 1030, "(1)"
+       line 421, "pan.___", state 1030, "(1)"
+       line 425, "pan.___", state 1038, "(1)"
+       line 425, "pan.___", state 1039, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 1039, "else"
+       line 425, "pan.___", state 1042, "(1)"
+       line 425, "pan.___", state 1043, "(1)"
+       line 425, "pan.___", state 1043, "(1)"
+       line 423, "pan.___", state 1048, "((i<2))"
+       line 423, "pan.___", state 1048, "((i>=2))"
+       line 430, "pan.___", state 1052, "(1)"
+       line 430, "pan.___", state 1052, "(1)"
+       line 687, "pan.___", state 1056, "_proc_urcu_reader = (_proc_urcu_reader|(1<<11))"
+       line 395, "pan.___", state 1061, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1093, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1107, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1126, "(1)"
+       line 421, "pan.___", state 1156, "(1)"
+       line 425, "pan.___", state 1169, "(1)"
+       line 395, "pan.___", state 1193, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1225, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1239, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1258, "(1)"
+       line 421, "pan.___", state 1288, "(1)"
+       line 425, "pan.___", state 1301, "(1)"
+       line 395, "pan.___", state 1326, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1358, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1372, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1391, "(1)"
+       line 421, "pan.___", state 1421, "(1)"
+       line 425, "pan.___", state 1434, "(1)"
+       line 395, "pan.___", state 1455, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1487, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1501, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1520, "(1)"
+       line 421, "pan.___", state 1550, "(1)"
+       line 425, "pan.___", state 1563, "(1)"
+       line 395, "pan.___", state 1589, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1621, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1635, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1654, "(1)"
+       line 421, "pan.___", state 1684, "(1)"
+       line 425, "pan.___", state 1697, "(1)"
+       line 395, "pan.___", state 1718, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1750, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1764, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1783, "(1)"
+       line 421, "pan.___", state 1813, "(1)"
+       line 425, "pan.___", state 1826, "(1)"
+       line 395, "pan.___", state 1850, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1882, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1896, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1915, "(1)"
+       line 421, "pan.___", state 1945, "(1)"
+       line 425, "pan.___", state 1958, "(1)"
+       line 726, "pan.___", state 1979, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<19))"
+       line 395, "pan.___", state 1986, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2018, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2032, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2051, "(1)"
+       line 421, "pan.___", state 2081, "(1)"
+       line 425, "pan.___", state 2094, "(1)"
+       line 395, "pan.___", state 2115, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2147, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2161, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2180, "(1)"
+       line 421, "pan.___", state 2210, "(1)"
+       line 425, "pan.___", state 2223, "(1)"
+       line 395, "pan.___", state 2246, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 2248, "(1)"
+       line 395, "pan.___", state 2249, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 2249, "else"
+       line 395, "pan.___", state 2252, "(1)"
+       line 399, "pan.___", state 2260, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 2262, "(1)"
+       line 399, "pan.___", state 2263, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 2263, "else"
+       line 399, "pan.___", state 2266, "(1)"
+       line 399, "pan.___", state 2267, "(1)"
+       line 399, "pan.___", state 2267, "(1)"
+       line 397, "pan.___", state 2272, "((i<1))"
+       line 397, "pan.___", state 2272, "((i>=1))"
+       line 404, "pan.___", state 2278, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2280, "(1)"
+       line 404, "pan.___", state 2281, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 2281, "else"
+       line 404, "pan.___", state 2284, "(1)"
+       line 404, "pan.___", state 2285, "(1)"
+       line 404, "pan.___", state 2285, "(1)"
+       line 408, "pan.___", state 2292, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2294, "(1)"
+       line 408, "pan.___", state 2295, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 2295, "else"
+       line 408, "pan.___", state 2298, "(1)"
+       line 408, "pan.___", state 2299, "(1)"
+       line 408, "pan.___", state 2299, "(1)"
+       line 406, "pan.___", state 2304, "((i<2))"
+       line 406, "pan.___", state 2304, "((i>=2))"
+       line 412, "pan.___", state 2311, "(1)"
+       line 412, "pan.___", state 2312, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 2312, "else"
+       line 412, "pan.___", state 2315, "(1)"
+       line 412, "pan.___", state 2316, "(1)"
+       line 412, "pan.___", state 2316, "(1)"
+       line 416, "pan.___", state 2324, "(1)"
+       line 416, "pan.___", state 2325, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 2325, "else"
+       line 416, "pan.___", state 2328, "(1)"
+       line 416, "pan.___", state 2329, "(1)"
+       line 416, "pan.___", state 2329, "(1)"
+       line 414, "pan.___", state 2334, "((i<1))"
+       line 414, "pan.___", state 2334, "((i>=1))"
+       line 421, "pan.___", state 2341, "(1)"
+       line 421, "pan.___", state 2342, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 2342, "else"
+       line 421, "pan.___", state 2345, "(1)"
+       line 421, "pan.___", state 2346, "(1)"
+       line 421, "pan.___", state 2346, "(1)"
+       line 425, "pan.___", state 2354, "(1)"
+       line 425, "pan.___", state 2355, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 2355, "else"
+       line 425, "pan.___", state 2358, "(1)"
+       line 425, "pan.___", state 2359, "(1)"
+       line 425, "pan.___", state 2359, "(1)"
+       line 423, "pan.___", state 2364, "((i<2))"
+       line 423, "pan.___", state 2364, "((i>=2))"
+       line 430, "pan.___", state 2368, "(1)"
+       line 430, "pan.___", state 2368, "(1)"
+       line 726, "pan.___", state 2371, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 726, "pan.___", state 2372, "_proc_urcu_reader = (_proc_urcu_reader|(1<<23))"
+       line 726, "pan.___", state 2373, "(1)"
+       line 395, "pan.___", state 2380, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2412, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2426, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2445, "(1)"
+       line 421, "pan.___", state 2475, "(1)"
+       line 425, "pan.___", state 2488, "(1)"
+       line 395, "pan.___", state 2515, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2547, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2561, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2580, "(1)"
+       line 421, "pan.___", state 2610, "(1)"
+       line 425, "pan.___", state 2623, "(1)"
+       line 395, "pan.___", state 2644, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2676, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2690, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2709, "(1)"
+       line 421, "pan.___", state 2739, "(1)"
+       line 425, "pan.___", state 2752, "(1)"
+       line 227, "pan.___", state 2785, "(1)"
+       line 235, "pan.___", state 2805, "(1)"
+       line 239, "pan.___", state 2813, "(1)"
+       line 227, "pan.___", state 2828, "(1)"
+       line 235, "pan.___", state 2848, "(1)"
+       line 239, "pan.___", state 2856, "(1)"
+       line 877, "pan.___", state 2873, "-end-"
+       (278 of 2873 states)
+unreached in proctype urcu_writer
+       line 395, "pan.___", state 20, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 26, "(1)"
+       line 399, "pan.___", state 34, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 40, "(1)"
+       line 399, "pan.___", state 41, "(1)"
+       line 399, "pan.___", state 41, "(1)"
+       line 397, "pan.___", state 46, "((i<1))"
+       line 397, "pan.___", state 46, "((i>=1))"
+       line 404, "pan.___", state 52, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 58, "(1)"
+       line 404, "pan.___", state 59, "(1)"
+       line 404, "pan.___", state 59, "(1)"
+       line 408, "pan.___", state 72, "(1)"
+       line 408, "pan.___", state 73, "(1)"
+       line 408, "pan.___", state 73, "(1)"
+       line 406, "pan.___", state 78, "((i<2))"
+       line 406, "pan.___", state 78, "((i>=2))"
+       line 412, "pan.___", state 85, "(1)"
+       line 412, "pan.___", state 86, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 86, "else"
+       line 412, "pan.___", state 89, "(1)"
+       line 412, "pan.___", state 90, "(1)"
+       line 412, "pan.___", state 90, "(1)"
+       line 416, "pan.___", state 98, "(1)"
+       line 416, "pan.___", state 99, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 99, "else"
+       line 416, "pan.___", state 102, "(1)"
+       line 416, "pan.___", state 103, "(1)"
+       line 416, "pan.___", state 103, "(1)"
+       line 414, "pan.___", state 108, "((i<1))"
+       line 414, "pan.___", state 108, "((i>=1))"
+       line 421, "pan.___", state 115, "(1)"
+       line 421, "pan.___", state 116, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 116, "else"
+       line 421, "pan.___", state 119, "(1)"
+       line 421, "pan.___", state 120, "(1)"
+       line 421, "pan.___", state 120, "(1)"
+       line 425, "pan.___", state 128, "(1)"
+       line 425, "pan.___", state 129, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 129, "else"
+       line 425, "pan.___", state 132, "(1)"
+       line 425, "pan.___", state 133, "(1)"
+       line 425, "pan.___", state 133, "(1)"
+       line 423, "pan.___", state 138, "((i<2))"
+       line 423, "pan.___", state 138, "((i>=2))"
+       line 430, "pan.___", state 142, "(1)"
+       line 430, "pan.___", state 142, "(1)"
+       line 250, "pan.___", state 151, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 160, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 252, "pan.___", state 168, "((i<1))"
+       line 252, "pan.___", state 168, "((i>=1))"
+       line 258, "pan.___", state 173, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 1000, "pan.___", state 201, "old_data = cached_rcu_ptr.val[_pid]"
+       line 1011, "pan.___", state 205, "_proc_urcu_writer = (_proc_urcu_writer|(1<<4))"
+       line 395, "pan.___", state 213, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 219, "(1)"
+       line 399, "pan.___", state 227, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 233, "(1)"
+       line 399, "pan.___", state 234, "(1)"
+       line 399, "pan.___", state 234, "(1)"
+       line 397, "pan.___", state 239, "((i<1))"
+       line 397, "pan.___", state 239, "((i>=1))"
+       line 404, "pan.___", state 247, "(1)"
+       line 404, "pan.___", state 248, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 248, "else"
+       line 404, "pan.___", state 251, "(1)"
+       line 404, "pan.___", state 252, "(1)"
+       line 404, "pan.___", state 252, "(1)"
+       line 408, "pan.___", state 259, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 265, "(1)"
+       line 408, "pan.___", state 266, "(1)"
+       line 408, "pan.___", state 266, "(1)"
+       line 406, "pan.___", state 271, "((i<2))"
+       line 406, "pan.___", state 271, "((i>=2))"
+       line 412, "pan.___", state 278, "(1)"
+       line 412, "pan.___", state 279, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 279, "else"
+       line 412, "pan.___", state 282, "(1)"
+       line 412, "pan.___", state 283, "(1)"
+       line 412, "pan.___", state 283, "(1)"
+       line 416, "pan.___", state 291, "(1)"
+       line 416, "pan.___", state 292, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 292, "else"
+       line 416, "pan.___", state 295, "(1)"
+       line 416, "pan.___", state 296, "(1)"
+       line 416, "pan.___", state 296, "(1)"
+       line 414, "pan.___", state 301, "((i<1))"
+       line 414, "pan.___", state 301, "((i>=1))"
+       line 421, "pan.___", state 308, "(1)"
+       line 421, "pan.___", state 309, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 309, "else"
+       line 421, "pan.___", state 312, "(1)"
+       line 421, "pan.___", state 313, "(1)"
+       line 421, "pan.___", state 313, "(1)"
+       line 425, "pan.___", state 321, "(1)"
+       line 425, "pan.___", state 322, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 322, "else"
+       line 425, "pan.___", state 325, "(1)"
+       line 425, "pan.___", state 326, "(1)"
+       line 425, "pan.___", state 326, "(1)"
+       line 423, "pan.___", state 331, "((i<2))"
+       line 423, "pan.___", state 331, "((i>=2))"
+       line 430, "pan.___", state 335, "(1)"
+       line 430, "pan.___", state 335, "(1)"
+       line 395, "pan.___", state 346, "(1)"
+       line 395, "pan.___", state 347, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 347, "else"
+       line 395, "pan.___", state 350, "(1)"
+       line 399, "pan.___", state 358, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 364, "(1)"
+       line 399, "pan.___", state 365, "(1)"
+       line 399, "pan.___", state 365, "(1)"
+       line 397, "pan.___", state 370, "((i<1))"
+       line 397, "pan.___", state 370, "((i>=1))"
+       line 404, "pan.___", state 376, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 382, "(1)"
+       line 404, "pan.___", state 383, "(1)"
+       line 404, "pan.___", state 383, "(1)"
+       line 408, "pan.___", state 390, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 396, "(1)"
+       line 408, "pan.___", state 397, "(1)"
+       line 408, "pan.___", state 397, "(1)"
+       line 406, "pan.___", state 402, "((i<2))"
+       line 406, "pan.___", state 402, "((i>=2))"
+       line 412, "pan.___", state 409, "(1)"
+       line 412, "pan.___", state 410, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 410, "else"
+       line 412, "pan.___", state 413, "(1)"
+       line 412, "pan.___", state 414, "(1)"
+       line 412, "pan.___", state 414, "(1)"
+       line 416, "pan.___", state 422, "(1)"
+       line 416, "pan.___", state 423, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 423, "else"
+       line 416, "pan.___", state 426, "(1)"
+       line 416, "pan.___", state 427, "(1)"
+       line 416, "pan.___", state 427, "(1)"
+       line 414, "pan.___", state 432, "((i<1))"
+       line 414, "pan.___", state 432, "((i>=1))"
+       line 421, "pan.___", state 439, "(1)"
+       line 421, "pan.___", state 440, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 440, "else"
+       line 421, "pan.___", state 443, "(1)"
+       line 421, "pan.___", state 444, "(1)"
+       line 421, "pan.___", state 444, "(1)"
+       line 425, "pan.___", state 452, "(1)"
+       line 425, "pan.___", state 453, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 453, "else"
+       line 425, "pan.___", state 456, "(1)"
+       line 425, "pan.___", state 457, "(1)"
+       line 425, "pan.___", state 457, "(1)"
+       line 423, "pan.___", state 462, "((i<2))"
+       line 423, "pan.___", state 462, "((i>=2))"
+       line 430, "pan.___", state 466, "(1)"
+       line 430, "pan.___", state 466, "(1)"
+       line 1063, "pan.___", state 477, "_proc_urcu_writer = (_proc_urcu_writer&~(((1<<8)|(1<<7))))"
+       line 395, "pan.___", state 482, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 488, "(1)"
+       line 399, "pan.___", state 496, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 502, "(1)"
+       line 399, "pan.___", state 503, "(1)"
+       line 399, "pan.___", state 503, "(1)"
+       line 397, "pan.___", state 508, "((i<1))"
+       line 397, "pan.___", state 508, "((i>=1))"
+       line 404, "pan.___", state 514, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 520, "(1)"
+       line 404, "pan.___", state 521, "(1)"
+       line 404, "pan.___", state 521, "(1)"
+       line 408, "pan.___", state 528, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 534, "(1)"
+       line 408, "pan.___", state 535, "(1)"
+       line 408, "pan.___", state 535, "(1)"
+       line 406, "pan.___", state 540, "((i<2))"
+       line 406, "pan.___", state 540, "((i>=2))"
+       line 412, "pan.___", state 547, "(1)"
+       line 412, "pan.___", state 548, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 548, "else"
+       line 412, "pan.___", state 551, "(1)"
+       line 412, "pan.___", state 552, "(1)"
+       line 412, "pan.___", state 552, "(1)"
+       line 416, "pan.___", state 560, "(1)"
+       line 416, "pan.___", state 561, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 561, "else"
+       line 416, "pan.___", state 564, "(1)"
+       line 416, "pan.___", state 565, "(1)"
+       line 416, "pan.___", state 565, "(1)"
+       line 414, "pan.___", state 570, "((i<1))"
+       line 414, "pan.___", state 570, "((i>=1))"
+       line 421, "pan.___", state 577, "(1)"
+       line 421, "pan.___", state 578, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 578, "else"
+       line 421, "pan.___", state 581, "(1)"
+       line 421, "pan.___", state 582, "(1)"
+       line 421, "pan.___", state 582, "(1)"
+       line 425, "pan.___", state 590, "(1)"
+       line 425, "pan.___", state 591, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 591, "else"
+       line 425, "pan.___", state 594, "(1)"
+       line 425, "pan.___", state 595, "(1)"
+       line 425, "pan.___", state 595, "(1)"
+       line 430, "pan.___", state 604, "(1)"
+       line 430, "pan.___", state 604, "(1)"
+       line 395, "pan.___", state 611, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 625, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 643, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 676, "(1)"
+       line 416, "pan.___", state 689, "(1)"
+       line 421, "pan.___", state 706, "(1)"
+       line 425, "pan.___", state 719, "(1)"
+       line 399, "pan.___", state 756, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 774, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 788, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 820, "(1)"
+       line 421, "pan.___", state 837, "(1)"
+       line 425, "pan.___", state 850, "(1)"
+       line 1135, "pan.___", state 877, "_proc_urcu_writer = (_proc_urcu_writer|(1<<13))"
+       line 250, "pan.___", state 905, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 250, "pan.___", state 907, "(1)"
+       line 254, "pan.___", state 914, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 916, "(1)"
+       line 254, "pan.___", state 917, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 254, "pan.___", state 917, "else"
+       line 252, "pan.___", state 922, "((i<1))"
+       line 252, "pan.___", state 922, "((i>=1))"
+       line 258, "pan.___", state 927, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 929, "(1)"
+       line 258, "pan.___", state 930, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 930, "else"
+       line 262, "pan.___", state 936, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 938, "(1)"
+       line 262, "pan.___", state 939, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 262, "pan.___", state 939, "else"
+       line 260, "pan.___", state 944, "((i<2))"
+       line 260, "pan.___", state 944, "((i>=2))"
+       line 227, "pan.___", state 952, "(1)"
+       line 231, "pan.___", state 960, "(1)"
+       line 231, "pan.___", state 961, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 961, "else"
+       line 229, "pan.___", state 966, "((i<1))"
+       line 229, "pan.___", state 966, "((i>=1))"
+       line 235, "pan.___", state 972, "(1)"
+       line 235, "pan.___", state 973, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 973, "else"
+       line 239, "pan.___", state 980, "(1)"
+       line 239, "pan.___", state 981, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 981, "else"
+       line 244, "pan.___", state 990, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 990, "else"
+       line 1189, "pan.___", state 1006, "((i<1))"
+       line 1189, "pan.___", state 1006, "((i>=1))"
+       line 250, "pan.___", state 1011, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 250, "pan.___", state 1013, "(1)"
+       line 254, "pan.___", state 1020, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1022, "(1)"
+       line 254, "pan.___", state 1023, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 254, "pan.___", state 1023, "else"
+       line 252, "pan.___", state 1028, "((i<1))"
+       line 252, "pan.___", state 1028, "((i>=1))"
+       line 258, "pan.___", state 1033, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1035, "(1)"
+       line 258, "pan.___", state 1036, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 1036, "else"
+       line 262, "pan.___", state 1042, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1044, "(1)"
+       line 262, "pan.___", state 1045, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 262, "pan.___", state 1045, "else"
+       line 260, "pan.___", state 1050, "((i<2))"
+       line 260, "pan.___", state 1050, "((i>=2))"
+       line 227, "pan.___", state 1058, "(1)"
+       line 231, "pan.___", state 1066, "(1)"
+       line 231, "pan.___", state 1067, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 1067, "else"
+       line 229, "pan.___", state 1072, "((i<1))"
+       line 229, "pan.___", state 1072, "((i>=1))"
+       line 235, "pan.___", state 1078, "(1)"
+       line 235, "pan.___", state 1079, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 1079, "else"
+       line 239, "pan.___", state 1086, "(1)"
+       line 239, "pan.___", state 1087, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 1087, "else"
+       line 244, "pan.___", state 1096, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 1096, "else"
+       line 277, "pan.___", state 1098, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 277, "pan.___", state 1098, "else"
+       line 1189, "pan.___", state 1099, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 1189, "pan.___", state 1099, "else"
+       line 250, "pan.___", state 1103, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 250, "pan.___", state 1105, "(1)"
+       line 254, "pan.___", state 1112, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1114, "(1)"
+       line 254, "pan.___", state 1115, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 254, "pan.___", state 1115, "else"
+       line 252, "pan.___", state 1120, "((i<1))"
+       line 252, "pan.___", state 1120, "((i>=1))"
+       line 258, "pan.___", state 1125, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1127, "(1)"
+       line 258, "pan.___", state 1128, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 1128, "else"
+       line 262, "pan.___", state 1134, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1136, "(1)"
+       line 262, "pan.___", state 1137, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 262, "pan.___", state 1137, "else"
+       line 260, "pan.___", state 1142, "((i<2))"
+       line 260, "pan.___", state 1142, "((i>=2))"
+       line 227, "pan.___", state 1150, "(1)"
+       line 231, "pan.___", state 1158, "(1)"
+       line 231, "pan.___", state 1159, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 1159, "else"
+       line 229, "pan.___", state 1164, "((i<1))"
+       line 229, "pan.___", state 1164, "((i>=1))"
+       line 235, "pan.___", state 1170, "(1)"
+       line 235, "pan.___", state 1171, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 1171, "else"
+       line 239, "pan.___", state 1178, "(1)"
+       line 239, "pan.___", state 1179, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 1179, "else"
+       line 244, "pan.___", state 1188, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 1188, "else"
+       line 1193, "pan.___", state 1191, "i = 0"
+       line 1193, "pan.___", state 1193, "reader_barrier = 1"
+       line 1193, "pan.___", state 1204, "((i<1))"
+       line 1193, "pan.___", state 1204, "((i>=1))"
+       line 250, "pan.___", state 1209, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 250, "pan.___", state 1211, "(1)"
+       line 254, "pan.___", state 1218, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1220, "(1)"
+       line 254, "pan.___", state 1221, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 254, "pan.___", state 1221, "else"
+       line 252, "pan.___", state 1226, "((i<1))"
+       line 252, "pan.___", state 1226, "((i>=1))"
+       line 258, "pan.___", state 1231, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1233, "(1)"
+       line 258, "pan.___", state 1234, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 1234, "else"
+       line 262, "pan.___", state 1240, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1242, "(1)"
+       line 262, "pan.___", state 1243, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 262, "pan.___", state 1243, "else"
+       line 260, "pan.___", state 1248, "((i<2))"
+       line 260, "pan.___", state 1248, "((i>=2))"
+       line 227, "pan.___", state 1256, "(1)"
+       line 231, "pan.___", state 1264, "(1)"
+       line 231, "pan.___", state 1265, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 1265, "else"
+       line 229, "pan.___", state 1270, "((i<1))"
+       line 229, "pan.___", state 1270, "((i>=1))"
+       line 235, "pan.___", state 1276, "(1)"
+       line 235, "pan.___", state 1277, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 1277, "else"
+       line 239, "pan.___", state 1284, "(1)"
+       line 239, "pan.___", state 1285, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 1285, "else"
+       line 244, "pan.___", state 1294, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 1294, "else"
+       line 277, "pan.___", state 1296, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 277, "pan.___", state 1296, "else"
+       line 1193, "pan.___", state 1297, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 1193, "pan.___", state 1297, "else"
+       line 254, "pan.___", state 1310, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1323, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1332, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1348, "(1)"
+       line 231, "pan.___", state 1356, "(1)"
+       line 235, "pan.___", state 1368, "(1)"
+       line 239, "pan.___", state 1376, "(1)"
+       line 250, "pan.___", state 1407, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1416, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1429, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1438, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1454, "(1)"
+       line 231, "pan.___", state 1462, "(1)"
+       line 235, "pan.___", state 1474, "(1)"
+       line 239, "pan.___", state 1482, "(1)"
+       line 250, "pan.___", state 1499, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 250, "pan.___", state 1501, "(1)"
+       line 254, "pan.___", state 1508, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1510, "(1)"
+       line 254, "pan.___", state 1511, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 254, "pan.___", state 1511, "else"
+       line 252, "pan.___", state 1516, "((i<1))"
+       line 252, "pan.___", state 1516, "((i>=1))"
+       line 258, "pan.___", state 1521, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1523, "(1)"
+       line 258, "pan.___", state 1524, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 1524, "else"
+       line 262, "pan.___", state 1530, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1532, "(1)"
+       line 262, "pan.___", state 1533, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 262, "pan.___", state 1533, "else"
+       line 260, "pan.___", state 1538, "((i<2))"
+       line 260, "pan.___", state 1538, "((i>=2))"
+       line 227, "pan.___", state 1546, "(1)"
+       line 231, "pan.___", state 1554, "(1)"
+       line 231, "pan.___", state 1555, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 1555, "else"
+       line 229, "pan.___", state 1560, "((i<1))"
+       line 229, "pan.___", state 1560, "((i>=1))"
+       line 235, "pan.___", state 1566, "(1)"
+       line 235, "pan.___", state 1567, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 1567, "else"
+       line 239, "pan.___", state 1574, "(1)"
+       line 239, "pan.___", state 1575, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 1575, "else"
+       line 244, "pan.___", state 1584, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 1584, "else"
+       line 1200, "pan.___", state 1587, "i = 0"
+       line 1200, "pan.___", state 1589, "reader_barrier = 1"
+       line 1200, "pan.___", state 1600, "((i<1))"
+       line 1200, "pan.___", state 1600, "((i>=1))"
+       line 250, "pan.___", state 1605, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 250, "pan.___", state 1607, "(1)"
+       line 254, "pan.___", state 1614, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1616, "(1)"
+       line 254, "pan.___", state 1617, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 254, "pan.___", state 1617, "else"
+       line 252, "pan.___", state 1622, "((i<1))"
+       line 252, "pan.___", state 1622, "((i>=1))"
+       line 258, "pan.___", state 1627, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1629, "(1)"
+       line 258, "pan.___", state 1630, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 1630, "else"
+       line 262, "pan.___", state 1636, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1638, "(1)"
+       line 262, "pan.___", state 1639, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 262, "pan.___", state 1639, "else"
+       line 260, "pan.___", state 1644, "((i<2))"
+       line 260, "pan.___", state 1644, "((i>=2))"
+       line 227, "pan.___", state 1652, "(1)"
+       line 231, "pan.___", state 1660, "(1)"
+       line 231, "pan.___", state 1661, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 1661, "else"
+       line 229, "pan.___", state 1666, "((i<1))"
+       line 229, "pan.___", state 1666, "((i>=1))"
+       line 235, "pan.___", state 1672, "(1)"
+       line 235, "pan.___", state 1673, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 1673, "else"
+       line 239, "pan.___", state 1680, "(1)"
+       line 239, "pan.___", state 1681, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 1681, "else"
+       line 244, "pan.___", state 1690, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 1690, "else"
+       line 277, "pan.___", state 1692, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 277, "pan.___", state 1692, "else"
+       line 1200, "pan.___", state 1693, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 1200, "pan.___", state 1693, "else"
+       line 1204, "pan.___", state 1696, "-end-"
+       (310 of 1696 states)
+unreached in proctype :init:
+       line 1215, "pan.___", state 9, "((j<2))"
+       line 1215, "pan.___", state 9, "((j>=2))"
+       line 1216, "pan.___", state 20, "((j<2))"
+       line 1216, "pan.___", state 20, "((j>=2))"
+       line 1221, "pan.___", state 33, "((j<2))"
+       line 1221, "pan.___", state 33, "((j>=2))"
+       line 1219, "pan.___", state 43, "((i<1))"
+       line 1219, "pan.___", state 43, "((i>=1))"
+       line 1229, "pan.___", state 54, "((j<2))"
+       line 1229, "pan.___", state 54, "((j>=2))"
+       line 1233, "pan.___", state 67, "((j<2))"
+       line 1233, "pan.___", state 67, "((j>=2))"
+       (6 of 78 states)
+unreached in proctype :never:
+       line 1263, "pan.___", state 8, "-end-"
+       (1 of 8 states)
+
+pan: elapsed time 92.4 seconds
+pan: rate 5975.3706 states/second
+pan: avg transition delay 1.2521e-06 usec
+cp .input.spin urcu_free_no_mb.spin.input
+cp .input.spin.trail urcu_free_no_mb.spin.input.trail
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_free_no_mb.spin.input b/formal-model/results/urcu-controldataflow-ipi/urcu_free_no_mb.spin.input
new file mode 100644 (file)
index 0000000..a930be8
--- /dev/null
@@ -0,0 +1,1240 @@
+#define NO_MB
+
+// Poison value for freed memory
+#define POISON 1
+// Memory with correct data
+#define WINE 0
+#define SLAB_SIZE 2
+
+#define read_poison    (data_read_first[0] == POISON || data_read_second[0] == POISON)
+
+#define RCU_GP_CTR_BIT (1 << 7)
+#define RCU_GP_CTR_NEST_MASK (RCU_GP_CTR_BIT - 1)
+
+//disabled
+#define REMOTE_BARRIERS
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+typedef per_proc_bit {
+       bit val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bitfield {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bitfield cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               /*
+                * 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, j);
+               reader_barrier[get_readerid()] = 0;
+       :: 1 ->
+               /*
+                * 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)
+//#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);                                                           \
+       i = 0;                                                                  \
+       do                                                                      \
+       :: i < NR_READERS ->                                                    \
+               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.                                            \
+                */                                                             \
+               do                                                              \
+               :: (reader_barrier[i] == 1) ->                                  \
+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(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, smp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only one reader */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* RCU data */
+DECLARE_CACHED_VAR(bit, rcu_data[SLAB_SIZE]);
+
+/* RCU pointer */
+#if (SLAB_SIZE == 2)
+DECLARE_CACHED_VAR(bit, rcu_ptr);
+bit ptr_read_first[NR_READERS];
+bit ptr_read_second[NR_READERS];
+#else
+DECLARE_CACHED_VAR(byte, rcu_ptr);
+byte ptr_read_first[NR_READERS];
+byte ptr_read_second[NR_READERS];
+#endif
+
+bit data_read_first[NR_READERS];
+bit data_read_second[NR_READERS];
+
+bit init_done = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               ptr_read_first[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb1;
+rmb1_end:
+                               data_read_first[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_first[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               ptr_read_second[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb2;
+rmb2_end:
+                               data_read_second[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_second[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+rmb1:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb1_end;
+rmb2:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_DATA                     (1 << 1)
+#define WRITE_PROC_WMB                 (1 << 2)
+#define WRITE_XCHG_PTR                 (1 << 3)
+
+#define WRITE_PROC_FIRST_MB            (1 << 4)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 5)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 6)
+#define WRITE_PROC_FIRST_WAIT          (1 << 7)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 8)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 9)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 10)
+#define WRITE_PROC_SECOND_WAIT         (1 << 11)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 12)
+
+#define WRITE_PROC_SECOND_MB           (1 << 13)
+
+#define WRITE_FREE                     (1 << 14)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_DATA                    \
+                                       | WRITE_PROC_WMB                \
+                                       | WRITE_XCHG_PTR                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB          \
+                                       | WRITE_FREE)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 15) - 1)
+
+/*
+ * Mutexes are implied around writer execution. A single writer at a time.
+ */
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte cur_data = 0, old_data, loop_nr = 0;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (loop_nr < 3) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               loop_nr = loop_nr + 1;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_WMB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+#endif
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_DATA) ->
+                       ooo_mem(i);
+                       cur_data = (cur_data + 1) % SLAB_SIZE;
+                       WRITE_CACHED_VAR(rcu_data[cur_data], WINE);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_DATA);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA,
+                                 WRITE_PROC_WMB) ->
+                       smp_wmb(i, j);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_WMB,
+                                 WRITE_XCHG_PTR) ->
+                       /* rcu_xchg_pointer() */
+                       atomic {
+                               old_data = READ_CACHED_VAR(rcu_ptr);
+                               WRITE_CACHED_VAR(rcu_ptr, cur_data);
+                       }
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_XCHG_PTR);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_WMB      /* No dependency on
+                                                        * WRITE_DATA because we
+                                                        * write to a
+                                                        * different location. */
+                                 | WRITE_PROC_SECOND_MB
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_FREE) ->
+                       WRITE_CACHED_VAR(rcu_data[old_data], POISON);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_FREE);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+               /*
+                * Note : Promela model adds implicit serialization of the
+                * WRITE_FREE instruction. Normally, it would be permitted to
+                * spill on the next loop execution. Given the validation we do
+                * checks for the data entry read to be poisoned, it's ok if
+                * we do not check "late arriving" memory poisoning.
+                */
+       :: 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
+#ifdef READER_PROGRESS
+               /*
+                * Make sure we don't block the reader's progress.
+                */
+               smp_mb_send(i, j, 5);
+#endif
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(rcu_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       ptr_read_first[i] = 1;
+                       ptr_read_second[i] = 1;
+                       data_read_first[i] = WINE;
+                       data_read_second[i] = WINE;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               INIT_CACHED_VAR(rcu_data[0], WINE, j);
+               i = 1;
+               do
+               :: i < SLAB_SIZE ->
+                       INIT_CACHED_VAR(rcu_data[i], POISON, j);
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_free_no_mb.spin.input.trail b/formal-model/results/urcu-controldataflow-ipi/urcu_free_no_mb.spin.input.trail
new file mode 100644 (file)
index 0000000..582fc24
--- /dev/null
@@ -0,0 +1,1423 @@
+-2:3:-2
+-4:-4:-4
+1:0:4649
+2:3:4569
+3:3:4572
+4:3:4572
+5:3:4575
+6:3:4583
+7:3:4583
+8:3:4586
+9:3:4592
+10:3:4596
+11:3:4596
+12:3:4599
+13:3:4609
+14:3:4617
+15:3:4617
+16:3:4620
+17:3:4626
+18:3:4630
+19:3:4630
+20:3:4633
+21:3:4639
+22:3:4643
+23:3:4644
+24:0:4649
+25:3:4646
+26:0:4649
+27:2:2875
+28:0:4649
+29:2:2881
+30:0:4649
+31:2:2882
+32:0:4649
+33:2:2884
+34:0:4649
+35:2:2885
+36:0:4649
+37:2:2886
+38:0:4649
+39:2:2887
+40:0:4649
+41:2:2888
+42:2:2889
+43:2:2893
+44:2:2894
+45:2:2902
+46:2:2903
+47:2:2907
+48:2:2908
+49:2:2916
+50:2:2921
+51:2:2925
+52:2:2926
+53:2:2934
+54:2:2935
+55:2:2939
+56:2:2940
+57:2:2934
+58:2:2935
+59:2:2939
+60:2:2940
+61:2:2948
+62:2:2953
+63:2:2954
+64:2:2965
+65:2:2966
+66:2:2967
+67:2:2978
+68:2:2983
+69:2:2984
+70:2:2995
+71:2:2996
+72:2:2997
+73:2:2995
+74:2:2996
+75:2:2997
+76:2:3008
+77:2:3016
+78:0:4649
+79:2:2887
+80:0:4649
+81:2:3020
+82:2:3024
+83:2:3025
+84:2:3029
+85:2:3033
+86:2:3034
+87:2:3038
+88:2:3046
+89:2:3047
+90:2:3051
+91:2:3055
+92:2:3056
+93:2:3051
+94:2:3052
+95:2:3060
+96:0:4649
+97:2:2887
+98:0:4649
+99:2:3068
+100:2:3069
+101:2:3070
+102:0:4649
+103:2:2887
+104:0:4649
+105:2:3078
+106:0:4649
+107:2:2887
+108:0:4649
+109:2:3081
+110:2:3082
+111:2:3086
+112:2:3087
+113:2:3095
+114:2:3096
+115:2:3100
+116:2:3101
+117:2:3109
+118:2:3114
+119:2:3115
+120:2:3127
+121:2:3128
+122:2:3132
+123:2:3133
+124:2:3127
+125:2:3128
+126:2:3132
+127:2:3133
+128:2:3141
+129:2:3146
+130:2:3147
+131:2:3158
+132:2:3159
+133:2:3160
+134:2:3171
+135:2:3176
+136:2:3177
+137:2:3188
+138:2:3189
+139:2:3190
+140:2:3188
+141:2:3189
+142:2:3190
+143:2:3201
+144:2:3208
+145:0:4649
+146:2:2887
+147:0:4649
+148:2:3212
+149:2:3213
+150:2:3214
+151:2:3226
+152:2:3227
+153:2:3231
+154:2:3232
+155:2:3240
+156:2:3245
+157:2:3249
+158:2:3250
+159:2:3258
+160:2:3259
+161:2:3263
+162:2:3264
+163:2:3258
+164:2:3259
+165:2:3263
+166:2:3264
+167:2:3272
+168:2:3277
+169:2:3278
+170:2:3289
+171:2:3290
+172:2:3291
+173:2:3302
+174:2:3307
+175:2:3308
+176:2:3319
+177:2:3320
+178:2:3321
+179:2:3319
+180:2:3320
+181:2:3321
+182:2:3332
+183:2:3343
+184:2:3344
+185:0:4649
+186:2:2887
+187:0:4649
+188:2:3350
+189:2:3351
+190:2:3355
+191:2:3356
+192:2:3364
+193:2:3365
+194:2:3369
+195:2:3370
+196:2:3378
+197:2:3383
+198:2:3387
+199:2:3388
+200:2:3396
+201:2:3397
+202:2:3401
+203:2:3402
+204:2:3396
+205:2:3397
+206:2:3401
+207:2:3402
+208:2:3410
+209:2:3415
+210:2:3416
+211:2:3427
+212:2:3428
+213:2:3429
+214:2:3440
+215:2:3445
+216:2:3446
+217:2:3457
+218:2:3458
+219:2:3459
+220:2:3457
+221:2:3458
+222:2:3459
+223:2:3470
+224:0:4649
+225:2:2887
+226:0:4649
+227:2:3479
+228:2:3480
+229:2:3484
+230:2:3485
+231:2:3493
+232:2:3494
+233:2:3498
+234:2:3499
+235:2:3507
+236:2:3512
+237:2:3516
+238:2:3517
+239:2:3525
+240:2:3526
+241:2:3530
+242:2:3531
+243:2:3525
+244:2:3526
+245:2:3530
+246:2:3531
+247:2:3539
+248:2:3544
+249:2:3545
+250:2:3556
+251:2:3557
+252:2:3558
+253:2:3569
+254:2:3574
+255:2:3575
+256:2:3586
+257:2:3587
+258:2:3588
+259:2:3586
+260:2:3587
+261:2:3588
+262:2:3599
+263:2:3606
+264:0:4649
+265:2:2887
+266:0:4649
+267:2:3610
+268:2:3611
+269:2:3612
+270:2:3624
+271:2:3625
+272:2:3629
+273:2:3630
+274:2:3638
+275:2:3643
+276:2:3647
+277:2:3648
+278:2:3656
+279:2:3657
+280:2:3661
+281:2:3662
+282:2:3656
+283:2:3657
+284:2:3661
+285:2:3662
+286:2:3670
+287:2:3675
+288:2:3676
+289:2:3687
+290:2:3688
+291:2:3689
+292:2:3700
+293:2:3705
+294:2:3706
+295:2:3717
+296:2:3718
+297:2:3719
+298:2:3717
+299:2:3718
+300:2:3719
+301:2:3730
+302:2:3740
+303:2:3741
+304:0:4649
+305:2:2887
+306:0:4649
+307:2:3750
+308:2:3751
+309:0:4649
+310:2:2887
+311:0:4649
+312:2:3755
+313:0:4649
+314:2:3763
+315:0:4649
+316:2:2882
+317:0:4649
+318:2:2884
+319:0:4649
+320:2:2885
+321:0:4649
+322:2:2886
+323:0:4649
+324:2:2887
+325:0:4649
+326:2:2888
+327:2:2889
+328:2:2893
+329:2:2894
+330:2:2902
+331:2:2903
+332:2:2907
+333:2:2908
+334:2:2916
+335:2:2921
+336:2:2925
+337:2:2926
+338:2:2934
+339:2:2935
+340:2:2936
+341:2:2934
+342:2:2935
+343:2:2939
+344:2:2940
+345:2:2948
+346:2:2953
+347:2:2954
+348:2:2965
+349:2:2966
+350:2:2967
+351:2:2978
+352:2:2983
+353:2:2984
+354:2:2995
+355:2:2996
+356:2:2997
+357:2:2995
+358:2:2996
+359:2:2997
+360:2:3008
+361:2:3016
+362:0:4649
+363:2:2887
+364:0:4649
+365:2:3020
+366:2:3024
+367:2:3025
+368:2:3029
+369:2:3033
+370:2:3034
+371:2:3038
+372:2:3046
+373:2:3047
+374:2:3051
+375:2:3052
+376:2:3051
+377:2:3055
+378:2:3056
+379:2:3060
+380:0:4649
+381:2:2887
+382:0:4649
+383:2:3068
+384:2:3069
+385:2:3070
+386:0:4649
+387:2:2887
+388:0:4649
+389:2:3078
+390:0:4649
+391:2:2887
+392:0:4649
+393:2:3081
+394:2:3082
+395:2:3086
+396:2:3087
+397:2:3095
+398:2:3096
+399:2:3100
+400:2:3101
+401:2:3109
+402:2:3114
+403:2:3115
+404:2:3127
+405:2:3128
+406:2:3132
+407:2:3133
+408:2:3127
+409:2:3128
+410:2:3132
+411:2:3133
+412:2:3141
+413:2:3146
+414:2:3147
+415:2:3158
+416:2:3159
+417:2:3160
+418:2:3171
+419:2:3176
+420:2:3177
+421:2:3188
+422:2:3189
+423:2:3190
+424:2:3188
+425:2:3189
+426:2:3190
+427:2:3201
+428:2:3208
+429:0:4649
+430:2:2887
+431:0:4649
+432:2:3212
+433:2:3213
+434:2:3214
+435:2:3226
+436:2:3227
+437:2:3231
+438:2:3232
+439:2:3240
+440:2:3245
+441:2:3249
+442:2:3250
+443:2:3258
+444:2:3259
+445:2:3263
+446:2:3264
+447:2:3258
+448:2:3259
+449:2:3263
+450:2:3264
+451:2:3272
+452:2:3277
+453:2:3278
+454:2:3289
+455:2:3290
+456:2:3291
+457:2:3302
+458:2:3307
+459:2:3308
+460:2:3319
+461:2:3320
+462:2:3321
+463:2:3319
+464:2:3320
+465:2:3321
+466:2:3332
+467:2:3343
+468:2:3344
+469:0:4649
+470:2:2887
+471:0:4649
+472:2:3350
+473:2:3351
+474:2:3355
+475:2:3356
+476:2:3364
+477:2:3365
+478:2:3369
+479:2:3370
+480:2:3378
+481:2:3383
+482:2:3387
+483:2:3388
+484:2:3396
+485:2:3397
+486:2:3401
+487:2:3402
+488:2:3396
+489:2:3397
+490:2:3401
+491:2:3402
+492:2:3410
+493:2:3415
+494:2:3416
+495:2:3427
+496:2:3428
+497:2:3429
+498:2:3440
+499:2:3445
+500:2:3446
+501:2:3457
+502:2:3458
+503:2:3459
+504:2:3457
+505:2:3458
+506:2:3459
+507:2:3470
+508:0:4649
+509:2:2887
+510:0:4649
+511:2:3479
+512:2:3480
+513:2:3484
+514:2:3485
+515:2:3493
+516:2:3494
+517:2:3498
+518:2:3499
+519:2:3507
+520:2:3512
+521:2:3516
+522:2:3517
+523:2:3525
+524:2:3526
+525:2:3530
+526:2:3531
+527:2:3525
+528:2:3526
+529:2:3530
+530:2:3531
+531:2:3539
+532:2:3544
+533:2:3545
+534:2:3556
+535:2:3557
+536:2:3558
+537:2:3569
+538:2:3574
+539:2:3575
+540:2:3586
+541:2:3587
+542:2:3588
+543:2:3586
+544:2:3587
+545:2:3588
+546:2:3599
+547:2:3606
+548:0:4649
+549:2:2887
+550:0:4649
+551:2:3610
+552:2:3611
+553:2:3612
+554:2:3624
+555:2:3625
+556:2:3629
+557:2:3630
+558:2:3638
+559:2:3643
+560:2:3647
+561:2:3648
+562:2:3656
+563:2:3657
+564:2:3661
+565:2:3662
+566:2:3656
+567:2:3657
+568:2:3661
+569:2:3662
+570:2:3670
+571:2:3675
+572:2:3676
+573:2:3687
+574:2:3688
+575:2:3689
+576:2:3700
+577:2:3705
+578:2:3706
+579:2:3717
+580:2:3718
+581:2:3719
+582:2:3717
+583:2:3718
+584:2:3719
+585:2:3730
+586:2:3740
+587:2:3741
+588:0:4649
+589:2:2887
+590:0:4649
+591:2:3750
+592:2:3751
+593:0:4649
+594:2:2887
+595:0:4649
+596:2:3755
+597:0:4649
+598:2:3763
+599:0:4649
+600:2:2882
+601:0:4649
+602:2:2884
+603:0:4649
+604:2:2885
+605:0:4649
+606:2:2886
+607:0:4649
+608:2:2887
+609:0:4649
+610:2:2888
+611:2:2889
+612:2:2893
+613:2:2894
+614:2:2902
+615:2:2903
+616:2:2907
+617:2:2908
+618:2:2916
+619:2:2921
+620:2:2925
+621:2:2926
+622:2:2934
+623:2:2935
+624:2:2939
+625:2:2940
+626:2:2934
+627:2:2935
+628:2:2936
+629:2:2948
+630:2:2953
+631:2:2954
+632:2:2965
+633:2:2966
+634:2:2967
+635:2:2978
+636:2:2983
+637:2:2984
+638:2:2995
+639:2:2996
+640:2:2997
+641:2:2995
+642:2:2996
+643:2:2997
+644:2:3008
+645:2:3016
+646:0:4649
+647:2:2887
+648:0:4649
+649:2:3020
+650:2:3024
+651:2:3025
+652:2:3029
+653:2:3033
+654:2:3034
+655:2:3038
+656:2:3046
+657:2:3047
+658:2:3051
+659:2:3055
+660:2:3056
+661:2:3051
+662:2:3052
+663:2:3060
+664:0:4649
+665:2:2887
+666:0:4649
+667:2:3068
+668:2:3069
+669:2:3070
+670:0:4649
+671:2:2887
+672:0:4649
+673:2:3078
+674:0:4649
+675:2:2887
+676:0:4649
+677:2:3081
+678:2:3082
+679:2:3086
+680:2:3087
+681:2:3095
+682:2:3096
+683:2:3100
+684:2:3101
+685:2:3109
+686:2:3114
+687:2:3115
+688:2:3127
+689:2:3128
+690:2:3132
+691:2:3133
+692:2:3127
+693:2:3128
+694:2:3132
+695:2:3133
+696:2:3141
+697:2:3146
+698:2:3147
+699:2:3158
+700:2:3159
+701:2:3160
+702:2:3171
+703:2:3176
+704:2:3177
+705:2:3188
+706:2:3189
+707:2:3190
+708:2:3188
+709:2:3189
+710:2:3190
+711:2:3201
+712:2:3208
+713:0:4649
+714:2:2887
+715:0:4649
+716:2:3212
+717:2:3213
+718:2:3214
+719:2:3226
+720:2:3227
+721:2:3231
+722:2:3232
+723:2:3240
+724:2:3245
+725:2:3249
+726:2:3250
+727:2:3258
+728:2:3259
+729:2:3263
+730:2:3264
+731:2:3258
+732:2:3259
+733:2:3263
+734:2:3264
+735:2:3272
+736:2:3277
+737:2:3278
+738:2:3289
+739:2:3290
+740:2:3291
+741:2:3302
+742:2:3307
+743:2:3308
+744:2:3319
+745:2:3320
+746:2:3321
+747:2:3319
+748:2:3320
+749:2:3321
+750:2:3332
+751:2:3343
+752:2:3344
+753:0:4649
+754:2:2887
+755:0:4649
+756:2:3350
+757:2:3351
+758:2:3355
+759:2:3356
+760:2:3364
+761:2:3365
+762:2:3369
+763:2:3370
+764:2:3378
+765:2:3383
+766:2:3387
+767:2:3388
+768:2:3396
+769:2:3397
+770:2:3401
+771:2:3402
+772:2:3396
+773:2:3397
+774:2:3401
+775:2:3402
+776:2:3410
+777:2:3415
+778:2:3416
+779:2:3427
+780:2:3428
+781:2:3429
+782:2:3440
+783:2:3445
+784:2:3446
+785:2:3457
+786:2:3458
+787:2:3459
+788:2:3457
+789:2:3458
+790:2:3459
+791:2:3470
+792:0:4649
+793:2:2887
+794:0:4649
+795:2:3610
+796:2:3611
+797:2:3615
+798:2:3616
+799:2:3624
+800:2:3625
+801:2:3629
+802:2:3630
+803:2:3638
+804:2:3643
+805:2:3647
+806:2:3648
+807:2:3656
+808:2:3657
+809:2:3661
+810:2:3662
+811:2:3656
+812:2:3657
+813:2:3661
+814:2:3662
+815:2:3670
+816:2:3675
+817:2:3676
+818:2:3687
+819:2:3688
+820:2:3689
+821:2:3700
+822:2:3705
+823:2:3706
+824:2:3717
+825:2:3718
+826:2:3719
+827:2:3717
+828:2:3718
+829:2:3719
+830:2:3730
+831:2:3740
+832:2:3741
+833:0:4649
+834:2:2887
+835:0:4649
+836:2:3750
+837:2:3751
+838:0:4649
+839:2:2887
+840:0:4649
+841:2:3479
+842:2:3480
+843:2:3484
+844:2:3485
+845:2:3493
+846:2:3494
+847:2:3498
+848:2:3499
+849:2:3507
+850:2:3512
+851:2:3516
+852:2:3517
+853:2:3525
+854:2:3526
+855:2:3527
+856:2:3525
+857:2:3526
+858:2:3530
+859:2:3531
+860:2:3539
+861:2:3544
+862:2:3545
+863:2:3556
+864:2:3557
+865:2:3558
+866:2:3569
+867:2:3574
+868:2:3575
+869:2:3586
+870:2:3587
+871:2:3588
+872:2:3586
+873:2:3587
+874:2:3588
+875:2:3599
+876:2:3606
+877:0:4649
+878:2:2887
+879:0:4649
+880:2:3755
+881:0:4649
+882:2:3763
+883:0:4649
+884:2:3764
+885:0:4649
+886:2:3769
+887:0:4649
+888:1:2
+889:0:4649
+890:2:3770
+891:0:4649
+892:1:8
+893:0:4649
+894:2:3769
+895:0:4649
+896:1:9
+897:0:4649
+898:2:3770
+899:0:4649
+900:1:10
+901:0:4649
+902:2:3769
+903:0:4649
+904:1:11
+905:0:4649
+906:2:3770
+907:0:4649
+908:1:12
+909:0:4649
+910:2:3769
+911:0:4649
+912:1:13
+913:0:4649
+914:2:3770
+915:0:4649
+916:1:14
+917:0:4649
+918:2:3769
+919:0:4649
+920:1:15
+921:0:4649
+922:2:3770
+923:0:4649
+924:1:16
+925:0:4649
+926:2:3769
+927:0:4649
+928:1:17
+929:0:4649
+930:2:3770
+931:0:4649
+932:1:18
+933:0:4649
+934:2:3769
+935:0:4649
+936:1:19
+937:0:4649
+938:2:3770
+939:0:4649
+940:1:20
+941:0:4649
+942:2:3769
+943:0:4649
+944:1:21
+945:0:4649
+946:2:3770
+947:0:4649
+948:1:122
+949:0:4649
+950:2:3769
+951:0:4649
+952:1:124
+953:0:4649
+954:2:3770
+955:0:4649
+956:1:23
+957:0:4649
+958:2:3769
+959:0:4649
+960:1:130
+961:1:131
+962:1:135
+963:1:136
+964:1:144
+965:1:145
+966:1:149
+967:1:150
+968:1:158
+969:1:163
+970:1:167
+971:1:168
+972:1:176
+973:1:177
+974:1:181
+975:1:182
+976:1:176
+977:1:177
+978:1:181
+979:1:182
+980:1:190
+981:1:195
+982:1:196
+983:1:207
+984:1:208
+985:1:209
+986:1:220
+987:1:232
+988:1:233
+989:1:237
+990:1:238
+991:1:239
+992:1:237
+993:1:238
+994:1:239
+995:1:250
+996:0:4649
+997:2:3770
+998:0:4649
+999:1:19
+1000:0:4649
+1001:2:3769
+1002:0:4649
+1003:1:20
+1004:0:4649
+1005:2:3770
+1006:0:4649
+1007:1:21
+1008:0:4649
+1009:2:3769
+1010:0:4649
+1011:1:122
+1012:0:4649
+1013:2:3770
+1014:0:4649
+1015:1:124
+1016:0:4649
+1017:2:3769
+1018:0:4649
+1019:1:23
+1020:0:4649
+1021:2:3770
+1022:0:4649
+1023:1:259
+1024:1:260
+1025:0:4649
+1026:2:3769
+1027:0:4649
+1028:1:19
+1029:0:4649
+1030:2:3770
+1031:0:4649
+1032:1:20
+1033:0:4649
+1034:2:3769
+1035:0:4649
+1036:1:21
+1037:0:4649
+1038:2:3770
+1039:0:4649
+1040:1:122
+1041:0:4649
+1042:2:3769
+1043:0:4649
+1044:1:124
+1045:0:4649
+1046:2:3770
+1047:0:4649
+1048:1:23
+1049:0:4649
+1050:2:3769
+1051:0:4649
+1052:1:266
+1053:1:267
+1054:1:271
+1055:1:272
+1056:1:280
+1057:1:281
+1058:1:285
+1059:1:286
+1060:1:294
+1061:1:299
+1062:1:303
+1063:1:304
+1064:1:312
+1065:1:313
+1066:1:317
+1067:1:318
+1068:1:312
+1069:1:313
+1070:1:317
+1071:1:318
+1072:1:326
+1073:1:331
+1074:1:332
+1075:1:343
+1076:1:344
+1077:1:345
+1078:1:356
+1079:1:368
+1080:1:369
+1081:1:373
+1082:1:374
+1083:1:375
+1084:1:373
+1085:1:374
+1086:1:375
+1087:1:386
+1088:0:4649
+1089:2:3770
+1090:0:4649
+1091:1:19
+1092:0:4649
+1093:2:3769
+1094:0:4649
+1095:1:20
+1096:0:4649
+1097:2:3770
+1098:0:4649
+1099:1:21
+1100:0:4649
+1101:2:3769
+1102:0:4649
+1103:1:122
+1104:0:4649
+1105:2:3770
+1106:0:4649
+1107:1:124
+1108:0:4649
+1109:2:3769
+1110:0:4649
+1111:1:23
+1112:0:4649
+1113:2:3770
+1114:0:4649
+1115:1:395
+1116:1:396
+1117:1:400
+1118:1:401
+1119:1:409
+1120:1:410
+1121:1:414
+1122:1:415
+1123:1:423
+1124:1:428
+1125:1:432
+1126:1:433
+1127:1:441
+1128:1:442
+1129:1:446
+1130:1:447
+1131:1:441
+1132:1:442
+1133:1:446
+1134:1:447
+1135:1:455
+1136:1:460
+1137:1:461
+1138:1:472
+1139:1:473
+1140:1:474
+1141:1:485
+1142:1:497
+1143:1:498
+1144:1:502
+1145:1:503
+1146:1:504
+1147:1:502
+1148:1:503
+1149:1:504
+1150:1:515
+1151:1:522
+1152:0:4649
+1153:2:3769
+1154:0:4649
+1155:1:19
+1156:0:4649
+1157:2:3770
+1158:0:4649
+1159:1:20
+1160:0:4649
+1161:2:3769
+1162:0:4649
+1163:1:21
+1164:0:4649
+1165:2:3770
+1166:0:4649
+1167:1:122
+1168:0:4649
+1169:2:3769
+1170:0:4649
+1171:1:124
+1172:0:4649
+1173:2:3770
+1174:0:4649
+1175:1:23
+1176:0:4649
+1177:2:3769
+1178:0:4649
+1179:1:660
+1180:1:661
+1181:1:665
+1182:1:666
+1183:1:674
+1184:1:675
+1185:1:676
+1186:1:688
+1187:1:693
+1188:1:697
+1189:1:698
+1190:1:706
+1191:1:707
+1192:1:711
+1193:1:712
+1194:1:706
+1195:1:707
+1196:1:711
+1197:1:712
+1198:1:720
+1199:1:725
+1200:1:726
+1201:1:737
+1202:1:738
+1203:1:739
+1204:1:750
+1205:1:762
+1206:1:763
+1207:1:767
+1208:1:768
+1209:1:769
+1210:1:767
+1211:1:768
+1212:1:769
+1213:1:780
+1214:0:4649
+1215:2:3770
+1216:0:4649
+1217:1:19
+1218:0:4649
+1219:2:3769
+1220:0:4649
+1221:1:20
+1222:0:4649
+1223:2:3770
+1224:0:4649
+1225:1:21
+1226:0:4649
+1227:2:3769
+1228:0:4649
+1229:1:122
+1230:0:4649
+1231:2:3770
+1232:0:4649
+1233:1:124
+1234:0:4649
+1235:2:3769
+1236:0:4649
+1237:1:23
+1238:0:4649
+1239:2:3770
+1240:0:4649
+1241:1:789
+1242:1:792
+1243:1:793
+1244:0:4649
+1245:2:3769
+1246:0:4649
+1247:1:19
+1248:0:4649
+1249:2:3770
+1250:0:4649
+1251:1:20
+1252:0:4649
+1253:2:3769
+1254:0:4649
+1255:1:21
+1256:0:4649
+1257:2:3770
+1258:0:4649
+1259:1:122
+1260:0:4649
+1261:2:3769
+1262:0:4649
+1263:1:124
+1264:0:4649
+1265:2:3770
+1266:0:4649
+1267:1:23
+1268:0:4649
+1269:2:3769
+1270:0:4649
+1271:1:1056
+1272:1:1057
+1273:1:1061
+1274:1:1062
+1275:1:1070
+1276:1:1071
+1277:1:1075
+1278:1:1076
+1279:1:1084
+1280:1:1089
+1281:1:1093
+1282:1:1094
+1283:1:1102
+1284:1:1103
+1285:1:1107
+1286:1:1108
+1287:1:1102
+1288:1:1103
+1289:1:1107
+1290:1:1108
+1291:1:1116
+1292:1:1121
+1293:1:1122
+1294:1:1133
+1295:1:1134
+1296:1:1135
+1297:1:1146
+1298:1:1158
+1299:1:1159
+1300:1:1163
+1301:1:1164
+1302:1:1165
+1303:1:1163
+1304:1:1164
+1305:1:1165
+1306:1:1176
+1307:1:1183
+1308:1:1187
+1309:0:4649
+1310:2:3770
+1311:0:4649
+1312:1:19
+1313:0:4649
+1314:2:3769
+1315:0:4649
+1316:1:20
+1317:0:4649
+1318:2:3770
+1319:0:4649
+1320:1:21
+1321:0:4649
+1322:2:3769
+1323:0:4649
+1324:1:122
+1325:0:4649
+1326:2:3770
+1327:0:4649
+1328:1:124
+1329:0:4649
+1330:2:3769
+1331:0:4649
+1332:1:23
+1333:0:4649
+1334:2:3770
+1335:0:4649
+1336:1:1188
+1337:1:1189
+1338:1:1193
+1339:1:1194
+1340:1:1202
+1341:1:1203
+1342:1:1204
+1343:1:1216
+1344:1:1221
+1345:1:1225
+1346:1:1226
+1347:1:1234
+1348:1:1235
+1349:1:1239
+1350:1:1240
+1351:1:1234
+1352:1:1235
+1353:1:1239
+1354:1:1240
+1355:1:1248
+1356:1:1253
+1357:1:1254
+1358:1:1265
+1359:1:1266
+1360:1:1267
+1361:1:1278
+1362:1:1290
+1363:1:1291
+1364:1:1295
+1365:1:1296
+1366:1:1297
+1367:1:1295
+1368:1:1296
+1369:1:1297
+1370:1:1308
+1371:0:4649
+1372:2:3769
+1373:0:4649
+1374:1:19
+1375:0:4649
+1376:2:3770
+1377:0:4649
+1378:1:20
+1379:0:4649
+1380:2:3769
+1381:0:4649
+1382:1:21
+1383:0:4649
+1384:2:3770
+1385:0:4649
+1386:1:122
+1387:0:4649
+1388:2:3769
+1389:0:4649
+1390:1:124
+1391:0:4649
+1392:2:3770
+1393:0:4649
+1394:1:23
+1395:0:4649
+1396:2:3769
+1397:0:4649
+1398:1:1317
+1399:0:4649
+1400:2:3770
+1401:0:4649
+1402:1:2781
+1403:1:2788
+1404:1:2789
+1405:1:2796
+1406:1:2801
+1407:1:2808
+1408:1:2809
+1409:1:2808
+1410:1:2809
+1411:1:2816
+1412:1:2820
+1413:0:4649
+1414:2:3769
+1415:0:4649
+1416:1:1319
+1417:1:1320
+1418:0:4647
+1419:2:3770
+1420:0:4653
+1421:1:2465
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_free_no_rmb.define b/formal-model/results/urcu-controldataflow-ipi/urcu_free_no_rmb.define
new file mode 100644 (file)
index 0000000..73e61a4
--- /dev/null
@@ -0,0 +1 @@
+#define NO_RMB
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_free_no_rmb.log b/formal-model/results/urcu-controldataflow-ipi/urcu_free_no_rmb.log
new file mode 100644 (file)
index 0000000..dd57567
--- /dev/null
@@ -0,0 +1,581 @@
+rm -f pan* trail.out .input.spin* *.spin.trail .input.define
+touch .input.define
+cat .input.define >> pan.ltl
+cat DEFINES >> pan.ltl
+spin -f "!(`cat urcu_free.ltl | grep -v ^//`)" >> pan.ltl
+cp urcu_free_no_rmb.define .input.define
+cat .input.define > .input.spin
+cat DEFINES >> .input.spin
+cat urcu.spin >> .input.spin
+rm -f .input.spin.trail
+spin -a -X -N pan.ltl .input.spin
+Exit-Status 0
+gcc -O2 -w -DHASH64 -o pan pan.c
+./pan -a -v -c1 -X -m10000000 -w20
+warning: for p.o. reduction to be valid the never claim must be stutter-invariant
+(never claims generated from LTL formulae are stutter-invariant)
+depth 0: Claim reached state 5 (line 1258)
+Depth=    7365 States=    1e+06 Transitions= 1.38e+08 Memory=   550.432        t=    168 R=   6e+03
+Depth=    7365 States=    2e+06 Transitions= 4.31e+08 Memory=   634.318        t=    540 R=   4e+03
+pan: claim violated! (at depth 1624)
+pan: wrote .input.spin.trail
+
+(Spin Version 5.1.7 -- 23 December 2008)
+Warning: Search not completed
+       + Partial Order Reduction
+
+Full statespace search for:
+       never claim             +
+       assertion violations    + (if within scope of claim)
+       acceptance   cycles     + (fairness disabled)
+       invalid end states      - (disabled by never claim)
+
+State-vector 88 byte, depth reached 7365, errors: 1
+  2266036 states, stored
+5.03936e+08 states, matched
+5.0620203e+08 transitions (= stored+matched)
+2.8832147e+09 atomic steps
+hash conflicts: 3.6698737e+08 (resolved)
+
+Stats on memory usage (in Megabytes):
+  250.683      equivalent memory usage for states (stored*(State-vector + overhead))
+  191.039      actual memory usage for states (compression: 76.21%)
+               state-vector as stored = 60 byte + 28 byte overhead
+    8.000      memory used for hash table (-w20)
+  457.764      memory used for DFS stack (-m10000000)
+  656.682      total actual memory usage
+
+unreached in proctype urcu_reader
+       line 250, "pan.___", state 30, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 52, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 61, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 77, "(1)"
+       line 231, "pan.___", state 85, "(1)"
+       line 235, "pan.___", state 97, "(1)"
+       line 239, "pan.___", state 105, "(1)"
+       line 395, "pan.___", state 131, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 163, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 177, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 196, "(1)"
+       line 421, "pan.___", state 226, "(1)"
+       line 425, "pan.___", state 239, "(1)"
+       line 670, "pan.___", state 260, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<1))"
+       line 395, "pan.___", state 267, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 299, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 313, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 332, "(1)"
+       line 421, "pan.___", state 362, "(1)"
+       line 425, "pan.___", state 375, "(1)"
+       line 395, "pan.___", state 396, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 428, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 442, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 461, "(1)"
+       line 421, "pan.___", state 491, "(1)"
+       line 425, "pan.___", state 504, "(1)"
+       line 395, "pan.___", state 527, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 529, "(1)"
+       line 395, "pan.___", state 530, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 530, "else"
+       line 395, "pan.___", state 533, "(1)"
+       line 399, "pan.___", state 541, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 543, "(1)"
+       line 399, "pan.___", state 544, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 544, "else"
+       line 399, "pan.___", state 547, "(1)"
+       line 399, "pan.___", state 548, "(1)"
+       line 399, "pan.___", state 548, "(1)"
+       line 397, "pan.___", state 553, "((i<1))"
+       line 397, "pan.___", state 553, "((i>=1))"
+       line 404, "pan.___", state 559, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 561, "(1)"
+       line 404, "pan.___", state 562, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 562, "else"
+       line 404, "pan.___", state 565, "(1)"
+       line 404, "pan.___", state 566, "(1)"
+       line 404, "pan.___", state 566, "(1)"
+       line 408, "pan.___", state 573, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 575, "(1)"
+       line 408, "pan.___", state 576, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 576, "else"
+       line 408, "pan.___", state 579, "(1)"
+       line 408, "pan.___", state 580, "(1)"
+       line 408, "pan.___", state 580, "(1)"
+       line 406, "pan.___", state 585, "((i<2))"
+       line 406, "pan.___", state 585, "((i>=2))"
+       line 412, "pan.___", state 592, "(1)"
+       line 412, "pan.___", state 593, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 593, "else"
+       line 412, "pan.___", state 596, "(1)"
+       line 412, "pan.___", state 597, "(1)"
+       line 412, "pan.___", state 597, "(1)"
+       line 416, "pan.___", state 605, "(1)"
+       line 416, "pan.___", state 606, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 606, "else"
+       line 416, "pan.___", state 609, "(1)"
+       line 416, "pan.___", state 610, "(1)"
+       line 416, "pan.___", state 610, "(1)"
+       line 414, "pan.___", state 615, "((i<1))"
+       line 414, "pan.___", state 615, "((i>=1))"
+       line 421, "pan.___", state 622, "(1)"
+       line 421, "pan.___", state 623, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 623, "else"
+       line 421, "pan.___", state 626, "(1)"
+       line 421, "pan.___", state 627, "(1)"
+       line 421, "pan.___", state 627, "(1)"
+       line 425, "pan.___", state 635, "(1)"
+       line 425, "pan.___", state 636, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 636, "else"
+       line 425, "pan.___", state 639, "(1)"
+       line 425, "pan.___", state 640, "(1)"
+       line 425, "pan.___", state 640, "(1)"
+       line 423, "pan.___", state 645, "((i<2))"
+       line 423, "pan.___", state 645, "((i>=2))"
+       line 430, "pan.___", state 649, "(1)"
+       line 430, "pan.___", state 649, "(1)"
+       line 670, "pan.___", state 652, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 670, "pan.___", state 653, "_proc_urcu_reader = (_proc_urcu_reader|(1<<5))"
+       line 670, "pan.___", state 654, "(1)"
+       line 395, "pan.___", state 661, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 693, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 707, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 726, "(1)"
+       line 421, "pan.___", state 756, "(1)"
+       line 425, "pan.___", state 769, "(1)"
+       line 395, "pan.___", state 797, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 799, "(1)"
+       line 395, "pan.___", state 800, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 800, "else"
+       line 395, "pan.___", state 803, "(1)"
+       line 399, "pan.___", state 811, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 813, "(1)"
+       line 399, "pan.___", state 814, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 814, "else"
+       line 399, "pan.___", state 817, "(1)"
+       line 399, "pan.___", state 818, "(1)"
+       line 399, "pan.___", state 818, "(1)"
+       line 397, "pan.___", state 823, "((i<1))"
+       line 397, "pan.___", state 823, "((i>=1))"
+       line 404, "pan.___", state 829, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 831, "(1)"
+       line 404, "pan.___", state 832, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 832, "else"
+       line 404, "pan.___", state 835, "(1)"
+       line 404, "pan.___", state 836, "(1)"
+       line 404, "pan.___", state 836, "(1)"
+       line 408, "pan.___", state 843, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 845, "(1)"
+       line 408, "pan.___", state 846, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 846, "else"
+       line 408, "pan.___", state 849, "(1)"
+       line 408, "pan.___", state 850, "(1)"
+       line 408, "pan.___", state 850, "(1)"
+       line 406, "pan.___", state 855, "((i<2))"
+       line 406, "pan.___", state 855, "((i>=2))"
+       line 412, "pan.___", state 862, "(1)"
+       line 412, "pan.___", state 863, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 863, "else"
+       line 412, "pan.___", state 866, "(1)"
+       line 412, "pan.___", state 867, "(1)"
+       line 412, "pan.___", state 867, "(1)"
+       line 416, "pan.___", state 875, "(1)"
+       line 416, "pan.___", state 876, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 876, "else"
+       line 416, "pan.___", state 879, "(1)"
+       line 416, "pan.___", state 880, "(1)"
+       line 416, "pan.___", state 880, "(1)"
+       line 414, "pan.___", state 885, "((i<1))"
+       line 414, "pan.___", state 885, "((i>=1))"
+       line 421, "pan.___", state 892, "(1)"
+       line 421, "pan.___", state 893, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 893, "else"
+       line 421, "pan.___", state 896, "(1)"
+       line 421, "pan.___", state 897, "(1)"
+       line 421, "pan.___", state 897, "(1)"
+       line 425, "pan.___", state 905, "(1)"
+       line 425, "pan.___", state 906, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 906, "else"
+       line 425, "pan.___", state 909, "(1)"
+       line 425, "pan.___", state 910, "(1)"
+       line 425, "pan.___", state 910, "(1)"
+       line 430, "pan.___", state 919, "(1)"
+       line 430, "pan.___", state 919, "(1)"
+       line 395, "pan.___", state 926, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 928, "(1)"
+       line 395, "pan.___", state 929, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 929, "else"
+       line 395, "pan.___", state 932, "(1)"
+       line 399, "pan.___", state 940, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 942, "(1)"
+       line 399, "pan.___", state 943, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 943, "else"
+       line 399, "pan.___", state 946, "(1)"
+       line 399, "pan.___", state 947, "(1)"
+       line 399, "pan.___", state 947, "(1)"
+       line 397, "pan.___", state 952, "((i<1))"
+       line 397, "pan.___", state 952, "((i>=1))"
+       line 404, "pan.___", state 958, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 960, "(1)"
+       line 404, "pan.___", state 961, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 961, "else"
+       line 404, "pan.___", state 964, "(1)"
+       line 404, "pan.___", state 965, "(1)"
+       line 404, "pan.___", state 965, "(1)"
+       line 408, "pan.___", state 972, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 974, "(1)"
+       line 408, "pan.___", state 975, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 975, "else"
+       line 408, "pan.___", state 978, "(1)"
+       line 408, "pan.___", state 979, "(1)"
+       line 408, "pan.___", state 979, "(1)"
+       line 406, "pan.___", state 984, "((i<2))"
+       line 406, "pan.___", state 984, "((i>=2))"
+       line 412, "pan.___", state 991, "(1)"
+       line 412, "pan.___", state 992, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 992, "else"
+       line 412, "pan.___", state 995, "(1)"
+       line 412, "pan.___", state 996, "(1)"
+       line 412, "pan.___", state 996, "(1)"
+       line 416, "pan.___", state 1004, "(1)"
+       line 416, "pan.___", state 1005, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 1005, "else"
+       line 416, "pan.___", state 1008, "(1)"
+       line 416, "pan.___", state 1009, "(1)"
+       line 416, "pan.___", state 1009, "(1)"
+       line 414, "pan.___", state 1014, "((i<1))"
+       line 414, "pan.___", state 1014, "((i>=1))"
+       line 421, "pan.___", state 1021, "(1)"
+       line 421, "pan.___", state 1022, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 1022, "else"
+       line 421, "pan.___", state 1025, "(1)"
+       line 421, "pan.___", state 1026, "(1)"
+       line 421, "pan.___", state 1026, "(1)"
+       line 425, "pan.___", state 1034, "(1)"
+       line 425, "pan.___", state 1035, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 1035, "else"
+       line 425, "pan.___", state 1038, "(1)"
+       line 425, "pan.___", state 1039, "(1)"
+       line 425, "pan.___", state 1039, "(1)"
+       line 423, "pan.___", state 1044, "((i<2))"
+       line 423, "pan.___", state 1044, "((i>=2))"
+       line 430, "pan.___", state 1048, "(1)"
+       line 430, "pan.___", state 1048, "(1)"
+       line 678, "pan.___", state 1052, "_proc_urcu_reader = (_proc_urcu_reader|(1<<11))"
+       line 395, "pan.___", state 1057, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1089, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1103, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1122, "(1)"
+       line 421, "pan.___", state 1152, "(1)"
+       line 425, "pan.___", state 1165, "(1)"
+       line 395, "pan.___", state 1189, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1221, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1235, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1254, "(1)"
+       line 421, "pan.___", state 1284, "(1)"
+       line 425, "pan.___", state 1297, "(1)"
+       line 395, "pan.___", state 1322, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1354, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1368, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1387, "(1)"
+       line 421, "pan.___", state 1417, "(1)"
+       line 425, "pan.___", state 1430, "(1)"
+       line 395, "pan.___", state 1451, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1483, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1497, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1516, "(1)"
+       line 421, "pan.___", state 1546, "(1)"
+       line 425, "pan.___", state 1559, "(1)"
+       line 395, "pan.___", state 1585, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1617, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1631, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1650, "(1)"
+       line 421, "pan.___", state 1680, "(1)"
+       line 425, "pan.___", state 1693, "(1)"
+       line 395, "pan.___", state 1714, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1746, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1760, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1779, "(1)"
+       line 421, "pan.___", state 1809, "(1)"
+       line 425, "pan.___", state 1822, "(1)"
+       line 395, "pan.___", state 1846, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1878, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1892, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1911, "(1)"
+       line 421, "pan.___", state 1941, "(1)"
+       line 425, "pan.___", state 1954, "(1)"
+       line 717, "pan.___", state 1975, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<19))"
+       line 395, "pan.___", state 1982, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2014, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2028, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2047, "(1)"
+       line 421, "pan.___", state 2077, "(1)"
+       line 425, "pan.___", state 2090, "(1)"
+       line 395, "pan.___", state 2111, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2143, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2157, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2176, "(1)"
+       line 421, "pan.___", state 2206, "(1)"
+       line 425, "pan.___", state 2219, "(1)"
+       line 395, "pan.___", state 2242, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 2244, "(1)"
+       line 395, "pan.___", state 2245, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 2245, "else"
+       line 395, "pan.___", state 2248, "(1)"
+       line 399, "pan.___", state 2256, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 2258, "(1)"
+       line 399, "pan.___", state 2259, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 2259, "else"
+       line 399, "pan.___", state 2262, "(1)"
+       line 399, "pan.___", state 2263, "(1)"
+       line 399, "pan.___", state 2263, "(1)"
+       line 397, "pan.___", state 2268, "((i<1))"
+       line 397, "pan.___", state 2268, "((i>=1))"
+       line 404, "pan.___", state 2274, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2276, "(1)"
+       line 404, "pan.___", state 2277, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 2277, "else"
+       line 404, "pan.___", state 2280, "(1)"
+       line 404, "pan.___", state 2281, "(1)"
+       line 404, "pan.___", state 2281, "(1)"
+       line 408, "pan.___", state 2288, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2290, "(1)"
+       line 408, "pan.___", state 2291, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 2291, "else"
+       line 408, "pan.___", state 2294, "(1)"
+       line 408, "pan.___", state 2295, "(1)"
+       line 408, "pan.___", state 2295, "(1)"
+       line 406, "pan.___", state 2300, "((i<2))"
+       line 406, "pan.___", state 2300, "((i>=2))"
+       line 412, "pan.___", state 2307, "(1)"
+       line 412, "pan.___", state 2308, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 2308, "else"
+       line 412, "pan.___", state 2311, "(1)"
+       line 412, "pan.___", state 2312, "(1)"
+       line 412, "pan.___", state 2312, "(1)"
+       line 416, "pan.___", state 2320, "(1)"
+       line 416, "pan.___", state 2321, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 2321, "else"
+       line 416, "pan.___", state 2324, "(1)"
+       line 416, "pan.___", state 2325, "(1)"
+       line 416, "pan.___", state 2325, "(1)"
+       line 414, "pan.___", state 2330, "((i<1))"
+       line 414, "pan.___", state 2330, "((i>=1))"
+       line 421, "pan.___", state 2337, "(1)"
+       line 421, "pan.___", state 2338, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 2338, "else"
+       line 421, "pan.___", state 2341, "(1)"
+       line 421, "pan.___", state 2342, "(1)"
+       line 421, "pan.___", state 2342, "(1)"
+       line 425, "pan.___", state 2350, "(1)"
+       line 425, "pan.___", state 2351, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 2351, "else"
+       line 425, "pan.___", state 2354, "(1)"
+       line 425, "pan.___", state 2355, "(1)"
+       line 425, "pan.___", state 2355, "(1)"
+       line 423, "pan.___", state 2360, "((i<2))"
+       line 423, "pan.___", state 2360, "((i>=2))"
+       line 430, "pan.___", state 2364, "(1)"
+       line 430, "pan.___", state 2364, "(1)"
+       line 717, "pan.___", state 2367, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 717, "pan.___", state 2368, "_proc_urcu_reader = (_proc_urcu_reader|(1<<23))"
+       line 717, "pan.___", state 2369, "(1)"
+       line 395, "pan.___", state 2376, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2408, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2422, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2441, "(1)"
+       line 421, "pan.___", state 2471, "(1)"
+       line 425, "pan.___", state 2484, "(1)"
+       line 395, "pan.___", state 2511, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2543, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2557, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2576, "(1)"
+       line 421, "pan.___", state 2606, "(1)"
+       line 425, "pan.___", state 2619, "(1)"
+       line 395, "pan.___", state 2640, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2672, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2686, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2705, "(1)"
+       line 421, "pan.___", state 2735, "(1)"
+       line 425, "pan.___", state 2748, "(1)"
+       line 395, "pan.___", state 2781, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2813, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2827, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2846, "(1)"
+       line 421, "pan.___", state 2876, "(1)"
+       line 425, "pan.___", state 2889, "(1)"
+       line 395, "pan.___", state 2908, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2940, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2954, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2973, "(1)"
+       line 421, "pan.___", state 3003, "(1)"
+       line 425, "pan.___", state 3016, "(1)"
+       line 877, "pan.___", state 3037, "-end-"
+       (284 of 3037 states)
+unreached in proctype urcu_writer
+       line 395, "pan.___", state 18, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 24, "(1)"
+       line 399, "pan.___", state 32, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 38, "(1)"
+       line 399, "pan.___", state 39, "(1)"
+       line 399, "pan.___", state 39, "(1)"
+       line 397, "pan.___", state 44, "((i<1))"
+       line 397, "pan.___", state 44, "((i>=1))"
+       line 404, "pan.___", state 50, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 56, "(1)"
+       line 404, "pan.___", state 57, "(1)"
+       line 404, "pan.___", state 57, "(1)"
+       line 408, "pan.___", state 70, "(1)"
+       line 408, "pan.___", state 71, "(1)"
+       line 408, "pan.___", state 71, "(1)"
+       line 406, "pan.___", state 76, "((i<2))"
+       line 406, "pan.___", state 76, "((i>=2))"
+       line 412, "pan.___", state 83, "(1)"
+       line 412, "pan.___", state 84, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 84, "else"
+       line 412, "pan.___", state 87, "(1)"
+       line 412, "pan.___", state 88, "(1)"
+       line 412, "pan.___", state 88, "(1)"
+       line 416, "pan.___", state 96, "(1)"
+       line 416, "pan.___", state 97, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 97, "else"
+       line 416, "pan.___", state 100, "(1)"
+       line 416, "pan.___", state 101, "(1)"
+       line 416, "pan.___", state 101, "(1)"
+       line 414, "pan.___", state 106, "((i<1))"
+       line 414, "pan.___", state 106, "((i>=1))"
+       line 421, "pan.___", state 113, "(1)"
+       line 421, "pan.___", state 114, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 114, "else"
+       line 421, "pan.___", state 117, "(1)"
+       line 421, "pan.___", state 118, "(1)"
+       line 421, "pan.___", state 118, "(1)"
+       line 425, "pan.___", state 126, "(1)"
+       line 425, "pan.___", state 127, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 127, "else"
+       line 425, "pan.___", state 130, "(1)"
+       line 425, "pan.___", state 131, "(1)"
+       line 425, "pan.___", state 131, "(1)"
+       line 423, "pan.___", state 136, "((i<2))"
+       line 423, "pan.___", state 136, "((i>=2))"
+       line 430, "pan.___", state 140, "(1)"
+       line 430, "pan.___", state 140, "(1)"
+       line 250, "pan.___", state 149, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 158, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 171, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 211, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 225, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 243, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 257, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 276, "(1)"
+       line 416, "pan.___", state 289, "(1)"
+       line 421, "pan.___", state 306, "(1)"
+       line 425, "pan.___", state 319, "(1)"
+       line 399, "pan.___", state 356, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 374, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 388, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 420, "(1)"
+       line 421, "pan.___", state 437, "(1)"
+       line 425, "pan.___", state 450, "(1)"
+       line 399, "pan.___", state 494, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 512, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 526, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 558, "(1)"
+       line 421, "pan.___", state 575, "(1)"
+       line 425, "pan.___", state 588, "(1)"
+       line 399, "pan.___", state 623, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 641, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 655, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 687, "(1)"
+       line 421, "pan.___", state 704, "(1)"
+       line 425, "pan.___", state 717, "(1)"
+       line 399, "pan.___", state 754, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 772, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 786, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 818, "(1)"
+       line 421, "pan.___", state 835, "(1)"
+       line 425, "pan.___", state 848, "(1)"
+       line 250, "pan.___", state 903, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 912, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 927, "(1)"
+       line 262, "pan.___", state 934, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 950, "(1)"
+       line 231, "pan.___", state 958, "(1)"
+       line 235, "pan.___", state 970, "(1)"
+       line 239, "pan.___", state 978, "(1)"
+       line 250, "pan.___", state 1009, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1018, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1031, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1040, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1056, "(1)"
+       line 231, "pan.___", state 1064, "(1)"
+       line 235, "pan.___", state 1076, "(1)"
+       line 239, "pan.___", state 1084, "(1)"
+       line 254, "pan.___", state 1110, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1123, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1132, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1148, "(1)"
+       line 231, "pan.___", state 1156, "(1)"
+       line 235, "pan.___", state 1168, "(1)"
+       line 239, "pan.___", state 1176, "(1)"
+       line 250, "pan.___", state 1207, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1216, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1229, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1238, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1254, "(1)"
+       line 231, "pan.___", state 1262, "(1)"
+       line 235, "pan.___", state 1274, "(1)"
+       line 239, "pan.___", state 1282, "(1)"
+       line 254, "pan.___", state 1308, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1321, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1330, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1346, "(1)"
+       line 231, "pan.___", state 1354, "(1)"
+       line 235, "pan.___", state 1366, "(1)"
+       line 239, "pan.___", state 1374, "(1)"
+       line 250, "pan.___", state 1405, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1414, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1427, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1436, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1452, "(1)"
+       line 231, "pan.___", state 1460, "(1)"
+       line 235, "pan.___", state 1472, "(1)"
+       line 239, "pan.___", state 1480, "(1)"
+       line 254, "pan.___", state 1506, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1519, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1528, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1544, "(1)"
+       line 231, "pan.___", state 1552, "(1)"
+       line 235, "pan.___", state 1564, "(1)"
+       line 239, "pan.___", state 1572, "(1)"
+       line 250, "pan.___", state 1603, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1612, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1625, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1634, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1650, "(1)"
+       line 231, "pan.___", state 1658, "(1)"
+       line 235, "pan.___", state 1670, "(1)"
+       line 239, "pan.___", state 1678, "(1)"
+       line 1204, "pan.___", state 1694, "-end-"
+       (128 of 1694 states)
+unreached in proctype :init:
+       line 1215, "pan.___", state 9, "((j<2))"
+       line 1215, "pan.___", state 9, "((j>=2))"
+       line 1216, "pan.___", state 20, "((j<2))"
+       line 1216, "pan.___", state 20, "((j>=2))"
+       line 1221, "pan.___", state 33, "((j<2))"
+       line 1221, "pan.___", state 33, "((j>=2))"
+       line 1219, "pan.___", state 43, "((i<1))"
+       line 1219, "pan.___", state 43, "((i>=1))"
+       line 1229, "pan.___", state 54, "((j<2))"
+       line 1229, "pan.___", state 54, "((j>=2))"
+       line 1233, "pan.___", state 67, "((j<2))"
+       line 1233, "pan.___", state 67, "((j>=2))"
+       (6 of 78 states)
+unreached in proctype :never:
+       line 1263, "pan.___", state 8, "-end-"
+       (1 of 8 states)
+
+pan: elapsed time 638 seconds
+pan: rate  3551.057 states/second
+pan: avg transition delay 1.2606e-06 usec
+cp .input.spin urcu_free_no_rmb.spin.input
+cp .input.spin.trail urcu_free_no_rmb.spin.input.trail
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_free_no_rmb.spin.input b/formal-model/results/urcu-controldataflow-ipi/urcu_free_no_rmb.spin.input
new file mode 100644 (file)
index 0000000..f653370
--- /dev/null
@@ -0,0 +1,1240 @@
+#define NO_RMB
+
+// Poison value for freed memory
+#define POISON 1
+// Memory with correct data
+#define WINE 0
+#define SLAB_SIZE 2
+
+#define read_poison    (data_read_first[0] == POISON || data_read_second[0] == POISON)
+
+#define RCU_GP_CTR_BIT (1 << 7)
+#define RCU_GP_CTR_NEST_MASK (RCU_GP_CTR_BIT - 1)
+
+//disabled
+#define REMOTE_BARRIERS
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+typedef per_proc_bit {
+       bit val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bitfield {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bitfield cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               /*
+                * 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, j);
+               reader_barrier[get_readerid()] = 0;
+       :: 1 ->
+               /*
+                * 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)
+//#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);                                                           \
+       i = 0;                                                                  \
+       do                                                                      \
+       :: i < NR_READERS ->                                                    \
+               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.                                            \
+                */                                                             \
+               do                                                              \
+               :: (reader_barrier[i] == 1) ->                                  \
+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(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, smp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only one reader */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* RCU data */
+DECLARE_CACHED_VAR(bit, rcu_data[SLAB_SIZE]);
+
+/* RCU pointer */
+#if (SLAB_SIZE == 2)
+DECLARE_CACHED_VAR(bit, rcu_ptr);
+bit ptr_read_first[NR_READERS];
+bit ptr_read_second[NR_READERS];
+#else
+DECLARE_CACHED_VAR(byte, rcu_ptr);
+byte ptr_read_first[NR_READERS];
+byte ptr_read_second[NR_READERS];
+#endif
+
+bit data_read_first[NR_READERS];
+bit data_read_second[NR_READERS];
+
+bit init_done = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               ptr_read_first[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb1;
+rmb1_end:
+                               data_read_first[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_first[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               ptr_read_second[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb2;
+rmb2_end:
+                               data_read_second[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_second[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+rmb1:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb1_end;
+rmb2:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_DATA                     (1 << 1)
+#define WRITE_PROC_WMB                 (1 << 2)
+#define WRITE_XCHG_PTR                 (1 << 3)
+
+#define WRITE_PROC_FIRST_MB            (1 << 4)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 5)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 6)
+#define WRITE_PROC_FIRST_WAIT          (1 << 7)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 8)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 9)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 10)
+#define WRITE_PROC_SECOND_WAIT         (1 << 11)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 12)
+
+#define WRITE_PROC_SECOND_MB           (1 << 13)
+
+#define WRITE_FREE                     (1 << 14)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_DATA                    \
+                                       | WRITE_PROC_WMB                \
+                                       | WRITE_XCHG_PTR                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB          \
+                                       | WRITE_FREE)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 15) - 1)
+
+/*
+ * Mutexes are implied around writer execution. A single writer at a time.
+ */
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte cur_data = 0, old_data, loop_nr = 0;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (loop_nr < 3) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               loop_nr = loop_nr + 1;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_WMB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+#endif
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_DATA) ->
+                       ooo_mem(i);
+                       cur_data = (cur_data + 1) % SLAB_SIZE;
+                       WRITE_CACHED_VAR(rcu_data[cur_data], WINE);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_DATA);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA,
+                                 WRITE_PROC_WMB) ->
+                       smp_wmb(i, j);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_WMB,
+                                 WRITE_XCHG_PTR) ->
+                       /* rcu_xchg_pointer() */
+                       atomic {
+                               old_data = READ_CACHED_VAR(rcu_ptr);
+                               WRITE_CACHED_VAR(rcu_ptr, cur_data);
+                       }
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_XCHG_PTR);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_WMB      /* No dependency on
+                                                        * WRITE_DATA because we
+                                                        * write to a
+                                                        * different location. */
+                                 | WRITE_PROC_SECOND_MB
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_FREE) ->
+                       WRITE_CACHED_VAR(rcu_data[old_data], POISON);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_FREE);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+               /*
+                * Note : Promela model adds implicit serialization of the
+                * WRITE_FREE instruction. Normally, it would be permitted to
+                * spill on the next loop execution. Given the validation we do
+                * checks for the data entry read to be poisoned, it's ok if
+                * we do not check "late arriving" memory poisoning.
+                */
+       :: 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
+#ifdef READER_PROGRESS
+               /*
+                * Make sure we don't block the reader's progress.
+                */
+               smp_mb_send(i, j, 5);
+#endif
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(rcu_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       ptr_read_first[i] = 1;
+                       ptr_read_second[i] = 1;
+                       data_read_first[i] = WINE;
+                       data_read_second[i] = WINE;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               INIT_CACHED_VAR(rcu_data[0], WINE, j);
+               i = 1;
+               do
+               :: i < SLAB_SIZE ->
+                       INIT_CACHED_VAR(rcu_data[i], POISON, j);
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_free_no_rmb.spin.input.trail b/formal-model/results/urcu-controldataflow-ipi/urcu_free_no_rmb.spin.input.trail
new file mode 100644 (file)
index 0000000..ad65225
--- /dev/null
@@ -0,0 +1,1627 @@
+-2:3:-2
+-4:-4:-4
+1:0:4811
+2:3:4731
+3:3:4734
+4:3:4734
+5:3:4737
+6:3:4745
+7:3:4745
+8:3:4748
+9:3:4754
+10:3:4758
+11:3:4758
+12:3:4761
+13:3:4771
+14:3:4779
+15:3:4779
+16:3:4782
+17:3:4788
+18:3:4792
+19:3:4792
+20:3:4795
+21:3:4801
+22:3:4805
+23:3:4806
+24:0:4811
+25:3:4808
+26:0:4811
+27:2:3039
+28:0:4811
+29:2:3045
+30:0:4811
+31:2:3046
+32:0:4811
+33:2:3048
+34:0:4811
+35:2:3049
+36:0:4811
+37:2:3050
+38:2:3051
+39:2:3055
+40:2:3056
+41:2:3064
+42:2:3065
+43:2:3069
+44:2:3070
+45:2:3078
+46:2:3083
+47:2:3087
+48:2:3088
+49:2:3096
+50:2:3097
+51:2:3101
+52:2:3102
+53:2:3096
+54:2:3097
+55:2:3101
+56:2:3102
+57:2:3110
+58:2:3115
+59:2:3116
+60:2:3127
+61:2:3128
+62:2:3129
+63:2:3140
+64:2:3145
+65:2:3146
+66:2:3157
+67:2:3158
+68:2:3159
+69:2:3157
+70:2:3158
+71:2:3159
+72:2:3170
+73:2:3178
+74:0:4811
+75:2:3049
+76:0:4811
+77:2:3182
+78:2:3186
+79:2:3187
+80:2:3191
+81:2:3195
+82:2:3196
+83:2:3200
+84:2:3208
+85:2:3209
+86:2:3213
+87:2:3217
+88:2:3218
+89:2:3213
+90:2:3214
+91:2:3222
+92:0:4811
+93:2:3049
+94:0:4811
+95:2:3230
+96:2:3231
+97:2:3232
+98:0:4811
+99:2:3049
+100:0:4811
+101:2:3237
+102:0:4811
+103:2:3940
+104:2:3941
+105:2:3945
+106:2:3949
+107:2:3950
+108:2:3954
+109:2:3959
+110:2:3967
+111:2:3971
+112:2:3972
+113:2:3967
+114:2:3971
+115:2:3972
+116:2:3976
+117:2:3983
+118:2:3990
+119:2:3991
+120:2:3998
+121:2:4003
+122:2:4010
+123:2:4011
+124:2:4010
+125:2:4011
+126:2:4018
+127:2:4022
+128:0:4811
+129:2:4027
+130:0:4811
+131:2:4028
+132:0:4811
+133:2:4029
+134:0:4811
+135:2:4030
+136:0:4811
+137:1:2
+138:0:4811
+139:2:4031
+140:0:4811
+141:1:8
+142:0:4811
+143:1:9
+144:0:4811
+145:2:4030
+146:0:4811
+147:1:10
+148:0:4811
+149:2:4031
+150:0:4811
+151:1:11
+152:0:4811
+153:2:4030
+154:0:4811
+155:1:12
+156:0:4811
+157:2:4031
+158:0:4811
+159:1:13
+160:0:4811
+161:2:4030
+162:0:4811
+163:1:14
+164:0:4811
+165:2:4031
+166:0:4811
+167:1:15
+168:0:4811
+169:1:16
+170:0:4811
+171:2:4030
+172:0:4811
+173:1:17
+174:0:4811
+175:2:4031
+176:0:4811
+177:1:26
+178:0:4811
+179:2:4030
+180:0:4811
+181:1:30
+182:1:31
+183:1:35
+184:1:39
+185:1:40
+186:1:44
+187:1:52
+188:1:53
+189:1:57
+190:1:61
+191:1:62
+192:1:57
+193:1:61
+194:1:62
+195:1:66
+196:1:73
+197:1:80
+198:1:81
+199:1:88
+200:1:93
+201:1:100
+202:1:101
+203:1:100
+204:1:101
+205:1:108
+206:1:112
+207:0:4811
+208:2:4031
+209:0:4811
+210:1:117
+211:0:4811
+212:2:4032
+213:0:4811
+214:2:4037
+215:0:4811
+216:2:4038
+217:0:4811
+218:2:4046
+219:2:4047
+220:2:4051
+221:2:4055
+222:2:4056
+223:2:4060
+224:2:4068
+225:2:4069
+226:2:4073
+227:2:4077
+228:2:4078
+229:2:4073
+230:2:4077
+231:2:4078
+232:2:4082
+233:2:4089
+234:2:4096
+235:2:4097
+236:2:4104
+237:2:4109
+238:2:4116
+239:2:4117
+240:2:4116
+241:2:4117
+242:2:4124
+243:2:4128
+244:0:4811
+245:2:3239
+246:2:3921
+247:0:4811
+248:2:3049
+249:0:4811
+250:2:3240
+251:0:4811
+252:2:3049
+253:0:4811
+254:2:3243
+255:2:3244
+256:2:3248
+257:2:3249
+258:2:3257
+259:2:3258
+260:2:3262
+261:2:3263
+262:2:3271
+263:2:3276
+264:2:3280
+265:2:3281
+266:2:3289
+267:2:3290
+268:2:3294
+269:2:3295
+270:2:3289
+271:2:3290
+272:2:3294
+273:2:3295
+274:2:3303
+275:2:3308
+276:2:3309
+277:2:3320
+278:2:3321
+279:2:3322
+280:2:3333
+281:2:3338
+282:2:3339
+283:2:3350
+284:2:3351
+285:2:3352
+286:2:3350
+287:2:3351
+288:2:3352
+289:2:3363
+290:2:3370
+291:0:4811
+292:2:3049
+293:0:4811
+294:2:3374
+295:2:3375
+296:2:3376
+297:2:3388
+298:2:3389
+299:2:3393
+300:2:3394
+301:2:3402
+302:2:3407
+303:2:3411
+304:2:3412
+305:2:3420
+306:2:3421
+307:2:3425
+308:2:3426
+309:2:3420
+310:2:3421
+311:2:3425
+312:2:3426
+313:2:3434
+314:2:3439
+315:2:3440
+316:2:3451
+317:2:3452
+318:2:3453
+319:2:3464
+320:2:3469
+321:2:3470
+322:2:3481
+323:2:3482
+324:2:3483
+325:2:3481
+326:2:3482
+327:2:3483
+328:2:3494
+329:2:3505
+330:2:3506
+331:0:4811
+332:2:3049
+333:0:4811
+334:2:3512
+335:2:3513
+336:2:3517
+337:2:3518
+338:2:3526
+339:2:3527
+340:2:3531
+341:2:3532
+342:2:3540
+343:2:3545
+344:2:3549
+345:2:3550
+346:2:3558
+347:2:3559
+348:2:3563
+349:2:3564
+350:2:3558
+351:2:3559
+352:2:3563
+353:2:3564
+354:2:3572
+355:2:3577
+356:2:3578
+357:2:3589
+358:2:3590
+359:2:3591
+360:2:3602
+361:2:3607
+362:2:3608
+363:2:3619
+364:2:3620
+365:2:3621
+366:2:3619
+367:2:3620
+368:2:3621
+369:2:3632
+370:0:4811
+371:2:3049
+372:0:4811
+373:2:3641
+374:2:3642
+375:2:3646
+376:2:3647
+377:2:3655
+378:2:3656
+379:2:3660
+380:2:3661
+381:2:3669
+382:2:3674
+383:2:3678
+384:2:3679
+385:2:3687
+386:2:3688
+387:2:3692
+388:2:3693
+389:2:3687
+390:2:3688
+391:2:3692
+392:2:3693
+393:2:3701
+394:2:3706
+395:2:3707
+396:2:3718
+397:2:3719
+398:2:3720
+399:2:3731
+400:2:3736
+401:2:3737
+402:2:3748
+403:2:3749
+404:2:3750
+405:2:3748
+406:2:3749
+407:2:3750
+408:2:3761
+409:2:3768
+410:0:4811
+411:2:3049
+412:0:4811
+413:2:3772
+414:2:3773
+415:2:3774
+416:2:3786
+417:2:3787
+418:2:3791
+419:2:3792
+420:2:3800
+421:2:3805
+422:2:3809
+423:2:3810
+424:2:3818
+425:2:3819
+426:2:3823
+427:2:3824
+428:2:3818
+429:2:3819
+430:2:3823
+431:2:3824
+432:2:3832
+433:2:3837
+434:2:3838
+435:2:3849
+436:2:3850
+437:2:3851
+438:2:3862
+439:2:3867
+440:2:3868
+441:2:3879
+442:2:3880
+443:2:3881
+444:2:3879
+445:2:3880
+446:2:3881
+447:2:3892
+448:2:3902
+449:2:3903
+450:0:4811
+451:2:3049
+452:0:4811
+453:2:3909
+454:0:4811
+455:2:4534
+456:2:4535
+457:2:4539
+458:2:4543
+459:2:4544
+460:2:4548
+461:2:4556
+462:2:4557
+463:2:4561
+464:2:4565
+465:2:4566
+466:2:4561
+467:2:4565
+468:2:4566
+469:2:4570
+470:2:4577
+471:2:4584
+472:2:4585
+473:2:4592
+474:2:4597
+475:2:4604
+476:2:4605
+477:2:4604
+478:2:4605
+479:2:4612
+480:2:4616
+481:0:4811
+482:2:4621
+483:0:4811
+484:2:4622
+485:0:4811
+486:2:4623
+487:0:4811
+488:2:4624
+489:0:4811
+490:1:26
+491:0:4811
+492:2:4625
+493:0:4811
+494:1:30
+495:1:31
+496:1:35
+497:1:39
+498:1:40
+499:1:44
+500:1:52
+501:1:53
+502:1:57
+503:1:61
+504:1:62
+505:1:57
+506:1:61
+507:1:62
+508:1:66
+509:1:73
+510:1:80
+511:1:81
+512:1:88
+513:1:93
+514:1:100
+515:1:101
+516:1:100
+517:1:101
+518:1:108
+519:1:112
+520:0:4811
+521:2:4624
+522:0:4811
+523:1:117
+524:0:4811
+525:2:4625
+526:0:4811
+527:2:4626
+528:0:4811
+529:2:4631
+530:0:4811
+531:2:4632
+532:0:4811
+533:2:4640
+534:2:4641
+535:2:4645
+536:2:4649
+537:2:4650
+538:2:4654
+539:2:4662
+540:2:4663
+541:2:4667
+542:2:4671
+543:2:4672
+544:2:4667
+545:2:4671
+546:2:4672
+547:2:4676
+548:2:4683
+549:2:4690
+550:2:4691
+551:2:4698
+552:2:4703
+553:2:4710
+554:2:4711
+555:2:4710
+556:2:4711
+557:2:4718
+558:2:4722
+559:0:4811
+560:2:3911
+561:2:3921
+562:0:4811
+563:2:3049
+564:0:4811
+565:2:3912
+566:2:3913
+567:0:4811
+568:2:3049
+569:0:4811
+570:2:3917
+571:0:4811
+572:2:3925
+573:0:4811
+574:2:3046
+575:0:4811
+576:2:3048
+577:0:4811
+578:2:3049
+579:0:4811
+580:2:3050
+581:2:3051
+582:2:3055
+583:2:3056
+584:2:3064
+585:2:3065
+586:2:3069
+587:2:3070
+588:2:3078
+589:2:3083
+590:2:3087
+591:2:3088
+592:2:3096
+593:2:3097
+594:2:3098
+595:2:3096
+596:2:3097
+597:2:3101
+598:2:3102
+599:2:3110
+600:2:3115
+601:2:3116
+602:2:3127
+603:2:3128
+604:2:3129
+605:2:3140
+606:2:3145
+607:2:3146
+608:2:3157
+609:2:3158
+610:2:3159
+611:2:3157
+612:2:3158
+613:2:3159
+614:2:3170
+615:2:3178
+616:0:4811
+617:2:3049
+618:0:4811
+619:2:3182
+620:2:3186
+621:2:3187
+622:2:3191
+623:2:3195
+624:2:3196
+625:2:3200
+626:2:3208
+627:2:3209
+628:2:3213
+629:2:3214
+630:2:3213
+631:2:3217
+632:2:3218
+633:2:3222
+634:0:4811
+635:2:3049
+636:0:4811
+637:2:3230
+638:2:3231
+639:2:3232
+640:0:4811
+641:2:3049
+642:0:4811
+643:2:3237
+644:0:4811
+645:2:3940
+646:2:3941
+647:2:3945
+648:2:3949
+649:2:3950
+650:2:3954
+651:2:3959
+652:2:3967
+653:2:3971
+654:2:3972
+655:2:3967
+656:2:3971
+657:2:3972
+658:2:3976
+659:2:3983
+660:2:3990
+661:2:3991
+662:2:3998
+663:2:4003
+664:2:4010
+665:2:4011
+666:2:4010
+667:2:4011
+668:2:4018
+669:2:4022
+670:0:4811
+671:2:4027
+672:0:4811
+673:2:4028
+674:0:4811
+675:2:4029
+676:0:4811
+677:2:4030
+678:0:4811
+679:1:26
+680:0:4811
+681:2:4031
+682:0:4811
+683:1:30
+684:1:31
+685:1:35
+686:1:39
+687:1:40
+688:1:44
+689:1:52
+690:1:53
+691:1:57
+692:1:61
+693:1:62
+694:1:57
+695:1:61
+696:1:62
+697:1:66
+698:1:73
+699:1:80
+700:1:81
+701:1:88
+702:1:93
+703:1:100
+704:1:101
+705:1:100
+706:1:101
+707:1:108
+708:1:112
+709:0:4811
+710:2:4030
+711:0:4811
+712:1:117
+713:0:4811
+714:2:4031
+715:0:4811
+716:2:4032
+717:0:4811
+718:2:4037
+719:0:4811
+720:2:4038
+721:0:4811
+722:2:4046
+723:2:4047
+724:2:4051
+725:2:4055
+726:2:4056
+727:2:4060
+728:2:4068
+729:2:4069
+730:2:4073
+731:2:4077
+732:2:4078
+733:2:4073
+734:2:4077
+735:2:4078
+736:2:4082
+737:2:4089
+738:2:4096
+739:2:4097
+740:2:4104
+741:2:4109
+742:2:4116
+743:2:4117
+744:2:4116
+745:2:4117
+746:2:4124
+747:2:4128
+748:0:4811
+749:2:3239
+750:2:3921
+751:0:4811
+752:2:3049
+753:0:4811
+754:2:3240
+755:0:4811
+756:2:3049
+757:0:4811
+758:2:3243
+759:2:3244
+760:2:3248
+761:2:3249
+762:2:3257
+763:2:3258
+764:2:3262
+765:2:3263
+766:2:3271
+767:2:3276
+768:2:3280
+769:2:3281
+770:2:3289
+771:2:3290
+772:2:3294
+773:2:3295
+774:2:3289
+775:2:3290
+776:2:3294
+777:2:3295
+778:2:3303
+779:2:3308
+780:2:3309
+781:2:3320
+782:2:3321
+783:2:3322
+784:2:3333
+785:2:3338
+786:2:3339
+787:2:3350
+788:2:3351
+789:2:3352
+790:2:3350
+791:2:3351
+792:2:3352
+793:2:3363
+794:2:3370
+795:0:4811
+796:2:3049
+797:0:4811
+798:2:3374
+799:2:3375
+800:2:3376
+801:2:3388
+802:2:3389
+803:2:3393
+804:2:3394
+805:2:3402
+806:2:3407
+807:2:3411
+808:2:3412
+809:2:3420
+810:2:3421
+811:2:3425
+812:2:3426
+813:2:3420
+814:2:3421
+815:2:3425
+816:2:3426
+817:2:3434
+818:2:3439
+819:2:3440
+820:2:3451
+821:2:3452
+822:2:3453
+823:2:3464
+824:2:3469
+825:2:3470
+826:2:3481
+827:2:3482
+828:2:3483
+829:2:3481
+830:2:3482
+831:2:3483
+832:2:3494
+833:2:3505
+834:2:3506
+835:0:4811
+836:2:3049
+837:0:4811
+838:2:3512
+839:2:3513
+840:2:3517
+841:2:3518
+842:2:3526
+843:2:3527
+844:2:3531
+845:2:3532
+846:2:3540
+847:2:3545
+848:2:3549
+849:2:3550
+850:2:3558
+851:2:3559
+852:2:3563
+853:2:3564
+854:2:3558
+855:2:3559
+856:2:3563
+857:2:3564
+858:2:3572
+859:2:3577
+860:2:3578
+861:2:3589
+862:2:3590
+863:2:3591
+864:2:3602
+865:2:3607
+866:2:3608
+867:2:3619
+868:2:3620
+869:2:3621
+870:2:3619
+871:2:3620
+872:2:3621
+873:2:3632
+874:0:4811
+875:2:3049
+876:0:4811
+877:2:3641
+878:2:3642
+879:2:3646
+880:2:3647
+881:2:3655
+882:2:3656
+883:2:3660
+884:2:3661
+885:2:3669
+886:2:3674
+887:2:3678
+888:2:3679
+889:2:3687
+890:2:3688
+891:2:3692
+892:2:3693
+893:2:3687
+894:2:3688
+895:2:3692
+896:2:3693
+897:2:3701
+898:2:3706
+899:2:3707
+900:2:3718
+901:2:3719
+902:2:3720
+903:2:3731
+904:2:3736
+905:2:3737
+906:2:3748
+907:2:3749
+908:2:3750
+909:2:3748
+910:2:3749
+911:2:3750
+912:2:3761
+913:2:3768
+914:0:4811
+915:2:3049
+916:0:4811
+917:2:3772
+918:2:3773
+919:2:3774
+920:2:3786
+921:2:3787
+922:2:3791
+923:2:3792
+924:2:3800
+925:2:3805
+926:2:3809
+927:2:3810
+928:2:3818
+929:2:3819
+930:2:3823
+931:2:3824
+932:2:3818
+933:2:3819
+934:2:3823
+935:2:3824
+936:2:3832
+937:2:3837
+938:2:3838
+939:2:3849
+940:2:3850
+941:2:3851
+942:2:3862
+943:2:3867
+944:2:3868
+945:2:3879
+946:2:3880
+947:2:3881
+948:2:3879
+949:2:3880
+950:2:3881
+951:2:3892
+952:2:3902
+953:2:3903
+954:0:4811
+955:2:3049
+956:0:4811
+957:2:3909
+958:0:4811
+959:2:4534
+960:2:4535
+961:2:4539
+962:2:4543
+963:2:4544
+964:2:4548
+965:2:4556
+966:2:4557
+967:2:4561
+968:2:4565
+969:2:4566
+970:2:4561
+971:2:4565
+972:2:4566
+973:2:4570
+974:2:4577
+975:2:4584
+976:2:4585
+977:2:4592
+978:2:4597
+979:2:4604
+980:2:4605
+981:2:4604
+982:2:4605
+983:2:4612
+984:2:4616
+985:0:4811
+986:2:4621
+987:0:4811
+988:2:4622
+989:0:4811
+990:2:4623
+991:0:4811
+992:2:4624
+993:0:4811
+994:1:26
+995:0:4811
+996:2:4625
+997:0:4811
+998:1:30
+999:1:31
+1000:1:35
+1001:1:39
+1002:1:40
+1003:1:44
+1004:1:52
+1005:1:53
+1006:1:57
+1007:1:61
+1008:1:62
+1009:1:57
+1010:1:61
+1011:1:62
+1012:1:66
+1013:1:73
+1014:1:80
+1015:1:81
+1016:1:88
+1017:1:93
+1018:1:100
+1019:1:101
+1020:1:100
+1021:1:101
+1022:1:108
+1023:1:112
+1024:0:4811
+1025:2:4624
+1026:0:4811
+1027:1:117
+1028:0:4811
+1029:2:4625
+1030:0:4811
+1031:2:4626
+1032:0:4811
+1033:2:4631
+1034:0:4811
+1035:2:4632
+1036:0:4811
+1037:2:4640
+1038:2:4641
+1039:2:4645
+1040:2:4649
+1041:2:4650
+1042:2:4654
+1043:2:4662
+1044:2:4663
+1045:2:4667
+1046:2:4671
+1047:2:4672
+1048:2:4667
+1049:2:4671
+1050:2:4672
+1051:2:4676
+1052:2:4683
+1053:2:4690
+1054:2:4691
+1055:2:4698
+1056:2:4703
+1057:2:4710
+1058:2:4711
+1059:2:4710
+1060:2:4711
+1061:2:4718
+1062:2:4722
+1063:0:4811
+1064:2:3911
+1065:2:3921
+1066:0:4811
+1067:2:3049
+1068:0:4811
+1069:2:3912
+1070:2:3913
+1071:0:4811
+1072:2:3049
+1073:0:4811
+1074:2:3917
+1075:0:4811
+1076:2:3925
+1077:0:4811
+1078:2:3046
+1079:0:4811
+1080:2:3048
+1081:0:4811
+1082:2:3049
+1083:0:4811
+1084:2:3050
+1085:2:3051
+1086:2:3055
+1087:2:3056
+1088:2:3064
+1089:2:3065
+1090:2:3069
+1091:2:3070
+1092:2:3078
+1093:2:3083
+1094:2:3087
+1095:2:3088
+1096:2:3096
+1097:2:3097
+1098:2:3101
+1099:2:3102
+1100:2:3096
+1101:2:3097
+1102:2:3098
+1103:2:3110
+1104:2:3115
+1105:2:3116
+1106:2:3127
+1107:2:3128
+1108:2:3129
+1109:2:3140
+1110:2:3145
+1111:2:3146
+1112:2:3157
+1113:2:3158
+1114:2:3159
+1115:2:3157
+1116:2:3158
+1117:2:3159
+1118:2:3170
+1119:2:3178
+1120:0:4811
+1121:2:3049
+1122:0:4811
+1123:1:118
+1124:0:4811
+1125:1:120
+1126:0:4811
+1127:1:19
+1128:0:4811
+1129:1:126
+1130:1:127
+1131:1:131
+1132:1:132
+1133:1:140
+1134:1:141
+1135:1:145
+1136:1:146
+1137:1:154
+1138:1:159
+1139:1:163
+1140:1:164
+1141:1:172
+1142:1:173
+1143:1:177
+1144:1:178
+1145:1:172
+1146:1:173
+1147:1:177
+1148:1:178
+1149:1:186
+1150:1:191
+1151:1:192
+1152:1:203
+1153:1:204
+1154:1:205
+1155:1:216
+1156:1:221
+1157:1:222
+1158:1:233
+1159:1:234
+1160:1:235
+1161:1:233
+1162:1:234
+1163:1:235
+1164:1:246
+1165:0:4811
+1166:1:15
+1167:0:4811
+1168:1:16
+1169:0:4811
+1170:2:3182
+1171:2:3186
+1172:2:3187
+1173:2:3191
+1174:2:3195
+1175:2:3196
+1176:2:3200
+1177:2:3208
+1178:2:3209
+1179:2:3213
+1180:2:3217
+1181:2:3218
+1182:2:3213
+1183:2:3214
+1184:2:3222
+1185:0:4811
+1186:2:3049
+1187:0:4811
+1188:2:3230
+1189:2:3231
+1190:2:3232
+1191:0:4811
+1192:2:3049
+1193:0:4811
+1194:2:3237
+1195:0:4811
+1196:2:3940
+1197:2:3941
+1198:2:3945
+1199:2:3949
+1200:2:3950
+1201:2:3954
+1202:2:3959
+1203:2:3967
+1204:2:3971
+1205:2:3972
+1206:2:3967
+1207:2:3971
+1208:2:3972
+1209:2:3976
+1210:2:3983
+1211:2:3990
+1212:2:3991
+1213:2:3998
+1214:2:4003
+1215:2:4010
+1216:2:4011
+1217:2:4010
+1218:2:4011
+1219:2:4018
+1220:2:4022
+1221:0:4811
+1222:2:4027
+1223:0:4811
+1224:2:4028
+1225:0:4811
+1226:2:4029
+1227:0:4811
+1228:2:4030
+1229:0:4811
+1230:1:17
+1231:0:4811
+1232:2:4031
+1233:0:4811
+1234:1:118
+1235:0:4811
+1236:1:120
+1237:0:4811
+1238:2:4030
+1239:0:4811
+1240:1:19
+1241:0:4811
+1242:2:4031
+1243:0:4811
+1244:1:255
+1245:1:256
+1246:0:4811
+1247:1:15
+1248:0:4811
+1249:1:16
+1250:0:4811
+1251:2:4030
+1252:0:4811
+1253:1:17
+1254:0:4811
+1255:2:4031
+1256:0:4811
+1257:1:118
+1258:0:4811
+1259:1:120
+1260:0:4811
+1261:2:4030
+1262:0:4811
+1263:1:19
+1264:0:4811
+1265:2:4031
+1266:0:4811
+1267:1:262
+1268:1:263
+1269:1:267
+1270:1:268
+1271:1:276
+1272:1:277
+1273:1:281
+1274:1:282
+1275:1:290
+1276:1:295
+1277:1:299
+1278:1:300
+1279:1:308
+1280:1:309
+1281:1:313
+1282:1:314
+1283:1:308
+1284:1:309
+1285:1:313
+1286:1:314
+1287:1:322
+1288:1:327
+1289:1:328
+1290:1:339
+1291:1:340
+1292:1:341
+1293:1:352
+1294:1:357
+1295:1:358
+1296:1:369
+1297:1:370
+1298:1:371
+1299:1:369
+1300:1:377
+1301:1:378
+1302:1:382
+1303:0:4811
+1304:1:15
+1305:0:4811
+1306:1:16
+1307:0:4811
+1308:2:4030
+1309:0:4811
+1310:1:17
+1311:0:4811
+1312:2:4031
+1313:0:4811
+1314:1:118
+1315:0:4811
+1316:1:120
+1317:0:4811
+1318:2:4030
+1319:0:4811
+1320:1:19
+1321:0:4811
+1322:2:4031
+1323:0:4811
+1324:1:391
+1325:1:392
+1326:1:396
+1327:1:397
+1328:1:405
+1329:1:406
+1330:1:410
+1331:1:411
+1332:1:419
+1333:1:424
+1334:1:428
+1335:1:429
+1336:1:437
+1337:1:438
+1338:1:442
+1339:1:443
+1340:1:437
+1341:1:438
+1342:1:442
+1343:1:443
+1344:1:451
+1345:1:456
+1346:1:457
+1347:1:468
+1348:1:469
+1349:1:470
+1350:1:481
+1351:1:486
+1352:1:487
+1353:1:498
+1354:1:499
+1355:1:500
+1356:1:498
+1357:1:506
+1358:1:507
+1359:1:511
+1360:1:518
+1361:0:4811
+1362:1:15
+1363:0:4811
+1364:1:16
+1365:0:4811
+1366:2:4030
+1367:0:4811
+1368:1:17
+1369:0:4811
+1370:2:4031
+1371:0:4811
+1372:1:118
+1373:0:4811
+1374:1:120
+1375:0:4811
+1376:2:4030
+1377:0:4811
+1378:1:19
+1379:0:4811
+1380:2:4031
+1381:0:4811
+1382:1:656
+1383:1:657
+1384:1:661
+1385:1:662
+1386:1:670
+1387:1:671
+1388:1:672
+1389:1:684
+1390:1:689
+1391:1:693
+1392:1:694
+1393:1:702
+1394:1:703
+1395:1:707
+1396:1:708
+1397:1:702
+1398:1:703
+1399:1:707
+1400:1:708
+1401:1:716
+1402:1:721
+1403:1:722
+1404:1:733
+1405:1:734
+1406:1:735
+1407:1:746
+1408:1:751
+1409:1:752
+1410:1:763
+1411:1:764
+1412:1:765
+1413:1:763
+1414:1:771
+1415:1:772
+1416:1:776
+1417:0:4811
+1418:1:15
+1419:0:4811
+1420:1:16
+1421:0:4811
+1422:2:4030
+1423:0:4811
+1424:1:17
+1425:0:4811
+1426:2:4031
+1427:0:4811
+1428:1:118
+1429:0:4811
+1430:1:120
+1431:0:4811
+1432:2:4030
+1433:0:4811
+1434:1:19
+1435:0:4811
+1436:2:4031
+1437:0:4811
+1438:1:785
+1439:1:788
+1440:1:789
+1441:0:4811
+1442:1:15
+1443:0:4811
+1444:1:16
+1445:0:4811
+1446:2:4030
+1447:0:4811
+1448:1:17
+1449:0:4811
+1450:2:4031
+1451:0:4811
+1452:1:118
+1453:0:4811
+1454:1:120
+1455:0:4811
+1456:2:4030
+1457:0:4811
+1458:1:19
+1459:0:4811
+1460:2:4031
+1461:0:4811
+1462:1:1052
+1463:1:1053
+1464:1:1057
+1465:1:1058
+1466:1:1066
+1467:1:1067
+1468:1:1071
+1469:1:1072
+1470:1:1080
+1471:1:1085
+1472:1:1089
+1473:1:1090
+1474:1:1098
+1475:1:1099
+1476:1:1103
+1477:1:1104
+1478:1:1098
+1479:1:1099
+1480:1:1103
+1481:1:1104
+1482:1:1112
+1483:1:1117
+1484:1:1118
+1485:1:1129
+1486:1:1130
+1487:1:1131
+1488:1:1142
+1489:1:1147
+1490:1:1148
+1491:1:1159
+1492:1:1160
+1493:1:1161
+1494:1:1159
+1495:1:1167
+1496:1:1168
+1497:1:1172
+1498:1:1179
+1499:1:1183
+1500:0:4811
+1501:1:15
+1502:0:4811
+1503:1:16
+1504:0:4811
+1505:2:4030
+1506:0:4811
+1507:1:17
+1508:0:4811
+1509:2:4031
+1510:0:4811
+1511:1:118
+1512:0:4811
+1513:1:120
+1514:0:4811
+1515:2:4030
+1516:0:4811
+1517:1:19
+1518:0:4811
+1519:2:4031
+1520:0:4811
+1521:1:1184
+1522:1:1185
+1523:1:1189
+1524:1:1190
+1525:1:1198
+1526:1:1199
+1527:1:1200
+1528:1:1212
+1529:1:1217
+1530:1:1221
+1531:1:1222
+1532:1:1230
+1533:1:1231
+1534:1:1235
+1535:1:1236
+1536:1:1230
+1537:1:1231
+1538:1:1235
+1539:1:1236
+1540:1:1244
+1541:1:1249
+1542:1:1250
+1543:1:1261
+1544:1:1262
+1545:1:1263
+1546:1:1274
+1547:1:1279
+1548:1:1280
+1549:1:1291
+1550:1:1292
+1551:1:1293
+1552:1:1291
+1553:1:1299
+1554:1:1300
+1555:1:1304
+1556:0:4811
+1557:1:15
+1558:0:4811
+1559:1:16
+1560:0:4811
+1561:2:4030
+1562:0:4811
+1563:1:17
+1564:0:4811
+1565:2:4031
+1566:0:4811
+1567:1:118
+1568:0:4811
+1569:1:120
+1570:0:4811
+1571:2:4030
+1572:0:4811
+1573:1:19
+1574:0:4811
+1575:2:4031
+1576:0:4811
+1577:1:1313
+1578:0:4811
+1579:2:4030
+1580:0:4811
+1581:1:2777
+1582:1:2781
+1583:1:2782
+1584:1:2790
+1585:1:2791
+1586:1:2795
+1587:1:2796
+1588:1:2804
+1589:1:2809
+1590:1:2813
+1591:1:2814
+1592:1:2822
+1593:1:2823
+1594:1:2827
+1595:1:2828
+1596:1:2822
+1597:1:2823
+1598:1:2827
+1599:1:2828
+1600:1:2836
+1601:1:2841
+1602:1:2842
+1603:1:2853
+1604:1:2854
+1605:1:2855
+1606:1:2866
+1607:1:2871
+1608:1:2872
+1609:1:2883
+1610:1:2884
+1611:1:2885
+1612:1:2883
+1613:1:2891
+1614:1:2892
+1615:1:2896
+1616:1:2900
+1617:0:4811
+1618:2:4031
+1619:0:4811
+1620:1:1315
+1621:1:1316
+1622:0:4809
+1623:1:15
+1624:0:4815
+1625:1:120
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_free_no_wmb.define b/formal-model/results/urcu-controldataflow-ipi/urcu_free_no_wmb.define
new file mode 100644 (file)
index 0000000..710f29d
--- /dev/null
@@ -0,0 +1 @@
+#define NO_WMB
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_free_no_wmb.log b/formal-model/results/urcu-controldataflow-ipi/urcu_free_no_wmb.log
new file mode 100644 (file)
index 0000000..c8da68c
--- /dev/null
@@ -0,0 +1,560 @@
+rm -f pan* trail.out .input.spin* *.spin.trail .input.define
+touch .input.define
+cat .input.define >> pan.ltl
+cat DEFINES >> pan.ltl
+spin -f "!(`cat urcu_free.ltl | grep -v ^//`)" >> pan.ltl
+cp urcu_free_no_wmb.define .input.define
+cat .input.define > .input.spin
+cat DEFINES >> .input.spin
+cat urcu.spin >> .input.spin
+rm -f .input.spin.trail
+spin -a -X -N pan.ltl .input.spin
+Exit-Status 0
+gcc -O2 -w -DHASH64 -o pan pan.c
+./pan -a -v -c1 -X -m10000000 -w20
+warning: for p.o. reduction to be valid the never claim must be stutter-invariant
+(never claims generated from LTL formulae are stutter-invariant)
+depth 0: Claim reached state 5 (line 1258)
+Depth=    7141 States=    1e+06 Transitions= 1.25e+08 Memory=   550.432        t=    155 R=   6e+03
+Depth=    7141 States=    2e+06 Transitions= 4.09e+08 Memory=   634.318        t=    526 R=   4e+03
+Depth=    7141 States=    3e+06 Transitions= 5.78e+08 Memory=   718.303        t=    751 R=   4e+03
+pan: resizing hashtable to -w22..  done
+Depth=    7141 States=    4e+06 Transitions= 8.27e+08 Memory=   833.311        t= 1.07e+03 R=   4e+03
+Depth=    7141 States=    5e+06 Transitions= 1.08e+09 Memory=   917.295        t= 1.39e+03 R=   4e+03
+Depth=    7141 States=    6e+06 Transitions= 1.57e+09 Memory=  1001.279        t= 2.04e+03 R=   3e+03
+Depth=    7141 States=    7e+06 Transitions= 1.97e+09 Memory=  1085.264        t= 2.58e+03 R=   3e+03
+Depth=    7141 States=    8e+06 Transitions= 2.31e+09 Memory=  1169.151        t= 3.03e+03 R=   3e+03
+Depth=    7141 States=    9e+06 Transitions= 2.62e+09 Memory=  1253.135        t= 3.44e+03 R=   3e+03
+pan: resizing hashtable to -w24..  done
+Depth=    7141 States=    1e+07 Transitions= 2.83e+09 Memory=  1461.115        t= 3.72e+03 R=   3e+03
+Depth=    7141 States=  1.1e+07 Transitions= 3.05e+09 Memory=  1545.100        t= 3.99e+03 R=   3e+03
+Depth=    7141 States=  1.2e+07 Transitions= 3.25e+09 Memory=  1629.084        t= 4.25e+03 R=   3e+03
+Depth=    7141 States=  1.3e+07 Transitions= 3.55e+09 Memory=  1713.068        t= 4.64e+03 R=   3e+03
+Depth=    7141 States=  1.4e+07 Transitions= 3.84e+09 Memory=  1797.053        t= 5.01e+03 R=   3e+03
+Depth=    7141 States=  1.5e+07 Transitions= 3.96e+09 Memory=  1881.037        t= 5.17e+03 R=   3e+03
+pan: claim violated! (at depth 1482)
+pan: wrote .input.spin.trail
+
+(Spin Version 5.1.7 -- 23 December 2008)
+Warning: Search not completed
+       + Partial Order Reduction
+
+Full statespace search for:
+       never claim             +
+       assertion violations    + (if within scope of claim)
+       acceptance   cycles     + (fairness disabled)
+       invalid end states      - (disabled by never claim)
+
+State-vector 88 byte, depth reached 7141, errors: 1
+ 15755160 states, stored
+4.1726493e+09 states, matched
+4.1884045e+09 transitions (= stored+matched)
+2.431858e+10 atomic steps
+hash conflicts: 2.849112e+09 (resolved)
+
+Stats on memory usage (in Megabytes):
+ 1742.934      equivalent memory usage for states (stored*(State-vector + overhead))
+ 1359.449      actual memory usage for states (compression: 78.00%)
+               state-vector as stored = 62 byte + 28 byte overhead
+  128.000      memory used for hash table (-w24)
+  457.764      memory used for DFS stack (-m10000000)
+ 1944.416      total actual memory usage
+
+unreached in proctype urcu_reader
+       line 250, "pan.___", state 30, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 52, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 61, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 77, "(1)"
+       line 231, "pan.___", state 85, "(1)"
+       line 235, "pan.___", state 97, "(1)"
+       line 239, "pan.___", state 105, "(1)"
+       line 395, "pan.___", state 131, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 163, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 177, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 196, "(1)"
+       line 421, "pan.___", state 226, "(1)"
+       line 425, "pan.___", state 239, "(1)"
+       line 670, "pan.___", state 260, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<1))"
+       line 395, "pan.___", state 267, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 299, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 313, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 332, "(1)"
+       line 421, "pan.___", state 362, "(1)"
+       line 425, "pan.___", state 375, "(1)"
+       line 395, "pan.___", state 396, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 428, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 442, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 461, "(1)"
+       line 421, "pan.___", state 491, "(1)"
+       line 425, "pan.___", state 504, "(1)"
+       line 395, "pan.___", state 527, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 529, "(1)"
+       line 395, "pan.___", state 530, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 530, "else"
+       line 395, "pan.___", state 533, "(1)"
+       line 399, "pan.___", state 541, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 543, "(1)"
+       line 399, "pan.___", state 544, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 544, "else"
+       line 399, "pan.___", state 547, "(1)"
+       line 399, "pan.___", state 548, "(1)"
+       line 399, "pan.___", state 548, "(1)"
+       line 397, "pan.___", state 553, "((i<1))"
+       line 397, "pan.___", state 553, "((i>=1))"
+       line 404, "pan.___", state 559, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 561, "(1)"
+       line 404, "pan.___", state 562, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 562, "else"
+       line 404, "pan.___", state 565, "(1)"
+       line 404, "pan.___", state 566, "(1)"
+       line 404, "pan.___", state 566, "(1)"
+       line 408, "pan.___", state 573, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 575, "(1)"
+       line 408, "pan.___", state 576, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 576, "else"
+       line 408, "pan.___", state 579, "(1)"
+       line 408, "pan.___", state 580, "(1)"
+       line 408, "pan.___", state 580, "(1)"
+       line 406, "pan.___", state 585, "((i<2))"
+       line 406, "pan.___", state 585, "((i>=2))"
+       line 412, "pan.___", state 592, "(1)"
+       line 412, "pan.___", state 593, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 593, "else"
+       line 412, "pan.___", state 596, "(1)"
+       line 412, "pan.___", state 597, "(1)"
+       line 412, "pan.___", state 597, "(1)"
+       line 416, "pan.___", state 605, "(1)"
+       line 416, "pan.___", state 606, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 606, "else"
+       line 416, "pan.___", state 609, "(1)"
+       line 416, "pan.___", state 610, "(1)"
+       line 416, "pan.___", state 610, "(1)"
+       line 414, "pan.___", state 615, "((i<1))"
+       line 414, "pan.___", state 615, "((i>=1))"
+       line 421, "pan.___", state 622, "(1)"
+       line 421, "pan.___", state 623, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 623, "else"
+       line 421, "pan.___", state 626, "(1)"
+       line 421, "pan.___", state 627, "(1)"
+       line 421, "pan.___", state 627, "(1)"
+       line 425, "pan.___", state 635, "(1)"
+       line 425, "pan.___", state 636, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 636, "else"
+       line 425, "pan.___", state 639, "(1)"
+       line 425, "pan.___", state 640, "(1)"
+       line 425, "pan.___", state 640, "(1)"
+       line 423, "pan.___", state 645, "((i<2))"
+       line 423, "pan.___", state 645, "((i>=2))"
+       line 430, "pan.___", state 649, "(1)"
+       line 430, "pan.___", state 649, "(1)"
+       line 670, "pan.___", state 652, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 670, "pan.___", state 653, "_proc_urcu_reader = (_proc_urcu_reader|(1<<5))"
+       line 670, "pan.___", state 654, "(1)"
+       line 395, "pan.___", state 661, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 693, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 707, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 726, "(1)"
+       line 421, "pan.___", state 756, "(1)"
+       line 425, "pan.___", state 769, "(1)"
+       line 395, "pan.___", state 797, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 799, "(1)"
+       line 395, "pan.___", state 800, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 800, "else"
+       line 395, "pan.___", state 803, "(1)"
+       line 399, "pan.___", state 811, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 813, "(1)"
+       line 399, "pan.___", state 814, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 814, "else"
+       line 399, "pan.___", state 817, "(1)"
+       line 399, "pan.___", state 818, "(1)"
+       line 399, "pan.___", state 818, "(1)"
+       line 397, "pan.___", state 823, "((i<1))"
+       line 397, "pan.___", state 823, "((i>=1))"
+       line 404, "pan.___", state 829, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 831, "(1)"
+       line 404, "pan.___", state 832, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 832, "else"
+       line 404, "pan.___", state 835, "(1)"
+       line 404, "pan.___", state 836, "(1)"
+       line 404, "pan.___", state 836, "(1)"
+       line 408, "pan.___", state 843, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 845, "(1)"
+       line 408, "pan.___", state 846, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 846, "else"
+       line 408, "pan.___", state 849, "(1)"
+       line 408, "pan.___", state 850, "(1)"
+       line 408, "pan.___", state 850, "(1)"
+       line 406, "pan.___", state 855, "((i<2))"
+       line 406, "pan.___", state 855, "((i>=2))"
+       line 412, "pan.___", state 862, "(1)"
+       line 412, "pan.___", state 863, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 863, "else"
+       line 412, "pan.___", state 866, "(1)"
+       line 412, "pan.___", state 867, "(1)"
+       line 412, "pan.___", state 867, "(1)"
+       line 416, "pan.___", state 875, "(1)"
+       line 416, "pan.___", state 876, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 876, "else"
+       line 416, "pan.___", state 879, "(1)"
+       line 416, "pan.___", state 880, "(1)"
+       line 416, "pan.___", state 880, "(1)"
+       line 414, "pan.___", state 885, "((i<1))"
+       line 414, "pan.___", state 885, "((i>=1))"
+       line 421, "pan.___", state 892, "(1)"
+       line 421, "pan.___", state 893, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 893, "else"
+       line 421, "pan.___", state 896, "(1)"
+       line 421, "pan.___", state 897, "(1)"
+       line 421, "pan.___", state 897, "(1)"
+       line 425, "pan.___", state 905, "(1)"
+       line 425, "pan.___", state 906, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 906, "else"
+       line 425, "pan.___", state 909, "(1)"
+       line 425, "pan.___", state 910, "(1)"
+       line 425, "pan.___", state 910, "(1)"
+       line 430, "pan.___", state 919, "(1)"
+       line 430, "pan.___", state 919, "(1)"
+       line 395, "pan.___", state 926, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 928, "(1)"
+       line 395, "pan.___", state 929, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 929, "else"
+       line 395, "pan.___", state 932, "(1)"
+       line 399, "pan.___", state 940, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 942, "(1)"
+       line 399, "pan.___", state 943, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 943, "else"
+       line 399, "pan.___", state 946, "(1)"
+       line 399, "pan.___", state 947, "(1)"
+       line 399, "pan.___", state 947, "(1)"
+       line 397, "pan.___", state 952, "((i<1))"
+       line 397, "pan.___", state 952, "((i>=1))"
+       line 404, "pan.___", state 958, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 960, "(1)"
+       line 404, "pan.___", state 961, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 961, "else"
+       line 404, "pan.___", state 964, "(1)"
+       line 404, "pan.___", state 965, "(1)"
+       line 404, "pan.___", state 965, "(1)"
+       line 408, "pan.___", state 972, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 974, "(1)"
+       line 408, "pan.___", state 975, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 975, "else"
+       line 408, "pan.___", state 978, "(1)"
+       line 408, "pan.___", state 979, "(1)"
+       line 408, "pan.___", state 979, "(1)"
+       line 406, "pan.___", state 984, "((i<2))"
+       line 406, "pan.___", state 984, "((i>=2))"
+       line 412, "pan.___", state 991, "(1)"
+       line 412, "pan.___", state 992, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 992, "else"
+       line 412, "pan.___", state 995, "(1)"
+       line 412, "pan.___", state 996, "(1)"
+       line 412, "pan.___", state 996, "(1)"
+       line 416, "pan.___", state 1004, "(1)"
+       line 416, "pan.___", state 1005, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 1005, "else"
+       line 416, "pan.___", state 1008, "(1)"
+       line 416, "pan.___", state 1009, "(1)"
+       line 416, "pan.___", state 1009, "(1)"
+       line 414, "pan.___", state 1014, "((i<1))"
+       line 414, "pan.___", state 1014, "((i>=1))"
+       line 421, "pan.___", state 1021, "(1)"
+       line 421, "pan.___", state 1022, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 1022, "else"
+       line 421, "pan.___", state 1025, "(1)"
+       line 421, "pan.___", state 1026, "(1)"
+       line 421, "pan.___", state 1026, "(1)"
+       line 425, "pan.___", state 1034, "(1)"
+       line 425, "pan.___", state 1035, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 1035, "else"
+       line 425, "pan.___", state 1038, "(1)"
+       line 425, "pan.___", state 1039, "(1)"
+       line 425, "pan.___", state 1039, "(1)"
+       line 423, "pan.___", state 1044, "((i<2))"
+       line 423, "pan.___", state 1044, "((i>=2))"
+       line 430, "pan.___", state 1048, "(1)"
+       line 430, "pan.___", state 1048, "(1)"
+       line 678, "pan.___", state 1052, "_proc_urcu_reader = (_proc_urcu_reader|(1<<11))"
+       line 395, "pan.___", state 1057, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1089, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1103, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1122, "(1)"
+       line 421, "pan.___", state 1152, "(1)"
+       line 425, "pan.___", state 1165, "(1)"
+       line 395, "pan.___", state 1189, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1221, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1235, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1254, "(1)"
+       line 421, "pan.___", state 1284, "(1)"
+       line 425, "pan.___", state 1297, "(1)"
+       line 395, "pan.___", state 1322, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1354, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1368, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1387, "(1)"
+       line 421, "pan.___", state 1417, "(1)"
+       line 425, "pan.___", state 1430, "(1)"
+       line 395, "pan.___", state 1451, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1483, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1497, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1516, "(1)"
+       line 421, "pan.___", state 1546, "(1)"
+       line 425, "pan.___", state 1559, "(1)"
+       line 395, "pan.___", state 1585, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1617, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1631, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1650, "(1)"
+       line 421, "pan.___", state 1680, "(1)"
+       line 425, "pan.___", state 1693, "(1)"
+       line 395, "pan.___", state 1714, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1746, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1760, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1779, "(1)"
+       line 421, "pan.___", state 1809, "(1)"
+       line 425, "pan.___", state 1822, "(1)"
+       line 395, "pan.___", state 1846, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1878, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1892, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1911, "(1)"
+       line 421, "pan.___", state 1941, "(1)"
+       line 425, "pan.___", state 1954, "(1)"
+       line 717, "pan.___", state 1975, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<19))"
+       line 395, "pan.___", state 1982, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2014, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2028, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2047, "(1)"
+       line 421, "pan.___", state 2077, "(1)"
+       line 425, "pan.___", state 2090, "(1)"
+       line 395, "pan.___", state 2111, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2143, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2157, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2176, "(1)"
+       line 421, "pan.___", state 2206, "(1)"
+       line 425, "pan.___", state 2219, "(1)"
+       line 395, "pan.___", state 2242, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 2244, "(1)"
+       line 395, "pan.___", state 2245, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 2245, "else"
+       line 395, "pan.___", state 2248, "(1)"
+       line 399, "pan.___", state 2256, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 2258, "(1)"
+       line 399, "pan.___", state 2259, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 2259, "else"
+       line 399, "pan.___", state 2262, "(1)"
+       line 399, "pan.___", state 2263, "(1)"
+       line 399, "pan.___", state 2263, "(1)"
+       line 397, "pan.___", state 2268, "((i<1))"
+       line 397, "pan.___", state 2268, "((i>=1))"
+       line 404, "pan.___", state 2274, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2276, "(1)"
+       line 404, "pan.___", state 2277, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 2277, "else"
+       line 404, "pan.___", state 2280, "(1)"
+       line 404, "pan.___", state 2281, "(1)"
+       line 404, "pan.___", state 2281, "(1)"
+       line 408, "pan.___", state 2288, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2290, "(1)"
+       line 408, "pan.___", state 2291, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 2291, "else"
+       line 408, "pan.___", state 2294, "(1)"
+       line 408, "pan.___", state 2295, "(1)"
+       line 408, "pan.___", state 2295, "(1)"
+       line 406, "pan.___", state 2300, "((i<2))"
+       line 406, "pan.___", state 2300, "((i>=2))"
+       line 412, "pan.___", state 2307, "(1)"
+       line 412, "pan.___", state 2308, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 2308, "else"
+       line 412, "pan.___", state 2311, "(1)"
+       line 412, "pan.___", state 2312, "(1)"
+       line 412, "pan.___", state 2312, "(1)"
+       line 416, "pan.___", state 2320, "(1)"
+       line 416, "pan.___", state 2321, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 2321, "else"
+       line 416, "pan.___", state 2324, "(1)"
+       line 416, "pan.___", state 2325, "(1)"
+       line 416, "pan.___", state 2325, "(1)"
+       line 414, "pan.___", state 2330, "((i<1))"
+       line 414, "pan.___", state 2330, "((i>=1))"
+       line 421, "pan.___", state 2337, "(1)"
+       line 421, "pan.___", state 2338, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 2338, "else"
+       line 421, "pan.___", state 2341, "(1)"
+       line 421, "pan.___", state 2342, "(1)"
+       line 421, "pan.___", state 2342, "(1)"
+       line 425, "pan.___", state 2350, "(1)"
+       line 425, "pan.___", state 2351, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 2351, "else"
+       line 425, "pan.___", state 2354, "(1)"
+       line 425, "pan.___", state 2355, "(1)"
+       line 425, "pan.___", state 2355, "(1)"
+       line 423, "pan.___", state 2360, "((i<2))"
+       line 423, "pan.___", state 2360, "((i>=2))"
+       line 430, "pan.___", state 2364, "(1)"
+       line 430, "pan.___", state 2364, "(1)"
+       line 717, "pan.___", state 2367, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 717, "pan.___", state 2368, "_proc_urcu_reader = (_proc_urcu_reader|(1<<23))"
+       line 717, "pan.___", state 2369, "(1)"
+       line 395, "pan.___", state 2376, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2408, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2422, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2441, "(1)"
+       line 421, "pan.___", state 2471, "(1)"
+       line 425, "pan.___", state 2484, "(1)"
+       line 395, "pan.___", state 2511, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2543, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2557, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2576, "(1)"
+       line 421, "pan.___", state 2606, "(1)"
+       line 425, "pan.___", state 2619, "(1)"
+       line 395, "pan.___", state 2640, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2672, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2686, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2705, "(1)"
+       line 421, "pan.___", state 2735, "(1)"
+       line 425, "pan.___", state 2748, "(1)"
+       line 227, "pan.___", state 2781, "(1)"
+       line 235, "pan.___", state 2801, "(1)"
+       line 239, "pan.___", state 2809, "(1)"
+       line 227, "pan.___", state 2824, "(1)"
+       line 235, "pan.___", state 2844, "(1)"
+       line 239, "pan.___", state 2852, "(1)"
+       line 877, "pan.___", state 2869, "-end-"
+       (278 of 2869 states)
+unreached in proctype urcu_writer
+       line 395, "pan.___", state 19, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 33, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 84, "(1)"
+       line 416, "pan.___", state 97, "(1)"
+       line 250, "pan.___", state 150, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 250, "pan.___", state 152, "(1)"
+       line 254, "pan.___", state 159, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 161, "(1)"
+       line 254, "pan.___", state 162, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 254, "pan.___", state 162, "else"
+       line 252, "pan.___", state 167, "((i<1))"
+       line 252, "pan.___", state 167, "((i>=1))"
+       line 258, "pan.___", state 172, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 174, "(1)"
+       line 258, "pan.___", state 175, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 175, "else"
+       line 262, "pan.___", state 181, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 183, "(1)"
+       line 262, "pan.___", state 184, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 262, "pan.___", state 184, "else"
+       line 267, "pan.___", state 193, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 267, "pan.___", state 193, "else"
+       line 395, "pan.___", state 212, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 226, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 244, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 258, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 277, "(1)"
+       line 416, "pan.___", state 290, "(1)"
+       line 421, "pan.___", state 307, "(1)"
+       line 425, "pan.___", state 320, "(1)"
+       line 399, "pan.___", state 357, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 375, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 389, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 421, "(1)"
+       line 421, "pan.___", state 438, "(1)"
+       line 425, "pan.___", state 451, "(1)"
+       line 399, "pan.___", state 495, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 513, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 527, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 559, "(1)"
+       line 421, "pan.___", state 576, "(1)"
+       line 425, "pan.___", state 589, "(1)"
+       line 399, "pan.___", state 624, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 642, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 656, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 688, "(1)"
+       line 421, "pan.___", state 705, "(1)"
+       line 425, "pan.___", state 718, "(1)"
+       line 399, "pan.___", state 755, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 773, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 787, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 819, "(1)"
+       line 421, "pan.___", state 836, "(1)"
+       line 425, "pan.___", state 849, "(1)"
+       line 250, "pan.___", state 904, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 913, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 951, "(1)"
+       line 231, "pan.___", state 959, "(1)"
+       line 235, "pan.___", state 971, "(1)"
+       line 239, "pan.___", state 979, "(1)"
+       line 250, "pan.___", state 1010, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1019, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1032, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1041, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1057, "(1)"
+       line 231, "pan.___", state 1065, "(1)"
+       line 235, "pan.___", state 1077, "(1)"
+       line 239, "pan.___", state 1085, "(1)"
+       line 254, "pan.___", state 1111, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1124, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1133, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1149, "(1)"
+       line 231, "pan.___", state 1157, "(1)"
+       line 235, "pan.___", state 1169, "(1)"
+       line 239, "pan.___", state 1177, "(1)"
+       line 250, "pan.___", state 1208, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1217, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1230, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1239, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1255, "(1)"
+       line 231, "pan.___", state 1263, "(1)"
+       line 235, "pan.___", state 1275, "(1)"
+       line 239, "pan.___", state 1283, "(1)"
+       line 254, "pan.___", state 1309, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1322, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1331, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1347, "(1)"
+       line 231, "pan.___", state 1355, "(1)"
+       line 235, "pan.___", state 1367, "(1)"
+       line 239, "pan.___", state 1375, "(1)"
+       line 250, "pan.___", state 1406, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1415, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1428, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1437, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1453, "(1)"
+       line 231, "pan.___", state 1461, "(1)"
+       line 235, "pan.___", state 1473, "(1)"
+       line 239, "pan.___", state 1481, "(1)"
+       line 254, "pan.___", state 1507, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1520, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1529, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1545, "(1)"
+       line 231, "pan.___", state 1553, "(1)"
+       line 235, "pan.___", state 1565, "(1)"
+       line 239, "pan.___", state 1573, "(1)"
+       line 250, "pan.___", state 1604, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1613, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1626, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1635, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1651, "(1)"
+       line 231, "pan.___", state 1659, "(1)"
+       line 235, "pan.___", state 1671, "(1)"
+       line 239, "pan.___", state 1679, "(1)"
+       line 1204, "pan.___", state 1695, "-end-"
+       (109 of 1695 states)
+unreached in proctype :init:
+       line 1215, "pan.___", state 9, "((j<2))"
+       line 1215, "pan.___", state 9, "((j>=2))"
+       line 1216, "pan.___", state 20, "((j<2))"
+       line 1216, "pan.___", state 20, "((j>=2))"
+       line 1221, "pan.___", state 33, "((j<2))"
+       line 1221, "pan.___", state 33, "((j>=2))"
+       line 1219, "pan.___", state 43, "((i<1))"
+       line 1219, "pan.___", state 43, "((i>=1))"
+       line 1229, "pan.___", state 54, "((j<2))"
+       line 1229, "pan.___", state 54, "((j>=2))"
+       line 1233, "pan.___", state 67, "((j<2))"
+       line 1233, "pan.___", state 67, "((j>=2))"
+       (6 of 78 states)
+unreached in proctype :never:
+       line 1263, "pan.___", state 8, "-end-"
+       (1 of 8 states)
+
+pan: elapsed time 5.46e+03 seconds
+pan: rate 2887.6389 states/second
+pan: avg transition delay 1.3027e-06 usec
+cp .input.spin urcu_free_no_wmb.spin.input
+cp .input.spin.trail urcu_free_no_wmb.spin.input.trail
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_free_no_wmb.spin.input b/formal-model/results/urcu-controldataflow-ipi/urcu_free_no_wmb.spin.input
new file mode 100644 (file)
index 0000000..2ff2df1
--- /dev/null
@@ -0,0 +1,1240 @@
+#define NO_WMB
+
+// Poison value for freed memory
+#define POISON 1
+// Memory with correct data
+#define WINE 0
+#define SLAB_SIZE 2
+
+#define read_poison    (data_read_first[0] == POISON || data_read_second[0] == POISON)
+
+#define RCU_GP_CTR_BIT (1 << 7)
+#define RCU_GP_CTR_NEST_MASK (RCU_GP_CTR_BIT - 1)
+
+//disabled
+#define REMOTE_BARRIERS
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+typedef per_proc_bit {
+       bit val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bitfield {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bitfield cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               /*
+                * 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, j);
+               reader_barrier[get_readerid()] = 0;
+       :: 1 ->
+               /*
+                * 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)
+//#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);                                                           \
+       i = 0;                                                                  \
+       do                                                                      \
+       :: i < NR_READERS ->                                                    \
+               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.                                            \
+                */                                                             \
+               do                                                              \
+               :: (reader_barrier[i] == 1) ->                                  \
+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(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, smp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only one reader */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* RCU data */
+DECLARE_CACHED_VAR(bit, rcu_data[SLAB_SIZE]);
+
+/* RCU pointer */
+#if (SLAB_SIZE == 2)
+DECLARE_CACHED_VAR(bit, rcu_ptr);
+bit ptr_read_first[NR_READERS];
+bit ptr_read_second[NR_READERS];
+#else
+DECLARE_CACHED_VAR(byte, rcu_ptr);
+byte ptr_read_first[NR_READERS];
+byte ptr_read_second[NR_READERS];
+#endif
+
+bit data_read_first[NR_READERS];
+bit data_read_second[NR_READERS];
+
+bit init_done = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               ptr_read_first[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb1;
+rmb1_end:
+                               data_read_first[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_first[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               ptr_read_second[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb2;
+rmb2_end:
+                               data_read_second[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_second[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+rmb1:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb1_end;
+rmb2:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_DATA                     (1 << 1)
+#define WRITE_PROC_WMB                 (1 << 2)
+#define WRITE_XCHG_PTR                 (1 << 3)
+
+#define WRITE_PROC_FIRST_MB            (1 << 4)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 5)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 6)
+#define WRITE_PROC_FIRST_WAIT          (1 << 7)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 8)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 9)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 10)
+#define WRITE_PROC_SECOND_WAIT         (1 << 11)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 12)
+
+#define WRITE_PROC_SECOND_MB           (1 << 13)
+
+#define WRITE_FREE                     (1 << 14)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_DATA                    \
+                                       | WRITE_PROC_WMB                \
+                                       | WRITE_XCHG_PTR                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB          \
+                                       | WRITE_FREE)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 15) - 1)
+
+/*
+ * Mutexes are implied around writer execution. A single writer at a time.
+ */
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte cur_data = 0, old_data, loop_nr = 0;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (loop_nr < 3) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               loop_nr = loop_nr + 1;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_WMB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+#endif
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_DATA) ->
+                       ooo_mem(i);
+                       cur_data = (cur_data + 1) % SLAB_SIZE;
+                       WRITE_CACHED_VAR(rcu_data[cur_data], WINE);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_DATA);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA,
+                                 WRITE_PROC_WMB) ->
+                       smp_wmb(i, j);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_WMB,
+                                 WRITE_XCHG_PTR) ->
+                       /* rcu_xchg_pointer() */
+                       atomic {
+                               old_data = READ_CACHED_VAR(rcu_ptr);
+                               WRITE_CACHED_VAR(rcu_ptr, cur_data);
+                       }
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_XCHG_PTR);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_WMB      /* No dependency on
+                                                        * WRITE_DATA because we
+                                                        * write to a
+                                                        * different location. */
+                                 | WRITE_PROC_SECOND_MB
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_FREE) ->
+                       WRITE_CACHED_VAR(rcu_data[old_data], POISON);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_FREE);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+               /*
+                * Note : Promela model adds implicit serialization of the
+                * WRITE_FREE instruction. Normally, it would be permitted to
+                * spill on the next loop execution. Given the validation we do
+                * checks for the data entry read to be poisoned, it's ok if
+                * we do not check "late arriving" memory poisoning.
+                */
+       :: 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
+#ifdef READER_PROGRESS
+               /*
+                * Make sure we don't block the reader's progress.
+                */
+               smp_mb_send(i, j, 5);
+#endif
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(rcu_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       ptr_read_first[i] = 1;
+                       ptr_read_second[i] = 1;
+                       data_read_first[i] = WINE;
+                       data_read_second[i] = WINE;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               INIT_CACHED_VAR(rcu_data[0], WINE, j);
+               i = 1;
+               do
+               :: i < SLAB_SIZE ->
+                       INIT_CACHED_VAR(rcu_data[i], POISON, j);
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_free_no_wmb.spin.input.trail b/formal-model/results/urcu-controldataflow-ipi/urcu_free_no_wmb.spin.input.trail
new file mode 100644 (file)
index 0000000..ddfccff
--- /dev/null
@@ -0,0 +1,1485 @@
+-2:3:-2
+-4:-4:-4
+1:0:4644
+2:3:4564
+3:3:4567
+4:3:4567
+5:3:4570
+6:3:4578
+7:3:4578
+8:3:4581
+9:3:4587
+10:3:4591
+11:3:4591
+12:3:4594
+13:3:4604
+14:3:4612
+15:3:4612
+16:3:4615
+17:3:4621
+18:3:4625
+19:3:4625
+20:3:4628
+21:3:4634
+22:3:4638
+23:3:4639
+24:0:4644
+25:3:4641
+26:0:4644
+27:2:2871
+28:0:4644
+29:2:2877
+30:0:4644
+31:2:2878
+32:0:4644
+33:2:2880
+34:0:4644
+35:2:2881
+36:0:4644
+37:2:2882
+38:0:4644
+39:2:2883
+40:2:2884
+41:2:2888
+42:2:2889
+43:2:2897
+44:2:2898
+45:2:2902
+46:2:2903
+47:2:2911
+48:2:2916
+49:2:2920
+50:2:2921
+51:2:2929
+52:2:2930
+53:2:2934
+54:2:2935
+55:2:2929
+56:2:2930
+57:2:2934
+58:2:2935
+59:2:2943
+60:2:2948
+61:2:2949
+62:2:2960
+63:2:2961
+64:2:2962
+65:2:2973
+66:2:2978
+67:2:2979
+68:2:2990
+69:2:2991
+70:2:2992
+71:2:2990
+72:2:2991
+73:2:2992
+74:2:3003
+75:2:3011
+76:0:4644
+77:2:2882
+78:0:4644
+79:2:3063
+80:2:3064
+81:2:3065
+82:0:4644
+83:2:2882
+84:0:4644
+85:2:3070
+86:0:4644
+87:2:3773
+88:2:3774
+89:2:3778
+90:2:3782
+91:2:3783
+92:2:3787
+93:2:3792
+94:2:3800
+95:2:3804
+96:2:3805
+97:2:3800
+98:2:3801
+99:2:3809
+100:2:3816
+101:2:3823
+102:2:3824
+103:2:3831
+104:2:3836
+105:2:3843
+106:2:3844
+107:2:3843
+108:2:3844
+109:2:3851
+110:2:3855
+111:0:4644
+112:2:3860
+113:0:4644
+114:2:3861
+115:0:4644
+116:2:3862
+117:0:4644
+118:2:3863
+119:0:4644
+120:1:2
+121:0:4644
+122:2:3864
+123:0:4644
+124:1:8
+125:0:4644
+126:1:9
+127:0:4644
+128:2:3863
+129:0:4644
+130:1:10
+131:0:4644
+132:2:3864
+133:0:4644
+134:1:11
+135:0:4644
+136:2:3863
+137:0:4644
+138:1:12
+139:0:4644
+140:2:3864
+141:0:4644
+142:1:13
+143:0:4644
+144:2:3863
+145:0:4644
+146:1:14
+147:0:4644
+148:2:3864
+149:0:4644
+150:1:15
+151:0:4644
+152:1:16
+153:0:4644
+154:2:3863
+155:0:4644
+156:1:17
+157:0:4644
+158:2:3864
+159:0:4644
+160:1:26
+161:0:4644
+162:2:3863
+163:0:4644
+164:1:30
+165:1:31
+166:1:35
+167:1:39
+168:1:40
+169:1:44
+170:1:52
+171:1:53
+172:1:57
+173:1:61
+174:1:62
+175:1:57
+176:1:61
+177:1:62
+178:1:66
+179:1:73
+180:1:80
+181:1:81
+182:1:88
+183:1:93
+184:1:100
+185:1:101
+186:1:100
+187:1:101
+188:1:108
+189:1:112
+190:0:4644
+191:2:3864
+192:0:4644
+193:1:117
+194:0:4644
+195:2:3865
+196:0:4644
+197:2:3870
+198:0:4644
+199:2:3871
+200:0:4644
+201:2:3879
+202:2:3880
+203:2:3884
+204:2:3888
+205:2:3889
+206:2:3893
+207:2:3901
+208:2:3902
+209:2:3906
+210:2:3910
+211:2:3911
+212:2:3906
+213:2:3910
+214:2:3911
+215:2:3915
+216:2:3922
+217:2:3929
+218:2:3930
+219:2:3937
+220:2:3942
+221:2:3949
+222:2:3950
+223:2:3949
+224:2:3950
+225:2:3957
+226:2:3961
+227:0:4644
+228:2:3072
+229:2:3754
+230:0:4644
+231:2:2882
+232:0:4644
+233:2:3073
+234:0:4644
+235:2:2882
+236:0:4644
+237:2:3076
+238:2:3077
+239:2:3081
+240:2:3082
+241:2:3090
+242:2:3091
+243:2:3095
+244:2:3096
+245:2:3104
+246:2:3109
+247:2:3113
+248:2:3114
+249:2:3122
+250:2:3123
+251:2:3127
+252:2:3128
+253:2:3122
+254:2:3123
+255:2:3127
+256:2:3128
+257:2:3136
+258:2:3141
+259:2:3142
+260:2:3153
+261:2:3154
+262:2:3155
+263:2:3166
+264:2:3171
+265:2:3172
+266:2:3183
+267:2:3184
+268:2:3185
+269:2:3183
+270:2:3184
+271:2:3185
+272:2:3196
+273:2:3203
+274:0:4644
+275:2:2882
+276:0:4644
+277:2:3207
+278:2:3208
+279:2:3209
+280:2:3221
+281:2:3222
+282:2:3226
+283:2:3227
+284:2:3235
+285:2:3240
+286:2:3244
+287:2:3245
+288:2:3253
+289:2:3254
+290:2:3258
+291:2:3259
+292:2:3253
+293:2:3254
+294:2:3258
+295:2:3259
+296:2:3267
+297:2:3272
+298:2:3273
+299:2:3284
+300:2:3285
+301:2:3286
+302:2:3297
+303:2:3302
+304:2:3303
+305:2:3314
+306:2:3315
+307:2:3316
+308:2:3314
+309:2:3315
+310:2:3316
+311:2:3327
+312:2:3338
+313:2:3339
+314:0:4644
+315:2:2882
+316:0:4644
+317:2:3345
+318:2:3346
+319:2:3350
+320:2:3351
+321:2:3359
+322:2:3360
+323:2:3364
+324:2:3365
+325:2:3373
+326:2:3378
+327:2:3382
+328:2:3383
+329:2:3391
+330:2:3392
+331:2:3396
+332:2:3397
+333:2:3391
+334:2:3392
+335:2:3396
+336:2:3397
+337:2:3405
+338:2:3410
+339:2:3411
+340:2:3422
+341:2:3423
+342:2:3424
+343:2:3435
+344:2:3440
+345:2:3441
+346:2:3452
+347:2:3453
+348:2:3454
+349:2:3452
+350:2:3453
+351:2:3454
+352:2:3465
+353:0:4644
+354:2:2882
+355:0:4644
+356:2:3474
+357:2:3475
+358:2:3479
+359:2:3480
+360:2:3488
+361:2:3489
+362:2:3493
+363:2:3494
+364:2:3502
+365:2:3507
+366:2:3511
+367:2:3512
+368:2:3520
+369:2:3521
+370:2:3525
+371:2:3526
+372:2:3520
+373:2:3521
+374:2:3525
+375:2:3526
+376:2:3534
+377:2:3539
+378:2:3540
+379:2:3551
+380:2:3552
+381:2:3553
+382:2:3564
+383:2:3569
+384:2:3570
+385:2:3581
+386:2:3582
+387:2:3583
+388:2:3581
+389:2:3582
+390:2:3583
+391:2:3594
+392:2:3601
+393:0:4644
+394:2:2882
+395:0:4644
+396:2:3605
+397:2:3606
+398:2:3607
+399:2:3619
+400:2:3620
+401:2:3624
+402:2:3625
+403:2:3633
+404:2:3638
+405:2:3642
+406:2:3643
+407:2:3651
+408:2:3652
+409:2:3656
+410:2:3657
+411:2:3651
+412:2:3652
+413:2:3656
+414:2:3657
+415:2:3665
+416:2:3670
+417:2:3671
+418:2:3682
+419:2:3683
+420:2:3684
+421:2:3695
+422:2:3700
+423:2:3701
+424:2:3712
+425:2:3713
+426:2:3714
+427:2:3712
+428:2:3713
+429:2:3714
+430:2:3725
+431:2:3735
+432:2:3736
+433:0:4644
+434:2:2882
+435:0:4644
+436:2:3742
+437:0:4644
+438:2:4367
+439:2:4368
+440:2:4372
+441:2:4376
+442:2:4377
+443:2:4381
+444:2:4389
+445:2:4390
+446:2:4394
+447:2:4398
+448:2:4399
+449:2:4394
+450:2:4398
+451:2:4399
+452:2:4403
+453:2:4410
+454:2:4417
+455:2:4418
+456:2:4425
+457:2:4430
+458:2:4437
+459:2:4438
+460:2:4437
+461:2:4438
+462:2:4445
+463:2:4449
+464:0:4644
+465:2:4454
+466:0:4644
+467:2:4455
+468:0:4644
+469:2:4456
+470:0:4644
+471:2:4457
+472:0:4644
+473:1:26
+474:0:4644
+475:2:4458
+476:0:4644
+477:1:30
+478:1:31
+479:1:35
+480:1:39
+481:1:40
+482:1:44
+483:1:52
+484:1:53
+485:1:57
+486:1:61
+487:1:62
+488:1:57
+489:1:61
+490:1:62
+491:1:66
+492:1:73
+493:1:80
+494:1:81
+495:1:88
+496:1:93
+497:1:100
+498:1:101
+499:1:100
+500:1:101
+501:1:108
+502:1:112
+503:0:4644
+504:2:4457
+505:0:4644
+506:1:117
+507:0:4644
+508:2:4458
+509:0:4644
+510:2:4459
+511:0:4644
+512:2:4464
+513:0:4644
+514:2:4465
+515:0:4644
+516:2:4473
+517:2:4474
+518:2:4478
+519:2:4482
+520:2:4483
+521:2:4487
+522:2:4495
+523:2:4496
+524:2:4500
+525:2:4504
+526:2:4505
+527:2:4500
+528:2:4504
+529:2:4505
+530:2:4509
+531:2:4516
+532:2:4523
+533:2:4524
+534:2:4531
+535:2:4536
+536:2:4543
+537:2:4544
+538:2:4543
+539:2:4544
+540:2:4551
+541:2:4555
+542:0:4644
+543:2:3744
+544:2:3754
+545:0:4644
+546:2:2882
+547:0:4644
+548:2:3745
+549:2:3746
+550:0:4644
+551:2:2882
+552:0:4644
+553:2:3750
+554:0:4644
+555:2:3758
+556:0:4644
+557:2:2878
+558:0:4644
+559:2:2880
+560:0:4644
+561:2:2881
+562:0:4644
+563:2:2882
+564:0:4644
+565:2:3063
+566:2:3064
+567:2:3065
+568:0:4644
+569:2:2882
+570:0:4644
+571:2:2883
+572:2:2884
+573:2:2888
+574:2:2889
+575:2:2897
+576:2:2898
+577:2:2902
+578:2:2903
+579:2:2911
+580:2:2916
+581:2:2917
+582:2:2929
+583:2:2930
+584:2:2931
+585:2:2929
+586:2:2930
+587:2:2934
+588:2:2935
+589:2:2943
+590:2:2948
+591:2:2949
+592:2:2960
+593:2:2961
+594:2:2962
+595:2:2973
+596:2:2978
+597:2:2979
+598:2:2990
+599:2:2991
+600:2:2992
+601:2:2990
+602:2:2991
+603:2:2992
+604:2:3003
+605:2:3011
+606:0:4644
+607:2:2882
+608:0:4644
+609:2:3070
+610:0:4644
+611:2:3773
+612:2:3774
+613:2:3778
+614:2:3782
+615:2:3783
+616:2:3787
+617:2:3795
+618:2:3796
+619:2:3800
+620:2:3801
+621:2:3800
+622:2:3804
+623:2:3805
+624:2:3809
+625:2:3816
+626:2:3823
+627:2:3824
+628:2:3831
+629:2:3836
+630:2:3843
+631:2:3844
+632:2:3843
+633:2:3844
+634:2:3851
+635:2:3855
+636:0:4644
+637:2:3860
+638:0:4644
+639:2:3861
+640:0:4644
+641:2:3862
+642:0:4644
+643:2:3863
+644:0:4644
+645:1:26
+646:0:4644
+647:2:3864
+648:0:4644
+649:1:30
+650:1:31
+651:1:35
+652:1:39
+653:1:40
+654:1:44
+655:1:52
+656:1:53
+657:1:57
+658:1:61
+659:1:62
+660:1:57
+661:1:61
+662:1:62
+663:1:66
+664:1:73
+665:1:80
+666:1:81
+667:1:88
+668:1:93
+669:1:100
+670:1:101
+671:1:100
+672:1:101
+673:1:108
+674:1:112
+675:0:4644
+676:2:3863
+677:0:4644
+678:1:117
+679:0:4644
+680:2:3864
+681:0:4644
+682:2:3865
+683:0:4644
+684:2:3870
+685:0:4644
+686:2:3871
+687:0:4644
+688:2:3879
+689:2:3880
+690:2:3884
+691:2:3888
+692:2:3889
+693:2:3893
+694:2:3901
+695:2:3902
+696:2:3906
+697:2:3910
+698:2:3911
+699:2:3906
+700:2:3910
+701:2:3911
+702:2:3915
+703:2:3922
+704:2:3929
+705:2:3930
+706:2:3937
+707:2:3942
+708:2:3949
+709:2:3950
+710:2:3949
+711:2:3950
+712:2:3957
+713:2:3961
+714:0:4644
+715:2:3072
+716:2:3754
+717:0:4644
+718:2:2882
+719:0:4644
+720:2:3073
+721:0:4644
+722:2:2882
+723:0:4644
+724:2:3076
+725:2:3077
+726:2:3081
+727:2:3082
+728:2:3090
+729:2:3091
+730:2:3095
+731:2:3096
+732:2:3104
+733:2:3109
+734:2:3113
+735:2:3114
+736:2:3122
+737:2:3123
+738:2:3127
+739:2:3128
+740:2:3122
+741:2:3123
+742:2:3127
+743:2:3128
+744:2:3136
+745:2:3141
+746:2:3142
+747:2:3153
+748:2:3154
+749:2:3155
+750:2:3166
+751:2:3171
+752:2:3172
+753:2:3183
+754:2:3184
+755:2:3185
+756:2:3183
+757:2:3184
+758:2:3185
+759:2:3196
+760:2:3203
+761:0:4644
+762:2:2882
+763:0:4644
+764:2:3207
+765:2:3208
+766:2:3209
+767:2:3221
+768:2:3222
+769:2:3226
+770:2:3227
+771:2:3235
+772:2:3240
+773:2:3244
+774:2:3245
+775:2:3253
+776:2:3254
+777:2:3258
+778:2:3259
+779:2:3253
+780:2:3254
+781:2:3258
+782:2:3259
+783:2:3267
+784:2:3272
+785:2:3273
+786:2:3284
+787:2:3285
+788:2:3286
+789:2:3297
+790:2:3302
+791:2:3303
+792:2:3314
+793:2:3315
+794:2:3316
+795:2:3314
+796:2:3315
+797:2:3316
+798:2:3327
+799:2:3338
+800:2:3339
+801:0:4644
+802:2:2882
+803:0:4644
+804:2:3345
+805:2:3346
+806:2:3350
+807:2:3351
+808:2:3359
+809:2:3360
+810:2:3364
+811:2:3365
+812:2:3373
+813:2:3378
+814:2:3382
+815:2:3383
+816:2:3391
+817:2:3392
+818:2:3396
+819:2:3397
+820:2:3391
+821:2:3392
+822:2:3396
+823:2:3397
+824:2:3405
+825:2:3410
+826:2:3411
+827:2:3422
+828:2:3423
+829:2:3424
+830:2:3435
+831:2:3440
+832:2:3441
+833:2:3452
+834:2:3453
+835:2:3454
+836:2:3452
+837:2:3453
+838:2:3454
+839:2:3465
+840:0:4644
+841:2:2882
+842:0:4644
+843:2:3474
+844:2:3475
+845:2:3479
+846:2:3480
+847:2:3488
+848:2:3489
+849:2:3493
+850:2:3494
+851:2:3502
+852:2:3507
+853:2:3511
+854:2:3512
+855:2:3520
+856:2:3521
+857:2:3525
+858:2:3526
+859:2:3520
+860:2:3521
+861:2:3525
+862:2:3526
+863:2:3534
+864:2:3539
+865:2:3540
+866:2:3551
+867:2:3552
+868:2:3553
+869:2:3564
+870:2:3569
+871:2:3570
+872:2:3581
+873:2:3582
+874:2:3583
+875:2:3581
+876:2:3582
+877:2:3583
+878:2:3594
+879:2:3601
+880:0:4644
+881:2:2882
+882:0:4644
+883:2:3605
+884:2:3606
+885:2:3607
+886:2:3619
+887:2:3620
+888:2:3624
+889:2:3625
+890:2:3633
+891:2:3638
+892:2:3642
+893:2:3643
+894:2:3651
+895:2:3652
+896:2:3656
+897:2:3657
+898:2:3651
+899:2:3652
+900:2:3656
+901:2:3657
+902:2:3665
+903:2:3670
+904:2:3671
+905:2:3682
+906:2:3683
+907:2:3684
+908:2:3695
+909:2:3700
+910:2:3701
+911:2:3712
+912:2:3713
+913:2:3714
+914:2:3712
+915:2:3713
+916:2:3714
+917:2:3725
+918:2:3735
+919:2:3736
+920:0:4644
+921:2:2882
+922:0:4644
+923:2:3742
+924:0:4644
+925:2:4367
+926:2:4368
+927:2:4372
+928:2:4376
+929:2:4377
+930:2:4381
+931:2:4389
+932:2:4390
+933:2:4394
+934:2:4398
+935:2:4399
+936:2:4394
+937:2:4398
+938:2:4399
+939:2:4403
+940:2:4410
+941:2:4417
+942:2:4418
+943:2:4425
+944:2:4430
+945:2:4437
+946:2:4438
+947:2:4437
+948:2:4438
+949:2:4445
+950:2:4449
+951:0:4644
+952:2:4454
+953:0:4644
+954:2:4455
+955:0:4644
+956:2:4456
+957:0:4644
+958:2:4457
+959:0:4644
+960:1:26
+961:0:4644
+962:2:4458
+963:0:4644
+964:1:30
+965:1:31
+966:1:35
+967:1:39
+968:1:40
+969:1:44
+970:1:52
+971:1:53
+972:1:57
+973:1:61
+974:1:62
+975:1:57
+976:1:61
+977:1:62
+978:1:66
+979:1:73
+980:1:80
+981:1:81
+982:1:88
+983:1:93
+984:1:100
+985:1:101
+986:1:100
+987:1:101
+988:1:108
+989:1:112
+990:0:4644
+991:2:4457
+992:0:4644
+993:1:117
+994:0:4644
+995:2:4458
+996:0:4644
+997:2:4459
+998:0:4644
+999:2:4464
+1000:0:4644
+1001:2:4465
+1002:0:4644
+1003:2:4473
+1004:2:4474
+1005:2:4478
+1006:2:4482
+1007:2:4483
+1008:2:4487
+1009:2:4495
+1010:2:4496
+1011:2:4500
+1012:2:4504
+1013:2:4505
+1014:2:4500
+1015:2:4504
+1016:2:4505
+1017:2:4509
+1018:2:4516
+1019:2:4523
+1020:2:4524
+1021:2:4531
+1022:2:4536
+1023:2:4543
+1024:2:4544
+1025:2:4543
+1026:2:4544
+1027:2:4551
+1028:2:4555
+1029:0:4644
+1030:2:3744
+1031:2:3754
+1032:0:4644
+1033:2:2882
+1034:0:4644
+1035:2:3745
+1036:2:3746
+1037:0:4644
+1038:2:2882
+1039:0:4644
+1040:2:3750
+1041:0:4644
+1042:2:3758
+1043:0:4644
+1044:2:2878
+1045:0:4644
+1046:2:2880
+1047:0:4644
+1048:2:2881
+1049:0:4644
+1050:2:2882
+1051:0:4644
+1052:2:2883
+1053:2:2884
+1054:2:2888
+1055:2:2889
+1056:2:2897
+1057:2:2898
+1058:2:2902
+1059:2:2903
+1060:2:2911
+1061:2:2916
+1062:2:2920
+1063:2:2921
+1064:2:2929
+1065:2:2930
+1066:2:2934
+1067:2:2935
+1068:2:2929
+1069:2:2930
+1070:2:2931
+1071:2:2943
+1072:2:2948
+1073:2:2949
+1074:2:2960
+1075:2:2961
+1076:2:2962
+1077:2:2973
+1078:2:2978
+1079:2:2979
+1080:2:2990
+1081:2:2991
+1082:2:2992
+1083:2:2990
+1084:2:2991
+1085:2:2992
+1086:2:3003
+1087:2:3011
+1088:0:4644
+1089:2:2882
+1090:0:4644
+1091:2:3063
+1092:2:3064
+1093:2:3065
+1094:0:4644
+1095:2:2882
+1096:0:4644
+1097:2:3070
+1098:0:4644
+1099:1:118
+1100:0:4644
+1101:1:120
+1102:0:4644
+1103:1:19
+1104:0:4644
+1105:1:126
+1106:1:127
+1107:1:131
+1108:1:132
+1109:1:140
+1110:1:141
+1111:1:145
+1112:1:146
+1113:1:154
+1114:1:159
+1115:1:163
+1116:1:164
+1117:1:172
+1118:1:173
+1119:1:177
+1120:1:178
+1121:1:172
+1122:1:173
+1123:1:177
+1124:1:178
+1125:1:186
+1126:1:191
+1127:1:192
+1128:1:203
+1129:1:204
+1130:1:205
+1131:1:216
+1132:1:221
+1133:1:222
+1134:1:233
+1135:1:234
+1136:1:235
+1137:1:233
+1138:1:234
+1139:1:235
+1140:1:246
+1141:0:4644
+1142:1:15
+1143:0:4644
+1144:1:16
+1145:0:4644
+1146:1:17
+1147:0:4644
+1148:1:118
+1149:0:4644
+1150:1:120
+1151:0:4644
+1152:1:19
+1153:0:4644
+1154:1:255
+1155:1:256
+1156:0:4644
+1157:1:15
+1158:0:4644
+1159:1:16
+1160:0:4644
+1161:1:17
+1162:0:4644
+1163:1:118
+1164:0:4644
+1165:1:120
+1166:0:4644
+1167:1:19
+1168:0:4644
+1169:1:262
+1170:1:263
+1171:1:267
+1172:1:268
+1173:1:276
+1174:1:277
+1175:1:281
+1176:1:282
+1177:1:290
+1178:1:295
+1179:1:299
+1180:1:300
+1181:1:308
+1182:1:309
+1183:1:313
+1184:1:314
+1185:1:308
+1186:1:309
+1187:1:313
+1188:1:314
+1189:1:322
+1190:1:327
+1191:1:328
+1192:1:339
+1193:1:340
+1194:1:341
+1195:1:352
+1196:1:357
+1197:1:358
+1198:1:369
+1199:1:370
+1200:1:371
+1201:1:369
+1202:1:370
+1203:1:371
+1204:1:382
+1205:0:4644
+1206:1:15
+1207:0:4644
+1208:1:16
+1209:0:4644
+1210:1:17
+1211:0:4644
+1212:1:118
+1213:0:4644
+1214:1:120
+1215:0:4644
+1216:1:19
+1217:0:4644
+1218:1:391
+1219:1:392
+1220:1:396
+1221:1:397
+1222:1:405
+1223:1:406
+1224:1:410
+1225:1:411
+1226:1:419
+1227:1:424
+1228:1:428
+1229:1:429
+1230:1:437
+1231:1:438
+1232:1:442
+1233:1:443
+1234:1:437
+1235:1:438
+1236:1:442
+1237:1:443
+1238:1:451
+1239:1:456
+1240:1:457
+1241:1:468
+1242:1:469
+1243:1:470
+1244:1:481
+1245:1:486
+1246:1:487
+1247:1:498
+1248:1:499
+1249:1:500
+1250:1:498
+1251:1:499
+1252:1:500
+1253:1:511
+1254:1:518
+1255:0:4644
+1256:1:15
+1257:0:4644
+1258:1:16
+1259:0:4644
+1260:1:17
+1261:0:4644
+1262:1:118
+1263:0:4644
+1264:1:120
+1265:0:4644
+1266:1:19
+1267:0:4644
+1268:1:656
+1269:1:657
+1270:1:661
+1271:1:662
+1272:1:670
+1273:1:671
+1274:1:672
+1275:1:684
+1276:1:689
+1277:1:693
+1278:1:694
+1279:1:702
+1280:1:703
+1281:1:707
+1282:1:708
+1283:1:702
+1284:1:703
+1285:1:707
+1286:1:708
+1287:1:716
+1288:1:721
+1289:1:722
+1290:1:733
+1291:1:734
+1292:1:735
+1293:1:746
+1294:1:751
+1295:1:752
+1296:1:763
+1297:1:764
+1298:1:765
+1299:1:763
+1300:1:764
+1301:1:765
+1302:1:776
+1303:0:4644
+1304:1:15
+1305:0:4644
+1306:1:16
+1307:0:4644
+1308:1:17
+1309:0:4644
+1310:1:118
+1311:0:4644
+1312:1:120
+1313:0:4644
+1314:1:19
+1315:0:4644
+1316:1:785
+1317:1:788
+1318:1:789
+1319:0:4644
+1320:1:15
+1321:0:4644
+1322:1:16
+1323:0:4644
+1324:1:17
+1325:0:4644
+1326:1:118
+1327:0:4644
+1328:1:120
+1329:0:4644
+1330:1:19
+1331:0:4644
+1332:1:1052
+1333:1:1053
+1334:1:1057
+1335:1:1058
+1336:1:1066
+1337:1:1067
+1338:1:1071
+1339:1:1072
+1340:1:1080
+1341:1:1085
+1342:1:1089
+1343:1:1090
+1344:1:1098
+1345:1:1099
+1346:1:1103
+1347:1:1104
+1348:1:1098
+1349:1:1099
+1350:1:1103
+1351:1:1104
+1352:1:1112
+1353:1:1117
+1354:1:1118
+1355:1:1129
+1356:1:1130
+1357:1:1131
+1358:1:1142
+1359:1:1147
+1360:1:1148
+1361:1:1159
+1362:1:1160
+1363:1:1161
+1364:1:1159
+1365:1:1160
+1366:1:1161
+1367:1:1172
+1368:1:1179
+1369:1:1183
+1370:0:4644
+1371:1:15
+1372:0:4644
+1373:1:16
+1374:0:4644
+1375:1:17
+1376:0:4644
+1377:1:118
+1378:0:4644
+1379:1:120
+1380:0:4644
+1381:1:19
+1382:0:4644
+1383:1:1184
+1384:1:1185
+1385:1:1189
+1386:1:1190
+1387:1:1198
+1388:1:1199
+1389:1:1200
+1390:1:1212
+1391:1:1217
+1392:1:1221
+1393:1:1222
+1394:1:1230
+1395:1:1231
+1396:1:1235
+1397:1:1236
+1398:1:1230
+1399:1:1231
+1400:1:1235
+1401:1:1236
+1402:1:1244
+1403:1:1249
+1404:1:1250
+1405:1:1261
+1406:1:1262
+1407:1:1263
+1408:1:1274
+1409:1:1279
+1410:1:1280
+1411:1:1291
+1412:1:1292
+1413:1:1293
+1414:1:1291
+1415:1:1292
+1416:1:1293
+1417:1:1304
+1418:0:4644
+1419:1:15
+1420:0:4644
+1421:1:16
+1422:0:4644
+1423:1:17
+1424:0:4644
+1425:1:118
+1426:0:4644
+1427:1:120
+1428:0:4644
+1429:1:19
+1430:0:4644
+1431:1:1313
+1432:0:4644
+1433:1:2777
+1434:1:2784
+1435:1:2785
+1436:1:2792
+1437:1:2797
+1438:1:2804
+1439:1:2805
+1440:1:2804
+1441:1:2805
+1442:1:2812
+1443:1:2816
+1444:0:4644
+1445:2:3773
+1446:2:3774
+1447:2:3778
+1448:2:3782
+1449:2:3783
+1450:2:3787
+1451:2:3792
+1452:2:3800
+1453:2:3804
+1454:2:3805
+1455:2:3800
+1456:2:3801
+1457:2:3809
+1458:2:3816
+1459:2:3823
+1460:2:3824
+1461:2:3831
+1462:2:3836
+1463:2:3843
+1464:2:3844
+1465:2:3843
+1466:2:3844
+1467:2:3851
+1468:2:3855
+1469:0:4644
+1470:2:3860
+1471:0:4644
+1472:2:3861
+1473:0:4644
+1474:2:3862
+1475:0:4644
+1476:2:3863
+1477:0:4644
+1478:1:1315
+1479:1:1316
+1480:0:4642
+1481:2:3864
+1482:0:4648
+1483:1:2474
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_free_single_flip.define b/formal-model/results/urcu-controldataflow-ipi/urcu_free_single_flip.define
new file mode 100644 (file)
index 0000000..5e642ef
--- /dev/null
@@ -0,0 +1 @@
+#define SINGLE_FLIP
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_free_single_flip.log b/formal-model/results/urcu-controldataflow-ipi/urcu_free_single_flip.log
new file mode 100644 (file)
index 0000000..eedc9f4
--- /dev/null
@@ -0,0 +1,761 @@
+rm -f pan* trail.out .input.spin* *.spin.trail .input.define
+touch .input.define
+cat .input.define >> pan.ltl
+cat DEFINES >> pan.ltl
+spin -f "!(`cat urcu_free.ltl | grep -v ^//`)" >> pan.ltl
+cp urcu_free_single_flip.define .input.define
+cat .input.define > .input.spin
+cat DEFINES >> .input.spin
+cat urcu.spin >> .input.spin
+rm -f .input.spin.trail
+spin -a -X -N pan.ltl .input.spin
+Exit-Status 0
+gcc -O2 -w -DHASH64 -o pan pan.c
+./pan -a -v -c1 -X -m10000000 -w20
+warning: for p.o. reduction to be valid the never claim must be stutter-invariant
+(never claims generated from LTL formulae are stutter-invariant)
+depth 0: Claim reached state 5 (line 1258)
+Depth=    6859 States=    1e+06 Transitions= 1.64e+08 Memory=   550.432        t=    209 R=   5e+03
+Depth=    6859 States=    2e+06 Transitions= 3.19e+08 Memory=   634.318        t=    409 R=   5e+03
+Depth=    6859 States=    3e+06 Transitions= 4.93e+08 Memory=   718.303        t=    643 R=   5e+03
+pan: resizing hashtable to -w22..  done
+Depth=    6859 States=    4e+06 Transitions= 6.91e+08 Memory=   833.311        t=    903 R=   4e+03
+Depth=    6859 States=    5e+06 Transitions=    9e+08 Memory=   917.295        t= 1.17e+03 R=   4e+03
+Depth=    6859 States=    6e+06 Transitions= 1.08e+09 Memory=  1001.279        t= 1.41e+03 R=   4e+03
+pan: claim violated! (at depth 1383)
+pan: wrote .input.spin.trail
+
+(Spin Version 5.1.7 -- 23 December 2008)
+Warning: Search not completed
+       + Partial Order Reduction
+
+Full statespace search for:
+       never claim             +
+       assertion violations    + (if within scope of claim)
+       acceptance   cycles     + (fairness disabled)
+       invalid end states      - (disabled by never claim)
+
+State-vector 88 byte, depth reached 6859, errors: 1
+  6177712 states, stored
+1.1177865e+09 states, matched
+1.1239642e+09 transitions (= stored+matched)
+6.3626905e+09 atomic steps
+hash conflicts: 8.98825e+08 (resolved)
+
+Stats on memory usage (in Megabytes):
+  683.417      equivalent memory usage for states (stored*(State-vector + overhead))
+  526.801      actual memory usage for states (compression: 77.08%)
+               state-vector as stored = 61 byte + 28 byte overhead
+   32.000      memory used for hash table (-w22)
+  457.764      memory used for DFS stack (-m10000000)
+ 1016.221      total actual memory usage
+
+unreached in proctype urcu_reader
+       line 250, "pan.___", state 30, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 52, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 61, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 77, "(1)"
+       line 231, "pan.___", state 85, "(1)"
+       line 235, "pan.___", state 97, "(1)"
+       line 239, "pan.___", state 105, "(1)"
+       line 395, "pan.___", state 131, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 163, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 177, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 196, "(1)"
+       line 421, "pan.___", state 226, "(1)"
+       line 425, "pan.___", state 239, "(1)"
+       line 670, "pan.___", state 260, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<1))"
+       line 395, "pan.___", state 267, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 299, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 313, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 332, "(1)"
+       line 421, "pan.___", state 362, "(1)"
+       line 425, "pan.___", state 375, "(1)"
+       line 395, "pan.___", state 396, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 428, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 442, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 461, "(1)"
+       line 421, "pan.___", state 491, "(1)"
+       line 425, "pan.___", state 504, "(1)"
+       line 395, "pan.___", state 527, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 529, "(1)"
+       line 395, "pan.___", state 530, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 530, "else"
+       line 395, "pan.___", state 533, "(1)"
+       line 399, "pan.___", state 541, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 543, "(1)"
+       line 399, "pan.___", state 544, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 544, "else"
+       line 399, "pan.___", state 547, "(1)"
+       line 399, "pan.___", state 548, "(1)"
+       line 399, "pan.___", state 548, "(1)"
+       line 397, "pan.___", state 553, "((i<1))"
+       line 397, "pan.___", state 553, "((i>=1))"
+       line 404, "pan.___", state 559, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 561, "(1)"
+       line 404, "pan.___", state 562, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 562, "else"
+       line 404, "pan.___", state 565, "(1)"
+       line 404, "pan.___", state 566, "(1)"
+       line 404, "pan.___", state 566, "(1)"
+       line 408, "pan.___", state 573, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 575, "(1)"
+       line 408, "pan.___", state 576, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 576, "else"
+       line 408, "pan.___", state 579, "(1)"
+       line 408, "pan.___", state 580, "(1)"
+       line 408, "pan.___", state 580, "(1)"
+       line 406, "pan.___", state 585, "((i<2))"
+       line 406, "pan.___", state 585, "((i>=2))"
+       line 412, "pan.___", state 592, "(1)"
+       line 412, "pan.___", state 593, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 593, "else"
+       line 412, "pan.___", state 596, "(1)"
+       line 412, "pan.___", state 597, "(1)"
+       line 412, "pan.___", state 597, "(1)"
+       line 416, "pan.___", state 605, "(1)"
+       line 416, "pan.___", state 606, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 606, "else"
+       line 416, "pan.___", state 609, "(1)"
+       line 416, "pan.___", state 610, "(1)"
+       line 416, "pan.___", state 610, "(1)"
+       line 414, "pan.___", state 615, "((i<1))"
+       line 414, "pan.___", state 615, "((i>=1))"
+       line 421, "pan.___", state 622, "(1)"
+       line 421, "pan.___", state 623, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 623, "else"
+       line 421, "pan.___", state 626, "(1)"
+       line 421, "pan.___", state 627, "(1)"
+       line 421, "pan.___", state 627, "(1)"
+       line 425, "pan.___", state 635, "(1)"
+       line 425, "pan.___", state 636, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 636, "else"
+       line 425, "pan.___", state 639, "(1)"
+       line 425, "pan.___", state 640, "(1)"
+       line 425, "pan.___", state 640, "(1)"
+       line 423, "pan.___", state 645, "((i<2))"
+       line 423, "pan.___", state 645, "((i>=2))"
+       line 430, "pan.___", state 649, "(1)"
+       line 430, "pan.___", state 649, "(1)"
+       line 670, "pan.___", state 652, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 670, "pan.___", state 653, "_proc_urcu_reader = (_proc_urcu_reader|(1<<5))"
+       line 670, "pan.___", state 654, "(1)"
+       line 395, "pan.___", state 661, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 693, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 707, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 726, "(1)"
+       line 421, "pan.___", state 756, "(1)"
+       line 425, "pan.___", state 769, "(1)"
+       line 395, "pan.___", state 797, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 799, "(1)"
+       line 395, "pan.___", state 800, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 800, "else"
+       line 395, "pan.___", state 803, "(1)"
+       line 399, "pan.___", state 811, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 813, "(1)"
+       line 399, "pan.___", state 814, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 814, "else"
+       line 399, "pan.___", state 817, "(1)"
+       line 399, "pan.___", state 818, "(1)"
+       line 399, "pan.___", state 818, "(1)"
+       line 397, "pan.___", state 823, "((i<1))"
+       line 397, "pan.___", state 823, "((i>=1))"
+       line 404, "pan.___", state 829, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 831, "(1)"
+       line 404, "pan.___", state 832, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 832, "else"
+       line 404, "pan.___", state 835, "(1)"
+       line 404, "pan.___", state 836, "(1)"
+       line 404, "pan.___", state 836, "(1)"
+       line 408, "pan.___", state 843, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 845, "(1)"
+       line 408, "pan.___", state 846, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 846, "else"
+       line 408, "pan.___", state 849, "(1)"
+       line 408, "pan.___", state 850, "(1)"
+       line 408, "pan.___", state 850, "(1)"
+       line 406, "pan.___", state 855, "((i<2))"
+       line 406, "pan.___", state 855, "((i>=2))"
+       line 412, "pan.___", state 862, "(1)"
+       line 412, "pan.___", state 863, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 863, "else"
+       line 412, "pan.___", state 866, "(1)"
+       line 412, "pan.___", state 867, "(1)"
+       line 412, "pan.___", state 867, "(1)"
+       line 416, "pan.___", state 875, "(1)"
+       line 416, "pan.___", state 876, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 876, "else"
+       line 416, "pan.___", state 879, "(1)"
+       line 416, "pan.___", state 880, "(1)"
+       line 416, "pan.___", state 880, "(1)"
+       line 414, "pan.___", state 885, "((i<1))"
+       line 414, "pan.___", state 885, "((i>=1))"
+       line 421, "pan.___", state 892, "(1)"
+       line 421, "pan.___", state 893, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 893, "else"
+       line 421, "pan.___", state 896, "(1)"
+       line 421, "pan.___", state 897, "(1)"
+       line 421, "pan.___", state 897, "(1)"
+       line 425, "pan.___", state 905, "(1)"
+       line 425, "pan.___", state 906, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 906, "else"
+       line 425, "pan.___", state 909, "(1)"
+       line 425, "pan.___", state 910, "(1)"
+       line 425, "pan.___", state 910, "(1)"
+       line 430, "pan.___", state 919, "(1)"
+       line 430, "pan.___", state 919, "(1)"
+       line 395, "pan.___", state 926, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 928, "(1)"
+       line 395, "pan.___", state 929, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 929, "else"
+       line 395, "pan.___", state 932, "(1)"
+       line 399, "pan.___", state 940, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 942, "(1)"
+       line 399, "pan.___", state 943, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 943, "else"
+       line 399, "pan.___", state 946, "(1)"
+       line 399, "pan.___", state 947, "(1)"
+       line 399, "pan.___", state 947, "(1)"
+       line 397, "pan.___", state 952, "((i<1))"
+       line 397, "pan.___", state 952, "((i>=1))"
+       line 404, "pan.___", state 958, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 960, "(1)"
+       line 404, "pan.___", state 961, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 961, "else"
+       line 404, "pan.___", state 964, "(1)"
+       line 404, "pan.___", state 965, "(1)"
+       line 404, "pan.___", state 965, "(1)"
+       line 408, "pan.___", state 972, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 974, "(1)"
+       line 408, "pan.___", state 975, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 975, "else"
+       line 408, "pan.___", state 978, "(1)"
+       line 408, "pan.___", state 979, "(1)"
+       line 408, "pan.___", state 979, "(1)"
+       line 406, "pan.___", state 984, "((i<2))"
+       line 406, "pan.___", state 984, "((i>=2))"
+       line 412, "pan.___", state 991, "(1)"
+       line 412, "pan.___", state 992, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 992, "else"
+       line 412, "pan.___", state 995, "(1)"
+       line 412, "pan.___", state 996, "(1)"
+       line 412, "pan.___", state 996, "(1)"
+       line 416, "pan.___", state 1004, "(1)"
+       line 416, "pan.___", state 1005, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 1005, "else"
+       line 416, "pan.___", state 1008, "(1)"
+       line 416, "pan.___", state 1009, "(1)"
+       line 416, "pan.___", state 1009, "(1)"
+       line 414, "pan.___", state 1014, "((i<1))"
+       line 414, "pan.___", state 1014, "((i>=1))"
+       line 421, "pan.___", state 1021, "(1)"
+       line 421, "pan.___", state 1022, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 1022, "else"
+       line 421, "pan.___", state 1025, "(1)"
+       line 421, "pan.___", state 1026, "(1)"
+       line 421, "pan.___", state 1026, "(1)"
+       line 425, "pan.___", state 1034, "(1)"
+       line 425, "pan.___", state 1035, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 1035, "else"
+       line 425, "pan.___", state 1038, "(1)"
+       line 425, "pan.___", state 1039, "(1)"
+       line 425, "pan.___", state 1039, "(1)"
+       line 423, "pan.___", state 1044, "((i<2))"
+       line 423, "pan.___", state 1044, "((i>=2))"
+       line 430, "pan.___", state 1048, "(1)"
+       line 430, "pan.___", state 1048, "(1)"
+       line 678, "pan.___", state 1052, "_proc_urcu_reader = (_proc_urcu_reader|(1<<11))"
+       line 395, "pan.___", state 1057, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1089, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1103, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1122, "(1)"
+       line 421, "pan.___", state 1152, "(1)"
+       line 425, "pan.___", state 1165, "(1)"
+       line 395, "pan.___", state 1189, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1221, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1235, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1254, "(1)"
+       line 421, "pan.___", state 1284, "(1)"
+       line 425, "pan.___", state 1297, "(1)"
+       line 395, "pan.___", state 1322, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1354, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1368, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1387, "(1)"
+       line 421, "pan.___", state 1417, "(1)"
+       line 425, "pan.___", state 1430, "(1)"
+       line 395, "pan.___", state 1451, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1483, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1497, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1516, "(1)"
+       line 421, "pan.___", state 1546, "(1)"
+       line 425, "pan.___", state 1559, "(1)"
+       line 395, "pan.___", state 1585, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1617, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1631, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1650, "(1)"
+       line 421, "pan.___", state 1680, "(1)"
+       line 425, "pan.___", state 1693, "(1)"
+       line 395, "pan.___", state 1714, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1746, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1760, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1779, "(1)"
+       line 421, "pan.___", state 1809, "(1)"
+       line 425, "pan.___", state 1822, "(1)"
+       line 395, "pan.___", state 1846, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1878, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1892, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1911, "(1)"
+       line 421, "pan.___", state 1941, "(1)"
+       line 425, "pan.___", state 1954, "(1)"
+       line 717, "pan.___", state 1975, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<19))"
+       line 395, "pan.___", state 1982, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2014, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2028, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2047, "(1)"
+       line 421, "pan.___", state 2077, "(1)"
+       line 425, "pan.___", state 2090, "(1)"
+       line 395, "pan.___", state 2111, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2143, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2157, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2176, "(1)"
+       line 421, "pan.___", state 2206, "(1)"
+       line 425, "pan.___", state 2219, "(1)"
+       line 395, "pan.___", state 2242, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 2244, "(1)"
+       line 395, "pan.___", state 2245, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 2245, "else"
+       line 395, "pan.___", state 2248, "(1)"
+       line 399, "pan.___", state 2256, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 2258, "(1)"
+       line 399, "pan.___", state 2259, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 2259, "else"
+       line 399, "pan.___", state 2262, "(1)"
+       line 399, "pan.___", state 2263, "(1)"
+       line 399, "pan.___", state 2263, "(1)"
+       line 397, "pan.___", state 2268, "((i<1))"
+       line 397, "pan.___", state 2268, "((i>=1))"
+       line 404, "pan.___", state 2274, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2276, "(1)"
+       line 404, "pan.___", state 2277, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 2277, "else"
+       line 404, "pan.___", state 2280, "(1)"
+       line 404, "pan.___", state 2281, "(1)"
+       line 404, "pan.___", state 2281, "(1)"
+       line 408, "pan.___", state 2288, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2290, "(1)"
+       line 408, "pan.___", state 2291, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 2291, "else"
+       line 408, "pan.___", state 2294, "(1)"
+       line 408, "pan.___", state 2295, "(1)"
+       line 408, "pan.___", state 2295, "(1)"
+       line 406, "pan.___", state 2300, "((i<2))"
+       line 406, "pan.___", state 2300, "((i>=2))"
+       line 412, "pan.___", state 2307, "(1)"
+       line 412, "pan.___", state 2308, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 2308, "else"
+       line 412, "pan.___", state 2311, "(1)"
+       line 412, "pan.___", state 2312, "(1)"
+       line 412, "pan.___", state 2312, "(1)"
+       line 416, "pan.___", state 2320, "(1)"
+       line 416, "pan.___", state 2321, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 2321, "else"
+       line 416, "pan.___", state 2324, "(1)"
+       line 416, "pan.___", state 2325, "(1)"
+       line 416, "pan.___", state 2325, "(1)"
+       line 414, "pan.___", state 2330, "((i<1))"
+       line 414, "pan.___", state 2330, "((i>=1))"
+       line 421, "pan.___", state 2337, "(1)"
+       line 421, "pan.___", state 2338, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 2338, "else"
+       line 421, "pan.___", state 2341, "(1)"
+       line 421, "pan.___", state 2342, "(1)"
+       line 421, "pan.___", state 2342, "(1)"
+       line 425, "pan.___", state 2350, "(1)"
+       line 425, "pan.___", state 2351, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 2351, "else"
+       line 425, "pan.___", state 2354, "(1)"
+       line 425, "pan.___", state 2355, "(1)"
+       line 425, "pan.___", state 2355, "(1)"
+       line 423, "pan.___", state 2360, "((i<2))"
+       line 423, "pan.___", state 2360, "((i>=2))"
+       line 430, "pan.___", state 2364, "(1)"
+       line 430, "pan.___", state 2364, "(1)"
+       line 717, "pan.___", state 2367, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 717, "pan.___", state 2368, "_proc_urcu_reader = (_proc_urcu_reader|(1<<23))"
+       line 717, "pan.___", state 2369, "(1)"
+       line 395, "pan.___", state 2376, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2408, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2422, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2441, "(1)"
+       line 421, "pan.___", state 2471, "(1)"
+       line 425, "pan.___", state 2484, "(1)"
+       line 395, "pan.___", state 2511, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2543, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2557, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2576, "(1)"
+       line 421, "pan.___", state 2606, "(1)"
+       line 425, "pan.___", state 2619, "(1)"
+       line 395, "pan.___", state 2640, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2672, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2686, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2705, "(1)"
+       line 421, "pan.___", state 2735, "(1)"
+       line 425, "pan.___", state 2748, "(1)"
+       line 227, "pan.___", state 2781, "(1)"
+       line 235, "pan.___", state 2801, "(1)"
+       line 239, "pan.___", state 2809, "(1)"
+       line 227, "pan.___", state 2824, "(1)"
+       line 235, "pan.___", state 2844, "(1)"
+       line 239, "pan.___", state 2852, "(1)"
+       line 877, "pan.___", state 2869, "-end-"
+       (278 of 2869 states)
+unreached in proctype urcu_writer
+       line 395, "pan.___", state 22, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 36, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 54, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 87, "(1)"
+       line 416, "pan.___", state 100, "(1)"
+       line 421, "pan.___", state 117, "(1)"
+       line 250, "pan.___", state 153, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 162, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 175, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 215, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 229, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 247, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 261, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 280, "(1)"
+       line 416, "pan.___", state 293, "(1)"
+       line 421, "pan.___", state 310, "(1)"
+       line 425, "pan.___", state 323, "(1)"
+       line 399, "pan.___", state 360, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 378, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 392, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 424, "(1)"
+       line 421, "pan.___", state 441, "(1)"
+       line 425, "pan.___", state 454, "(1)"
+       line 395, "pan.___", state 483, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 485, "(1)"
+       line 395, "pan.___", state 486, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 486, "else"
+       line 395, "pan.___", state 489, "(1)"
+       line 399, "pan.___", state 497, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 499, "(1)"
+       line 399, "pan.___", state 500, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 500, "else"
+       line 399, "pan.___", state 503, "(1)"
+       line 399, "pan.___", state 504, "(1)"
+       line 399, "pan.___", state 504, "(1)"
+       line 397, "pan.___", state 509, "((i<1))"
+       line 397, "pan.___", state 509, "((i>=1))"
+       line 404, "pan.___", state 515, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 517, "(1)"
+       line 404, "pan.___", state 518, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 518, "else"
+       line 404, "pan.___", state 521, "(1)"
+       line 404, "pan.___", state 522, "(1)"
+       line 404, "pan.___", state 522, "(1)"
+       line 408, "pan.___", state 529, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 531, "(1)"
+       line 408, "pan.___", state 532, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 532, "else"
+       line 408, "pan.___", state 535, "(1)"
+       line 408, "pan.___", state 536, "(1)"
+       line 408, "pan.___", state 536, "(1)"
+       line 406, "pan.___", state 541, "((i<2))"
+       line 406, "pan.___", state 541, "((i>=2))"
+       line 412, "pan.___", state 548, "(1)"
+       line 412, "pan.___", state 549, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 549, "else"
+       line 412, "pan.___", state 552, "(1)"
+       line 412, "pan.___", state 553, "(1)"
+       line 412, "pan.___", state 553, "(1)"
+       line 416, "pan.___", state 561, "(1)"
+       line 416, "pan.___", state 562, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 562, "else"
+       line 416, "pan.___", state 565, "(1)"
+       line 416, "pan.___", state 566, "(1)"
+       line 416, "pan.___", state 566, "(1)"
+       line 414, "pan.___", state 571, "((i<1))"
+       line 414, "pan.___", state 571, "((i>=1))"
+       line 421, "pan.___", state 578, "(1)"
+       line 421, "pan.___", state 579, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 579, "else"
+       line 421, "pan.___", state 582, "(1)"
+       line 421, "pan.___", state 583, "(1)"
+       line 421, "pan.___", state 583, "(1)"
+       line 425, "pan.___", state 591, "(1)"
+       line 425, "pan.___", state 592, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 592, "else"
+       line 425, "pan.___", state 595, "(1)"
+       line 425, "pan.___", state 596, "(1)"
+       line 425, "pan.___", state 596, "(1)"
+       line 430, "pan.___", state 605, "(1)"
+       line 430, "pan.___", state 605, "(1)"
+       line 395, "pan.___", state 612, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 614, "(1)"
+       line 395, "pan.___", state 615, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 615, "else"
+       line 395, "pan.___", state 618, "(1)"
+       line 399, "pan.___", state 626, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 628, "(1)"
+       line 399, "pan.___", state 629, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 629, "else"
+       line 399, "pan.___", state 632, "(1)"
+       line 399, "pan.___", state 633, "(1)"
+       line 399, "pan.___", state 633, "(1)"
+       line 397, "pan.___", state 638, "((i<1))"
+       line 397, "pan.___", state 638, "((i>=1))"
+       line 404, "pan.___", state 644, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 646, "(1)"
+       line 404, "pan.___", state 647, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 647, "else"
+       line 404, "pan.___", state 650, "(1)"
+       line 404, "pan.___", state 651, "(1)"
+       line 404, "pan.___", state 651, "(1)"
+       line 408, "pan.___", state 658, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 660, "(1)"
+       line 408, "pan.___", state 661, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 661, "else"
+       line 408, "pan.___", state 664, "(1)"
+       line 408, "pan.___", state 665, "(1)"
+       line 408, "pan.___", state 665, "(1)"
+       line 406, "pan.___", state 670, "((i<2))"
+       line 406, "pan.___", state 670, "((i>=2))"
+       line 412, "pan.___", state 677, "(1)"
+       line 412, "pan.___", state 678, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 678, "else"
+       line 412, "pan.___", state 681, "(1)"
+       line 412, "pan.___", state 682, "(1)"
+       line 412, "pan.___", state 682, "(1)"
+       line 416, "pan.___", state 690, "(1)"
+       line 416, "pan.___", state 691, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 691, "else"
+       line 416, "pan.___", state 694, "(1)"
+       line 416, "pan.___", state 695, "(1)"
+       line 416, "pan.___", state 695, "(1)"
+       line 414, "pan.___", state 700, "((i<1))"
+       line 414, "pan.___", state 700, "((i>=1))"
+       line 421, "pan.___", state 707, "(1)"
+       line 421, "pan.___", state 708, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 708, "else"
+       line 421, "pan.___", state 711, "(1)"
+       line 421, "pan.___", state 712, "(1)"
+       line 421, "pan.___", state 712, "(1)"
+       line 425, "pan.___", state 720, "(1)"
+       line 425, "pan.___", state 721, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 721, "else"
+       line 425, "pan.___", state 724, "(1)"
+       line 425, "pan.___", state 725, "(1)"
+       line 425, "pan.___", state 725, "(1)"
+       line 423, "pan.___", state 730, "((i<2))"
+       line 423, "pan.___", state 730, "((i>=2))"
+       line 430, "pan.___", state 734, "(1)"
+       line 430, "pan.___", state 734, "(1)"
+       line 1085, "pan.___", state 738, "_proc_urcu_writer = (_proc_urcu_writer|(1<<10))"
+       line 395, "pan.___", state 743, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 745, "(1)"
+       line 395, "pan.___", state 746, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 746, "else"
+       line 395, "pan.___", state 749, "(1)"
+       line 399, "pan.___", state 757, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 759, "(1)"
+       line 399, "pan.___", state 760, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 760, "else"
+       line 399, "pan.___", state 763, "(1)"
+       line 399, "pan.___", state 764, "(1)"
+       line 399, "pan.___", state 764, "(1)"
+       line 397, "pan.___", state 769, "((i<1))"
+       line 397, "pan.___", state 769, "((i>=1))"
+       line 404, "pan.___", state 775, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 777, "(1)"
+       line 404, "pan.___", state 778, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 778, "else"
+       line 404, "pan.___", state 781, "(1)"
+       line 404, "pan.___", state 782, "(1)"
+       line 404, "pan.___", state 782, "(1)"
+       line 408, "pan.___", state 789, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 791, "(1)"
+       line 408, "pan.___", state 792, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 792, "else"
+       line 408, "pan.___", state 795, "(1)"
+       line 408, "pan.___", state 796, "(1)"
+       line 408, "pan.___", state 796, "(1)"
+       line 406, "pan.___", state 801, "((i<2))"
+       line 406, "pan.___", state 801, "((i>=2))"
+       line 412, "pan.___", state 808, "(1)"
+       line 412, "pan.___", state 809, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 809, "else"
+       line 412, "pan.___", state 812, "(1)"
+       line 412, "pan.___", state 813, "(1)"
+       line 412, "pan.___", state 813, "(1)"
+       line 416, "pan.___", state 821, "(1)"
+       line 416, "pan.___", state 822, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 822, "else"
+       line 416, "pan.___", state 825, "(1)"
+       line 416, "pan.___", state 826, "(1)"
+       line 416, "pan.___", state 826, "(1)"
+       line 414, "pan.___", state 831, "((i<1))"
+       line 414, "pan.___", state 831, "((i>=1))"
+       line 421, "pan.___", state 838, "(1)"
+       line 421, "pan.___", state 839, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 839, "else"
+       line 421, "pan.___", state 842, "(1)"
+       line 421, "pan.___", state 843, "(1)"
+       line 421, "pan.___", state 843, "(1)"
+       line 425, "pan.___", state 851, "(1)"
+       line 425, "pan.___", state 852, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 852, "else"
+       line 425, "pan.___", state 855, "(1)"
+       line 425, "pan.___", state 856, "(1)"
+       line 425, "pan.___", state 856, "(1)"
+       line 423, "pan.___", state 861, "((i<2))"
+       line 423, "pan.___", state 861, "((i>=2))"
+       line 430, "pan.___", state 865, "(1)"
+       line 430, "pan.___", state 865, "(1)"
+       line 1100, "pan.___", state 870, "_proc_urcu_writer = (_proc_urcu_writer|(1<<11))"
+       line 1095, "pan.___", state 871, "(((tmp2&((1<<7)-1))&&((tmp2^0)&(1<<7))))"
+       line 1095, "pan.___", state 871, "else"
+       line 1120, "pan.___", state 875, "_proc_urcu_writer = (_proc_urcu_writer&~(((1<<12)|(1<<11))))"
+       line 250, "pan.___", state 906, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 915, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 930, "(1)"
+       line 262, "pan.___", state 937, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 953, "(1)"
+       line 231, "pan.___", state 961, "(1)"
+       line 235, "pan.___", state 973, "(1)"
+       line 239, "pan.___", state 981, "(1)"
+       line 250, "pan.___", state 1012, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1021, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1034, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1043, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1059, "(1)"
+       line 231, "pan.___", state 1067, "(1)"
+       line 235, "pan.___", state 1079, "(1)"
+       line 239, "pan.___", state 1087, "(1)"
+       line 254, "pan.___", state 1113, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1126, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1135, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1151, "(1)"
+       line 231, "pan.___", state 1159, "(1)"
+       line 235, "pan.___", state 1171, "(1)"
+       line 239, "pan.___", state 1179, "(1)"
+       line 250, "pan.___", state 1210, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1219, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1232, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1241, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1257, "(1)"
+       line 231, "pan.___", state 1265, "(1)"
+       line 235, "pan.___", state 1277, "(1)"
+       line 239, "pan.___", state 1285, "(1)"
+       line 250, "pan.___", state 1302, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 250, "pan.___", state 1304, "(1)"
+       line 254, "pan.___", state 1311, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1313, "(1)"
+       line 254, "pan.___", state 1314, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 254, "pan.___", state 1314, "else"
+       line 252, "pan.___", state 1319, "((i<1))"
+       line 252, "pan.___", state 1319, "((i>=1))"
+       line 258, "pan.___", state 1324, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1326, "(1)"
+       line 258, "pan.___", state 1327, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 1327, "else"
+       line 262, "pan.___", state 1333, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1335, "(1)"
+       line 262, "pan.___", state 1336, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 262, "pan.___", state 1336, "else"
+       line 260, "pan.___", state 1341, "((i<2))"
+       line 260, "pan.___", state 1341, "((i>=2))"
+       line 227, "pan.___", state 1349, "(1)"
+       line 231, "pan.___", state 1357, "(1)"
+       line 231, "pan.___", state 1358, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 1358, "else"
+       line 229, "pan.___", state 1363, "((i<1))"
+       line 229, "pan.___", state 1363, "((i>=1))"
+       line 235, "pan.___", state 1369, "(1)"
+       line 235, "pan.___", state 1370, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 1370, "else"
+       line 239, "pan.___", state 1377, "(1)"
+       line 239, "pan.___", state 1378, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 1378, "else"
+       line 244, "pan.___", state 1387, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 1387, "else"
+       line 1196, "pan.___", state 1390, "i = 0"
+       line 1196, "pan.___", state 1392, "reader_barrier = 1"
+       line 1196, "pan.___", state 1403, "((i<1))"
+       line 1196, "pan.___", state 1403, "((i>=1))"
+       line 250, "pan.___", state 1408, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 250, "pan.___", state 1410, "(1)"
+       line 254, "pan.___", state 1417, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1419, "(1)"
+       line 254, "pan.___", state 1420, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 254, "pan.___", state 1420, "else"
+       line 252, "pan.___", state 1425, "((i<1))"
+       line 252, "pan.___", state 1425, "((i>=1))"
+       line 258, "pan.___", state 1430, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1432, "(1)"
+       line 258, "pan.___", state 1433, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 1433, "else"
+       line 262, "pan.___", state 1439, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1441, "(1)"
+       line 262, "pan.___", state 1442, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 262, "pan.___", state 1442, "else"
+       line 260, "pan.___", state 1447, "((i<2))"
+       line 260, "pan.___", state 1447, "((i>=2))"
+       line 227, "pan.___", state 1455, "(1)"
+       line 231, "pan.___", state 1463, "(1)"
+       line 231, "pan.___", state 1464, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 1464, "else"
+       line 229, "pan.___", state 1469, "((i<1))"
+       line 229, "pan.___", state 1469, "((i>=1))"
+       line 235, "pan.___", state 1475, "(1)"
+       line 235, "pan.___", state 1476, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 1476, "else"
+       line 239, "pan.___", state 1483, "(1)"
+       line 239, "pan.___", state 1484, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 1484, "else"
+       line 244, "pan.___", state 1493, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 1493, "else"
+       line 277, "pan.___", state 1495, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 277, "pan.___", state 1495, "else"
+       line 1196, "pan.___", state 1496, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 1196, "pan.___", state 1496, "else"
+       line 254, "pan.___", state 1509, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1522, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1531, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1547, "(1)"
+       line 231, "pan.___", state 1555, "(1)"
+       line 235, "pan.___", state 1567, "(1)"
+       line 239, "pan.___", state 1575, "(1)"
+       line 250, "pan.___", state 1606, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1615, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1628, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1637, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1653, "(1)"
+       line 231, "pan.___", state 1661, "(1)"
+       line 235, "pan.___", state 1673, "(1)"
+       line 239, "pan.___", state 1681, "(1)"
+       line 1204, "pan.___", state 1697, "-end-"
+       (242 of 1697 states)
+unreached in proctype :init:
+       line 1215, "pan.___", state 9, "((j<2))"
+       line 1215, "pan.___", state 9, "((j>=2))"
+       line 1216, "pan.___", state 20, "((j<2))"
+       line 1216, "pan.___", state 20, "((j>=2))"
+       line 1221, "pan.___", state 33, "((j<2))"
+       line 1221, "pan.___", state 33, "((j>=2))"
+       line 1219, "pan.___", state 43, "((i<1))"
+       line 1219, "pan.___", state 43, "((i>=1))"
+       line 1229, "pan.___", state 54, "((j<2))"
+       line 1229, "pan.___", state 54, "((j>=2))"
+       line 1233, "pan.___", state 67, "((j<2))"
+       line 1233, "pan.___", state 67, "((j>=2))"
+       (6 of 78 states)
+unreached in proctype :never:
+       line 1263, "pan.___", state 8, "-end-"
+       (1 of 8 states)
+
+pan: elapsed time 1.47e+03 seconds
+pan: rate 4207.2476 states/second
+pan: avg transition delay 1.3064e-06 usec
+cp .input.spin urcu_free_single_flip.spin.input
+cp .input.spin.trail urcu_free_single_flip.spin.input.trail
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_free_single_flip.spin.input b/formal-model/results/urcu-controldataflow-ipi/urcu_free_single_flip.spin.input
new file mode 100644 (file)
index 0000000..e7c3890
--- /dev/null
@@ -0,0 +1,1240 @@
+#define SINGLE_FLIP
+
+// Poison value for freed memory
+#define POISON 1
+// Memory with correct data
+#define WINE 0
+#define SLAB_SIZE 2
+
+#define read_poison    (data_read_first[0] == POISON || data_read_second[0] == POISON)
+
+#define RCU_GP_CTR_BIT (1 << 7)
+#define RCU_GP_CTR_NEST_MASK (RCU_GP_CTR_BIT - 1)
+
+//disabled
+#define REMOTE_BARRIERS
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+typedef per_proc_bit {
+       bit val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bitfield {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bitfield cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               /*
+                * 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, j);
+               reader_barrier[get_readerid()] = 0;
+       :: 1 ->
+               /*
+                * 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)
+//#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);                                                           \
+       i = 0;                                                                  \
+       do                                                                      \
+       :: i < NR_READERS ->                                                    \
+               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.                                            \
+                */                                                             \
+               do                                                              \
+               :: (reader_barrier[i] == 1) ->                                  \
+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(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, smp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only one reader */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* RCU data */
+DECLARE_CACHED_VAR(bit, rcu_data[SLAB_SIZE]);
+
+/* RCU pointer */
+#if (SLAB_SIZE == 2)
+DECLARE_CACHED_VAR(bit, rcu_ptr);
+bit ptr_read_first[NR_READERS];
+bit ptr_read_second[NR_READERS];
+#else
+DECLARE_CACHED_VAR(byte, rcu_ptr);
+byte ptr_read_first[NR_READERS];
+byte ptr_read_second[NR_READERS];
+#endif
+
+bit data_read_first[NR_READERS];
+bit data_read_second[NR_READERS];
+
+bit init_done = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               ptr_read_first[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb1;
+rmb1_end:
+                               data_read_first[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_first[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               ptr_read_second[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb2;
+rmb2_end:
+                               data_read_second[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_second[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+rmb1:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb1_end;
+rmb2:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_DATA                     (1 << 1)
+#define WRITE_PROC_WMB                 (1 << 2)
+#define WRITE_XCHG_PTR                 (1 << 3)
+
+#define WRITE_PROC_FIRST_MB            (1 << 4)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 5)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 6)
+#define WRITE_PROC_FIRST_WAIT          (1 << 7)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 8)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 9)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 10)
+#define WRITE_PROC_SECOND_WAIT         (1 << 11)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 12)
+
+#define WRITE_PROC_SECOND_MB           (1 << 13)
+
+#define WRITE_FREE                     (1 << 14)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_DATA                    \
+                                       | WRITE_PROC_WMB                \
+                                       | WRITE_XCHG_PTR                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB          \
+                                       | WRITE_FREE)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 15) - 1)
+
+/*
+ * Mutexes are implied around writer execution. A single writer at a time.
+ */
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte cur_data = 0, old_data, loop_nr = 0;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (loop_nr < 3) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               loop_nr = loop_nr + 1;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_WMB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+#endif
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_DATA) ->
+                       ooo_mem(i);
+                       cur_data = (cur_data + 1) % SLAB_SIZE;
+                       WRITE_CACHED_VAR(rcu_data[cur_data], WINE);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_DATA);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA,
+                                 WRITE_PROC_WMB) ->
+                       smp_wmb(i, j);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_WMB,
+                                 WRITE_XCHG_PTR) ->
+                       /* rcu_xchg_pointer() */
+                       atomic {
+                               old_data = READ_CACHED_VAR(rcu_ptr);
+                               WRITE_CACHED_VAR(rcu_ptr, cur_data);
+                       }
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_XCHG_PTR);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_WMB      /* No dependency on
+                                                        * WRITE_DATA because we
+                                                        * write to a
+                                                        * different location. */
+                                 | WRITE_PROC_SECOND_MB
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_FREE) ->
+                       WRITE_CACHED_VAR(rcu_data[old_data], POISON);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_FREE);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+               /*
+                * Note : Promela model adds implicit serialization of the
+                * WRITE_FREE instruction. Normally, it would be permitted to
+                * spill on the next loop execution. Given the validation we do
+                * checks for the data entry read to be poisoned, it's ok if
+                * we do not check "late arriving" memory poisoning.
+                */
+       :: 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
+#ifdef READER_PROGRESS
+               /*
+                * Make sure we don't block the reader's progress.
+                */
+               smp_mb_send(i, j, 5);
+#endif
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(rcu_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       ptr_read_first[i] = 1;
+                       ptr_read_second[i] = 1;
+                       data_read_first[i] = WINE;
+                       data_read_second[i] = WINE;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               INIT_CACHED_VAR(rcu_data[0], WINE, j);
+               i = 1;
+               do
+               :: i < SLAB_SIZE ->
+                       INIT_CACHED_VAR(rcu_data[i], POISON, j);
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_free_single_flip.spin.input.trail b/formal-model/results/urcu-controldataflow-ipi/urcu_free_single_flip.spin.input.trail
new file mode 100644 (file)
index 0000000..f09d0eb
--- /dev/null
@@ -0,0 +1,1386 @@
+-2:3:-2
+-4:-4:-4
+1:0:4646
+2:3:4566
+3:3:4569
+4:3:4569
+5:3:4572
+6:3:4580
+7:3:4580
+8:3:4583
+9:3:4589
+10:3:4593
+11:3:4593
+12:3:4596
+13:3:4606
+14:3:4614
+15:3:4614
+16:3:4617
+17:3:4623
+18:3:4627
+19:3:4627
+20:3:4630
+21:3:4636
+22:3:4640
+23:3:4641
+24:0:4646
+25:3:4643
+26:0:4646
+27:2:2871
+28:0:4646
+29:2:2877
+30:0:4646
+31:2:2878
+32:0:4646
+33:2:2880
+34:0:4646
+35:2:2881
+36:0:4646
+37:2:2882
+38:0:4646
+39:2:2883
+40:0:4646
+41:2:2884
+42:0:4646
+43:2:2885
+44:0:4646
+45:2:2886
+46:2:2887
+47:2:2891
+48:2:2892
+49:2:2900
+50:2:2901
+51:2:2905
+52:2:2906
+53:2:2914
+54:2:2919
+55:2:2923
+56:2:2924
+57:2:2932
+58:2:2933
+59:2:2937
+60:2:2938
+61:2:2932
+62:2:2933
+63:2:2937
+64:2:2938
+65:2:2946
+66:2:2951
+67:2:2952
+68:2:2963
+69:2:2964
+70:2:2965
+71:2:2976
+72:2:2981
+73:2:2982
+74:2:2993
+75:2:2994
+76:2:2995
+77:2:2993
+78:2:2994
+79:2:2995
+80:2:3006
+81:2:3014
+82:0:4646
+83:2:2885
+84:0:4646
+85:2:3018
+86:2:3022
+87:2:3023
+88:2:3027
+89:2:3031
+90:2:3032
+91:2:3036
+92:2:3044
+93:2:3045
+94:2:3049
+95:2:3053
+96:2:3054
+97:2:3049
+98:2:3050
+99:2:3058
+100:0:4646
+101:2:2885
+102:0:4646
+103:2:3066
+104:2:3067
+105:2:3068
+106:0:4646
+107:2:2885
+108:0:4646
+109:2:3073
+110:0:4646
+111:2:3775
+112:2:3776
+113:2:3780
+114:2:3784
+115:2:3785
+116:2:3789
+117:2:3794
+118:2:3802
+119:2:3806
+120:2:3807
+121:2:3802
+122:2:3806
+123:2:3807
+124:2:3811
+125:2:3818
+126:2:3825
+127:2:3826
+128:2:3833
+129:2:3838
+130:2:3845
+131:2:3846
+132:2:3845
+133:2:3846
+134:2:3853
+135:2:3857
+136:0:4646
+137:2:3862
+138:0:4646
+139:2:3863
+140:0:4646
+141:2:3864
+142:0:4646
+143:2:3865
+144:0:4646
+145:1:2
+146:0:4646
+147:2:3866
+148:0:4646
+149:1:8
+150:0:4646
+151:1:9
+152:0:4646
+153:2:3865
+154:0:4646
+155:1:10
+156:0:4646
+157:2:3866
+158:0:4646
+159:1:11
+160:0:4646
+161:2:3865
+162:0:4646
+163:1:12
+164:0:4646
+165:2:3866
+166:0:4646
+167:1:13
+168:0:4646
+169:2:3865
+170:0:4646
+171:1:14
+172:0:4646
+173:2:3866
+174:0:4646
+175:1:15
+176:0:4646
+177:1:16
+178:0:4646
+179:2:3865
+180:0:4646
+181:1:17
+182:0:4646
+183:2:3866
+184:0:4646
+185:1:26
+186:0:4646
+187:2:3865
+188:0:4646
+189:1:30
+190:1:31
+191:1:35
+192:1:39
+193:1:40
+194:1:44
+195:1:52
+196:1:53
+197:1:57
+198:1:61
+199:1:62
+200:1:57
+201:1:61
+202:1:62
+203:1:66
+204:1:73
+205:1:80
+206:1:81
+207:1:88
+208:1:93
+209:1:100
+210:1:101
+211:1:100
+212:1:101
+213:1:108
+214:1:112
+215:0:4646
+216:2:3866
+217:0:4646
+218:1:117
+219:0:4646
+220:2:3867
+221:0:4646
+222:2:3872
+223:0:4646
+224:2:3873
+225:0:4646
+226:2:3881
+227:2:3882
+228:2:3886
+229:2:3890
+230:2:3891
+231:2:3895
+232:2:3903
+233:2:3904
+234:2:3908
+235:2:3912
+236:2:3913
+237:2:3908
+238:2:3912
+239:2:3913
+240:2:3917
+241:2:3924
+242:2:3931
+243:2:3932
+244:2:3939
+245:2:3944
+246:2:3951
+247:2:3952
+248:2:3951
+249:2:3952
+250:2:3959
+251:2:3963
+252:0:4646
+253:2:3075
+254:2:3756
+255:0:4646
+256:2:2885
+257:0:4646
+258:2:3076
+259:0:4646
+260:2:2885
+261:0:4646
+262:2:3079
+263:2:3080
+264:2:3084
+265:2:3085
+266:2:3093
+267:2:3094
+268:2:3098
+269:2:3099
+270:2:3107
+271:2:3112
+272:2:3116
+273:2:3117
+274:2:3125
+275:2:3126
+276:2:3130
+277:2:3131
+278:2:3125
+279:2:3126
+280:2:3130
+281:2:3131
+282:2:3139
+283:2:3144
+284:2:3145
+285:2:3156
+286:2:3157
+287:2:3158
+288:2:3169
+289:2:3174
+290:2:3175
+291:2:3186
+292:2:3187
+293:2:3188
+294:2:3186
+295:2:3187
+296:2:3188
+297:2:3199
+298:2:3206
+299:0:4646
+300:2:2885
+301:0:4646
+302:2:3210
+303:2:3211
+304:2:3212
+305:2:3224
+306:2:3225
+307:2:3229
+308:2:3230
+309:2:3238
+310:2:3243
+311:2:3247
+312:2:3248
+313:2:3256
+314:2:3257
+315:2:3261
+316:2:3262
+317:2:3256
+318:2:3257
+319:2:3261
+320:2:3262
+321:2:3270
+322:2:3275
+323:2:3276
+324:2:3287
+325:2:3288
+326:2:3289
+327:2:3300
+328:2:3305
+329:2:3306
+330:2:3317
+331:2:3318
+332:2:3319
+333:2:3317
+334:2:3318
+335:2:3319
+336:2:3330
+337:2:3340
+338:2:3341
+339:0:4646
+340:2:2885
+341:0:4646
+342:2:3744
+343:0:4646
+344:2:4369
+345:2:4370
+346:2:4374
+347:2:4378
+348:2:4379
+349:2:4383
+350:2:4391
+351:2:4392
+352:2:4396
+353:2:4400
+354:2:4401
+355:2:4396
+356:2:4400
+357:2:4401
+358:2:4405
+359:2:4412
+360:2:4419
+361:2:4420
+362:2:4427
+363:2:4432
+364:2:4439
+365:2:4440
+366:2:4439
+367:2:4440
+368:2:4447
+369:2:4451
+370:0:4646
+371:2:4456
+372:0:4646
+373:2:4457
+374:0:4646
+375:2:4458
+376:0:4646
+377:2:4459
+378:0:4646
+379:1:118
+380:0:4646
+381:2:4460
+382:0:4646
+383:1:120
+384:0:4646
+385:2:4459
+386:0:4646
+387:1:19
+388:0:4646
+389:2:4460
+390:0:4646
+391:1:126
+392:1:127
+393:1:131
+394:1:132
+395:1:140
+396:1:141
+397:1:145
+398:1:146
+399:1:154
+400:1:159
+401:1:163
+402:1:164
+403:1:172
+404:1:173
+405:1:177
+406:1:178
+407:1:172
+408:1:173
+409:1:177
+410:1:178
+411:1:186
+412:1:198
+413:1:199
+414:1:203
+415:1:204
+416:1:205
+417:1:216
+418:1:221
+419:1:222
+420:1:233
+421:1:234
+422:1:235
+423:1:233
+424:1:234
+425:1:235
+426:1:246
+427:0:4646
+428:1:15
+429:0:4646
+430:1:16
+431:0:4646
+432:2:4459
+433:0:4646
+434:1:17
+435:0:4646
+436:2:4460
+437:0:4646
+438:1:118
+439:0:4646
+440:1:120
+441:0:4646
+442:2:4459
+443:0:4646
+444:1:19
+445:0:4646
+446:2:4460
+447:0:4646
+448:1:255
+449:1:256
+450:0:4646
+451:1:15
+452:0:4646
+453:1:16
+454:0:4646
+455:2:4459
+456:0:4646
+457:1:17
+458:0:4646
+459:2:4460
+460:0:4646
+461:1:118
+462:0:4646
+463:1:120
+464:0:4646
+465:2:4459
+466:0:4646
+467:1:19
+468:0:4646
+469:2:4460
+470:0:4646
+471:1:262
+472:1:263
+473:1:267
+474:1:268
+475:1:276
+476:1:277
+477:1:281
+478:1:282
+479:1:290
+480:1:295
+481:1:299
+482:1:300
+483:1:308
+484:1:309
+485:1:313
+486:1:314
+487:1:308
+488:1:309
+489:1:313
+490:1:314
+491:1:322
+492:1:334
+493:1:335
+494:1:339
+495:1:340
+496:1:341
+497:1:352
+498:1:357
+499:1:358
+500:1:369
+501:1:370
+502:1:371
+503:1:369
+504:1:370
+505:1:371
+506:1:382
+507:0:4646
+508:1:15
+509:0:4646
+510:1:16
+511:0:4646
+512:2:4459
+513:0:4646
+514:1:17
+515:0:4646
+516:2:4460
+517:0:4646
+518:1:26
+519:0:4646
+520:2:4459
+521:0:4646
+522:1:30
+523:1:31
+524:1:35
+525:1:39
+526:1:40
+527:1:44
+528:1:52
+529:1:53
+530:1:57
+531:1:61
+532:1:62
+533:1:57
+534:1:61
+535:1:62
+536:1:66
+537:1:73
+538:1:80
+539:1:81
+540:1:88
+541:1:93
+542:1:100
+543:1:101
+544:1:100
+545:1:101
+546:1:108
+547:1:112
+548:0:4646
+549:2:4460
+550:0:4646
+551:1:117
+552:0:4646
+553:2:4461
+554:0:4646
+555:2:4466
+556:0:4646
+557:2:4467
+558:0:4646
+559:2:4475
+560:2:4476
+561:2:4480
+562:2:4484
+563:2:4485
+564:2:4489
+565:2:4497
+566:2:4498
+567:2:4502
+568:2:4506
+569:2:4507
+570:2:4502
+571:2:4506
+572:2:4507
+573:2:4511
+574:2:4518
+575:2:4525
+576:2:4526
+577:2:4533
+578:2:4538
+579:2:4545
+580:2:4546
+581:2:4545
+582:2:4546
+583:2:4553
+584:2:4557
+585:0:4646
+586:2:3746
+587:2:3756
+588:0:4646
+589:2:2885
+590:0:4646
+591:2:3747
+592:2:3748
+593:0:4646
+594:2:2885
+595:0:4646
+596:2:3752
+597:0:4646
+598:2:3760
+599:0:4646
+600:2:2878
+601:0:4646
+602:2:2880
+603:0:4646
+604:2:2881
+605:0:4646
+606:2:2882
+607:0:4646
+608:2:2883
+609:0:4646
+610:2:2884
+611:0:4646
+612:2:2885
+613:0:4646
+614:2:2886
+615:2:2887
+616:2:2891
+617:2:2892
+618:2:2900
+619:2:2901
+620:2:2905
+621:2:2906
+622:2:2914
+623:2:2919
+624:2:2923
+625:2:2924
+626:2:2932
+627:2:2933
+628:2:2934
+629:2:2932
+630:2:2933
+631:2:2937
+632:2:2938
+633:2:2946
+634:2:2951
+635:2:2952
+636:2:2963
+637:2:2964
+638:2:2965
+639:2:2976
+640:2:2981
+641:2:2982
+642:2:2993
+643:2:2994
+644:2:2995
+645:2:2993
+646:2:2994
+647:2:2995
+648:2:3006
+649:2:3014
+650:0:4646
+651:2:2885
+652:0:4646
+653:2:3018
+654:2:3022
+655:2:3023
+656:2:3027
+657:2:3031
+658:2:3032
+659:2:3036
+660:2:3044
+661:2:3045
+662:2:3049
+663:2:3050
+664:2:3049
+665:2:3053
+666:2:3054
+667:2:3058
+668:0:4646
+669:2:2885
+670:0:4646
+671:2:3066
+672:2:3067
+673:2:3068
+674:0:4646
+675:2:2885
+676:0:4646
+677:2:3073
+678:0:4646
+679:2:3775
+680:2:3776
+681:2:3780
+682:2:3784
+683:2:3785
+684:2:3789
+685:2:3794
+686:2:3802
+687:2:3806
+688:2:3807
+689:2:3802
+690:2:3806
+691:2:3807
+692:2:3811
+693:2:3818
+694:2:3825
+695:2:3826
+696:2:3833
+697:2:3838
+698:2:3845
+699:2:3846
+700:2:3845
+701:2:3846
+702:2:3853
+703:2:3857
+704:0:4646
+705:2:3862
+706:0:4646
+707:2:3863
+708:0:4646
+709:2:3864
+710:0:4646
+711:2:3865
+712:0:4646
+713:1:118
+714:0:4646
+715:2:3866
+716:0:4646
+717:1:120
+718:0:4646
+719:2:3865
+720:0:4646
+721:1:19
+722:0:4646
+723:2:3866
+724:0:4646
+725:1:391
+726:1:392
+727:1:396
+728:1:397
+729:1:405
+730:1:406
+731:1:410
+732:1:411
+733:1:419
+734:1:424
+735:1:428
+736:1:429
+737:1:437
+738:1:438
+739:1:442
+740:1:443
+741:1:437
+742:1:438
+743:1:442
+744:1:443
+745:1:451
+746:1:456
+747:1:457
+748:1:468
+749:1:469
+750:1:470
+751:1:481
+752:1:493
+753:1:494
+754:1:498
+755:1:499
+756:1:500
+757:1:498
+758:1:499
+759:1:500
+760:1:511
+761:1:518
+762:0:4646
+763:1:15
+764:0:4646
+765:1:16
+766:0:4646
+767:2:3865
+768:0:4646
+769:1:17
+770:0:4646
+771:2:3866
+772:0:4646
+773:1:118
+774:0:4646
+775:1:120
+776:0:4646
+777:2:3865
+778:0:4646
+779:1:19
+780:0:4646
+781:2:3866
+782:0:4646
+783:1:656
+784:1:657
+785:1:661
+786:1:662
+787:1:670
+788:1:671
+789:1:672
+790:1:684
+791:1:689
+792:1:693
+793:1:694
+794:1:702
+795:1:703
+796:1:707
+797:1:708
+798:1:702
+799:1:703
+800:1:707
+801:1:708
+802:1:716
+803:1:721
+804:1:722
+805:1:733
+806:1:734
+807:1:735
+808:1:746
+809:1:758
+810:1:759
+811:1:763
+812:1:764
+813:1:765
+814:1:763
+815:1:764
+816:1:765
+817:1:776
+818:0:4646
+819:1:15
+820:0:4646
+821:1:16
+822:0:4646
+823:2:3865
+824:0:4646
+825:1:17
+826:0:4646
+827:2:3866
+828:0:4646
+829:1:118
+830:0:4646
+831:1:120
+832:0:4646
+833:2:3865
+834:0:4646
+835:1:19
+836:0:4646
+837:2:3866
+838:0:4646
+839:1:785
+840:1:788
+841:1:789
+842:0:4646
+843:1:15
+844:0:4646
+845:1:16
+846:0:4646
+847:2:3865
+848:0:4646
+849:1:17
+850:0:4646
+851:2:3866
+852:0:4646
+853:1:118
+854:0:4646
+855:1:120
+856:0:4646
+857:2:3865
+858:0:4646
+859:1:19
+860:0:4646
+861:2:3866
+862:0:4646
+863:1:1052
+864:1:1053
+865:1:1057
+866:1:1058
+867:1:1066
+868:1:1067
+869:1:1071
+870:1:1072
+871:1:1080
+872:1:1085
+873:1:1089
+874:1:1090
+875:1:1098
+876:1:1099
+877:1:1103
+878:1:1104
+879:1:1098
+880:1:1099
+881:1:1103
+882:1:1104
+883:1:1112
+884:1:1117
+885:1:1118
+886:1:1129
+887:1:1130
+888:1:1131
+889:1:1142
+890:1:1154
+891:1:1155
+892:1:1159
+893:1:1160
+894:1:1161
+895:1:1159
+896:1:1160
+897:1:1161
+898:1:1172
+899:1:1179
+900:1:1183
+901:0:4646
+902:1:15
+903:0:4646
+904:1:16
+905:0:4646
+906:2:3865
+907:0:4646
+908:1:17
+909:0:4646
+910:2:3866
+911:0:4646
+912:1:118
+913:0:4646
+914:1:120
+915:0:4646
+916:2:3865
+917:0:4646
+918:1:19
+919:0:4646
+920:2:3866
+921:0:4646
+922:1:1184
+923:1:1185
+924:1:1189
+925:1:1190
+926:1:1198
+927:1:1199
+928:1:1200
+929:1:1212
+930:1:1217
+931:1:1221
+932:1:1222
+933:1:1230
+934:1:1231
+935:1:1235
+936:1:1236
+937:1:1230
+938:1:1231
+939:1:1235
+940:1:1236
+941:1:1244
+942:1:1249
+943:1:1250
+944:1:1261
+945:1:1262
+946:1:1263
+947:1:1274
+948:1:1286
+949:1:1287
+950:1:1291
+951:1:1292
+952:1:1293
+953:1:1291
+954:1:1292
+955:1:1293
+956:1:1304
+957:0:4646
+958:1:15
+959:0:4646
+960:1:16
+961:0:4646
+962:2:3865
+963:0:4646
+964:1:17
+965:0:4646
+966:2:3866
+967:0:4646
+968:1:26
+969:0:4646
+970:2:3865
+971:0:4646
+972:1:30
+973:1:31
+974:1:35
+975:1:39
+976:1:40
+977:1:44
+978:1:52
+979:1:53
+980:1:57
+981:1:61
+982:1:62
+983:1:57
+984:1:61
+985:1:62
+986:1:66
+987:1:73
+988:1:80
+989:1:81
+990:1:88
+991:1:93
+992:1:100
+993:1:101
+994:1:100
+995:1:101
+996:1:108
+997:1:112
+998:0:4646
+999:2:3866
+1000:0:4646
+1001:1:117
+1002:0:4646
+1003:2:3867
+1004:0:4646
+1005:2:3872
+1006:0:4646
+1007:2:3873
+1008:0:4646
+1009:2:3881
+1010:2:3882
+1011:2:3886
+1012:2:3890
+1013:2:3891
+1014:2:3895
+1015:2:3903
+1016:2:3904
+1017:2:3908
+1018:2:3912
+1019:2:3913
+1020:2:3908
+1021:2:3912
+1022:2:3913
+1023:2:3917
+1024:2:3924
+1025:2:3931
+1026:2:3932
+1027:2:3939
+1028:2:3944
+1029:2:3951
+1030:2:3952
+1031:2:3951
+1032:2:3952
+1033:2:3959
+1034:2:3963
+1035:0:4646
+1036:2:3075
+1037:2:3756
+1038:0:4646
+1039:2:2885
+1040:0:4646
+1041:2:3076
+1042:0:4646
+1043:2:2885
+1044:0:4646
+1045:2:3079
+1046:2:3080
+1047:2:3084
+1048:2:3085
+1049:2:3093
+1050:2:3094
+1051:2:3098
+1052:2:3099
+1053:2:3107
+1054:2:3112
+1055:2:3116
+1056:2:3117
+1057:2:3125
+1058:2:3126
+1059:2:3130
+1060:2:3131
+1061:2:3125
+1062:2:3126
+1063:2:3130
+1064:2:3131
+1065:2:3139
+1066:2:3144
+1067:2:3145
+1068:2:3156
+1069:2:3157
+1070:2:3158
+1071:2:3169
+1072:2:3174
+1073:2:3175
+1074:2:3186
+1075:2:3187
+1076:2:3188
+1077:2:3186
+1078:2:3187
+1079:2:3188
+1080:2:3199
+1081:2:3206
+1082:0:4646
+1083:2:2885
+1084:0:4646
+1085:2:3210
+1086:2:3211
+1087:2:3212
+1088:2:3224
+1089:2:3225
+1090:2:3229
+1091:2:3230
+1092:2:3238
+1093:2:3243
+1094:2:3247
+1095:2:3248
+1096:2:3256
+1097:2:3257
+1098:2:3261
+1099:2:3262
+1100:2:3256
+1101:2:3257
+1102:2:3261
+1103:2:3262
+1104:2:3270
+1105:2:3275
+1106:2:3276
+1107:2:3287
+1108:2:3288
+1109:2:3289
+1110:2:3300
+1111:2:3305
+1112:2:3306
+1113:2:3317
+1114:2:3318
+1115:2:3319
+1116:2:3317
+1117:2:3318
+1118:2:3319
+1119:2:3330
+1120:2:3340
+1121:2:3341
+1122:0:4646
+1123:2:2885
+1124:0:4646
+1125:2:3744
+1126:0:4646
+1127:2:4369
+1128:2:4370
+1129:2:4374
+1130:2:4378
+1131:2:4379
+1132:2:4383
+1133:2:4391
+1134:2:4392
+1135:2:4396
+1136:2:4400
+1137:2:4401
+1138:2:4396
+1139:2:4400
+1140:2:4401
+1141:2:4405
+1142:2:4412
+1143:2:4419
+1144:2:4420
+1145:2:4427
+1146:2:4432
+1147:2:4439
+1148:2:4440
+1149:2:4439
+1150:2:4440
+1151:2:4447
+1152:2:4451
+1153:0:4646
+1154:2:4456
+1155:0:4646
+1156:2:4457
+1157:0:4646
+1158:2:4458
+1159:0:4646
+1160:2:4459
+1161:0:4646
+1162:1:26
+1163:0:4646
+1164:2:4460
+1165:0:4646
+1166:1:30
+1167:1:31
+1168:1:35
+1169:1:39
+1170:1:40
+1171:1:44
+1172:1:52
+1173:1:53
+1174:1:57
+1175:1:61
+1176:1:62
+1177:1:57
+1178:1:61
+1179:1:62
+1180:1:66
+1181:1:73
+1182:1:80
+1183:1:81
+1184:1:88
+1185:1:93
+1186:1:100
+1187:1:101
+1188:1:100
+1189:1:101
+1190:1:108
+1191:1:112
+1192:0:4646
+1193:2:4459
+1194:0:4646
+1195:1:117
+1196:0:4646
+1197:2:4460
+1198:0:4646
+1199:2:4461
+1200:0:4646
+1201:2:4466
+1202:0:4646
+1203:2:4467
+1204:0:4646
+1205:2:4475
+1206:2:4476
+1207:2:4480
+1208:2:4484
+1209:2:4485
+1210:2:4489
+1211:2:4497
+1212:2:4498
+1213:2:4502
+1214:2:4506
+1215:2:4507
+1216:2:4502
+1217:2:4506
+1218:2:4507
+1219:2:4511
+1220:2:4518
+1221:2:4525
+1222:2:4526
+1223:2:4533
+1224:2:4538
+1225:2:4545
+1226:2:4546
+1227:2:4545
+1228:2:4546
+1229:2:4553
+1230:2:4557
+1231:0:4646
+1232:2:3746
+1233:2:3756
+1234:0:4646
+1235:2:2885
+1236:0:4646
+1237:2:3747
+1238:2:3748
+1239:0:4646
+1240:2:2885
+1241:0:4646
+1242:2:3752
+1243:0:4646
+1244:2:3760
+1245:0:4646
+1246:2:2878
+1247:0:4646
+1248:2:2880
+1249:0:4646
+1250:2:2881
+1251:0:4646
+1252:2:2882
+1253:0:4646
+1254:2:2883
+1255:0:4646
+1256:2:2884
+1257:0:4646
+1258:2:2885
+1259:0:4646
+1260:2:2886
+1261:2:2887
+1262:2:2891
+1263:2:2892
+1264:2:2900
+1265:2:2901
+1266:2:2905
+1267:2:2906
+1268:2:2914
+1269:2:2919
+1270:2:2923
+1271:2:2924
+1272:2:2932
+1273:2:2933
+1274:2:2937
+1275:2:2938
+1276:2:2932
+1277:2:2933
+1278:2:2934
+1279:2:2946
+1280:2:2951
+1281:2:2952
+1282:2:2963
+1283:2:2964
+1284:2:2965
+1285:2:2976
+1286:2:2981
+1287:2:2982
+1288:2:2993
+1289:2:2994
+1290:2:2995
+1291:2:2993
+1292:2:2994
+1293:2:2995
+1294:2:3006
+1295:2:3014
+1296:0:4646
+1297:2:2885
+1298:0:4646
+1299:1:118
+1300:0:4646
+1301:1:120
+1302:0:4646
+1303:1:19
+1304:0:4646
+1305:1:1313
+1306:0:4646
+1307:1:2777
+1308:1:2784
+1309:1:2785
+1310:1:2792
+1311:1:2797
+1312:1:2804
+1313:1:2805
+1314:1:2804
+1315:1:2805
+1316:1:2812
+1317:1:2816
+1318:0:4646
+1319:2:3018
+1320:2:3022
+1321:2:3023
+1322:2:3027
+1323:2:3031
+1324:2:3032
+1325:2:3036
+1326:2:3044
+1327:2:3045
+1328:2:3049
+1329:2:3053
+1330:2:3054
+1331:2:3049
+1332:2:3050
+1333:2:3058
+1334:0:4646
+1335:2:2885
+1336:0:4646
+1337:2:3066
+1338:2:3067
+1339:2:3068
+1340:0:4646
+1341:2:2885
+1342:0:4646
+1343:2:3073
+1344:0:4646
+1345:2:3775
+1346:2:3776
+1347:2:3780
+1348:2:3784
+1349:2:3785
+1350:2:3789
+1351:2:3794
+1352:2:3802
+1353:2:3806
+1354:2:3807
+1355:2:3802
+1356:2:3806
+1357:2:3807
+1358:2:3811
+1359:2:3818
+1360:2:3825
+1361:2:3826
+1362:2:3833
+1363:2:3838
+1364:2:3845
+1365:2:3846
+1366:2:3845
+1367:2:3846
+1368:2:3853
+1369:2:3857
+1370:0:4646
+1371:2:3862
+1372:0:4646
+1373:2:3863
+1374:0:4646
+1375:2:3864
+1376:0:4646
+1377:2:3865
+1378:0:4646
+1379:1:1315
+1380:1:1316
+1381:0:4644
+1382:2:3866
+1383:0:4650
+1384:1:2431
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_progress.ltl b/formal-model/results/urcu-controldataflow-ipi/urcu_progress.ltl
new file mode 100644 (file)
index 0000000..8718641
--- /dev/null
@@ -0,0 +1 @@
+([] <> !np_)
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_progress_reader.define b/formal-model/results/urcu-controldataflow-ipi/urcu_progress_reader.define
new file mode 100644 (file)
index 0000000..ff3f783
--- /dev/null
@@ -0,0 +1 @@
+#define READER_PROGRESS
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_progress_reader.log b/formal-model/results/urcu-controldataflow-ipi/urcu_progress_reader.log
new file mode 100644 (file)
index 0000000..e493a0c
--- /dev/null
@@ -0,0 +1,597 @@
+rm -f pan* trail.out .input.spin* *.spin.trail .input.define
+touch .input.define
+cat .input.define > pan.ltl
+cat DEFINES >> pan.ltl
+spin -f "!(`cat urcu_progress.ltl | grep -v ^//`)" >> pan.ltl
+cp urcu_progress_reader.define .input.define
+cat .input.define > .input.spin
+cat DEFINES >> .input.spin
+cat urcu.spin >> .input.spin
+rm -f .input.spin.trail
+spin -a -X -N pan.ltl .input.spin
+Exit-Status 0
+gcc -O2 -w -DHASH64 -o pan pan.c
+./pan -a -f -v -c1 -X -m10000000 -w20
+warning: for p.o. reduction to be valid the never claim must be stutter-invariant
+(never claims generated from LTL formulae are stutter-invariant)
+depth 0: Claim reached state 5 (line 1258)
+depth 23: Claim reached state 9 (line 1263)
+depth 137: Claim reached state 9 (line 1262)
+Depth=   31896 States=    1e+06 Transitions= 1.91e+08 Memory=   519.963        t=    240 R=   4e+03
+Depth=   35611 States=    2e+06 Transitions= 3.82e+08 Memory=   572.111        t=    484 R=   4e+03
+Depth=   35611 States=    3e+06 Transitions= 6.15e+08 Memory=   623.869        t=    790 R=   4e+03
+pan: resizing hashtable to -w22..  done
+Depth=   35611 States=    4e+06 Transitions= 8.15e+08 Memory=   707.236        t= 1.04e+03 R=   4e+03
+Depth=   35611 States=    5e+06 Transitions=    1e+09 Memory=   760.557        t= 1.28e+03 R=   4e+03
+Depth=   35611 States=    6e+06 Transitions= 1.33e+09 Memory=   808.408        t= 1.71e+03 R=   4e+03
+Depth=   35611 States=    7e+06 Transitions= 1.79e+09 Memory=   854.014        t= 2.32e+03 R=   3e+03
+Depth=   35611 States=    8e+06 Transitions= 2.33e+09 Memory=   898.740        t= 3.05e+03 R=   3e+03
+Depth=   35611 States=    9e+06 Transitions= 2.72e+09 Memory=   947.276        t= 3.57e+03 R=   3e+03
+pan: resizing hashtable to -w24..  done
+Depth=   35611 States=    1e+07 Transitions= 3.17e+09 Memory=  1119.123        t= 4.17e+03 R=   2e+03
+Depth=   35611 States=  1.1e+07 Transitions= 3.43e+09 Memory=  1167.854        t= 4.5e+03 R=   2e+03
+Depth=   35611 States=  1.2e+07 Transitions= 3.67e+09 Memory=  1219.221        t= 4.81e+03 R=   2e+03
+Depth=   35611 States=  1.3e+07 Transitions= 4.19e+09 Memory=  1262.776        t= 5.49e+03 R=   2e+03
+Depth=   35611 States=  1.4e+07 Transitions= 5.17e+09 Memory=  1311.213        t= 6.83e+03 R=   2e+03
+Depth=   35611 States=  1.5e+07 Transitions= 6.13e+09 Memory=  1349.006        t= 8.12e+03 R=   2e+03
+Depth=   35611 States=  1.6e+07 Transitions= 6.65e+09 Memory=  1393.635        t= 8.82e+03 R=   2e+03
+Depth=   35611 States=  1.7e+07 Transitions= 7.12e+09 Memory=  1441.779        t= 9.45e+03 R=   2e+03
+Depth=   35611 States=  1.8e+07 Transitions= 7.52e+09 Memory=  1486.408        t= 9.98e+03 R=   2e+03
+Depth=   35611 States=  1.9e+07 Transitions= 8.03e+09 Memory=  1534.162        t= 1.07e+04 R=   2e+03
+Depth=   35611 States=    2e+07 Transitions=  8.6e+09 Memory=  1579.768        t= 1.14e+04 R=   2e+03
+Depth=   35611 States=  2.1e+07 Transitions=    9e+09 Memory=  1629.475        t= 1.2e+04 R=   2e+03
+Depth=   35611 States=  2.2e+07 Transitions= 9.32e+09 Memory=  1676.545        t= 1.24e+04 R=   2e+03
+Depth=   35611 States=  2.3e+07 Transitions= 9.66e+09 Memory=  1724.494        t= 1.29e+04 R=   2e+03
+Depth=   35611 States=  2.4e+07 Transitions=    1e+10 Memory=  1774.299        t= 1.34e+04 R=   2e+03
+Depth=   35611 States=  2.5e+07 Transitions= 1.03e+10 Memory=  1822.151        t= 1.37e+04 R=   2e+03
+Depth=   35611 States=  2.6e+07 Transitions= 1.07e+10 Memory=  1871.272        t= 1.42e+04 R=   2e+03
+Depth=   35611 States=  2.7e+07 Transitions= 1.09e+10 Memory=  1921.272        t= 1.45e+04 R=   2e+03
+Depth=   35611 States=  2.8e+07 Transitions= 1.13e+10 Memory=  1969.904        t= 1.51e+04 R=   2e+03
+Depth=   35611 States=  2.9e+07 Transitions= 1.15e+10 Memory=  2019.709        t= 1.54e+04 R=   2e+03
+Depth=   35611 States=    3e+07 Transitions=  1.2e+10 Memory=  2063.654        t= 1.6e+04 R=   2e+03
+Depth=   35611 States=  3.1e+07 Transitions= 1.23e+10 Memory=  2110.920        t= 1.65e+04 R=   2e+03
+Depth=   35611 States=  3.2e+07 Transitions= 1.29e+10 Memory=  2156.721        t= 1.73e+04 R=   2e+03
+Depth=   35611 States=  3.3e+07 Transitions= 1.35e+10 Memory=  2200.276        t= 1.8e+04 R=   2e+03
+Depth=   35611 States=  3.4e+07 Transitions=  1.4e+10 Memory=  2245.881        t= 1.87e+04 R=   2e+03
+pan: resizing hashtable to -w26..  done
+Depth=   35611 States=  3.5e+07 Transitions= 1.43e+10 Memory=  2790.498        t= 1.91e+04 R=   2e+03
+Depth=   35611 States=  3.6e+07 Transitions= 1.45e+10 Memory=  2841.182        t= 1.94e+04 R=   2e+03
+Depth=   35611 States=  3.7e+07 Transitions= 1.49e+10 Memory=  2887.861        t= 1.99e+04 R=   2e+03
+Depth=   35611 States=  3.8e+07 Transitions= 1.57e+10 Memory=  2934.346        t= 2.1e+04 R=   2e+03
+Depth=   35611 States=  3.9e+07 Transitions= 1.67e+10 Memory=  2977.608        t= 2.23e+04 R=   2e+03
+Depth=   35611 States=    4e+07 Transitions= 1.74e+10 Memory=  3017.158        t= 2.33e+04 R=   2e+03
+Depth=   35611 States=  4.1e+07 Transitions= 1.81e+10 Memory=  3061.104        t= 2.42e+04 R=   2e+03
+Depth=   35611 States=  4.2e+07 Transitions= 1.83e+10 Memory=  3109.932        t= 2.45e+04 R=   2e+03
+Depth=   35611 States=  4.3e+07 Transitions= 1.88e+10 Memory=  3156.416        t= 2.51e+04 R=   2e+03
+Depth=   35611 States=  4.4e+07 Transitions= 1.93e+10 Memory=  3203.389        t= 2.58e+04 R=   2e+03
+Depth=   35611 States=  4.5e+07 Transitions= 1.98e+10 Memory=  3249.580        t= 2.65e+04 R=   2e+03
+Depth=   35611 States=  4.6e+07 Transitions= 2.02e+10 Memory=  3297.920        t= 2.69e+04 R=   2e+03
+Depth=   35611 States=  4.7e+07 Transitions= 2.06e+10 Memory=  3347.236        t= 2.75e+04 R=   2e+03
+Depth=   35611 States=  4.8e+07 Transitions= 2.09e+10 Memory=  3395.772        t= 2.79e+04 R=   2e+03
+Depth=   35611 States=  4.9e+07 Transitions= 2.12e+10 Memory=  3443.818        t= 2.83e+04 R=   2e+03
+Depth=   35611 States=    5e+07 Transitions= 2.15e+10 Memory=  3492.549        t= 2.87e+04 R=   2e+03
+Depth=   35611 States=  5.1e+07 Transitions= 2.18e+10 Memory=  3540.303        t= 2.91e+04 R=   2e+03
+Depth=   35611 States=  5.2e+07 Transitions= 2.21e+10 Memory=  3591.377        t= 2.95e+04 R=   2e+03
+Depth=   35611 States=  5.3e+07 Transitions= 2.24e+10 Memory=  3639.326        t=  3e+04 R=   2e+03
+Depth=   35611 States=  5.4e+07 Transitions= 2.27e+10 Memory=  3687.373        t= 3.04e+04 R=   2e+03
+Depth=   35611 States=  5.5e+07 Transitions= 2.31e+10 Memory=  3733.662        t= 3.09e+04 R=   2e+03
+Depth=   35611 States=  5.6e+07 Transitions= 2.37e+10 Memory=  3779.561        t= 3.16e+04 R=   2e+03
+Depth=   35611 States=  5.7e+07 Transitions= 2.42e+10 Memory=  3823.213        t= 3.24e+04 R=   2e+03
+Depth=   35611 States=  5.8e+07 Transitions= 2.47e+10 Memory=  3869.795        t= 3.3e+04 R=   2e+03
+Depth=   35611 States=  5.9e+07 Transitions= 2.52e+10 Memory=  3916.084        t= 3.37e+04 R=   2e+03
+
+(Spin Version 5.1.7 -- 23 December 2008)
+       + Partial Order Reduction
+
+Full statespace search for:
+       never claim             +
+       assertion violations    + (if within scope of claim)
+       acceptance   cycles     + (fairness enabled)
+       invalid end states      - (disabled by never claim)
+
+State-vector 88 byte, depth reached 35611, errors: 0
+ 33837266 states, stored (5.99297e+07 visited)
+2.557894e+10 states, matched
+2.563887e+10 transitions (= visited+matched)
+1.4922421e+11 atomic steps
+hash conflicts: 9.616061e+09 (resolved)
+
+Stats on memory usage (in Megabytes):
+ 3743.289      equivalent memory usage for states (stored*(State-vector + overhead))
+ 2990.875      actual memory usage for states (compression: 79.90%)
+               state-vector as stored = 65 byte + 28 byte overhead
+  512.000      memory used for hash table (-w26)
+  457.764      memory used for DFS stack (-m10000000)
+    1.683      memory lost to fragmentation
+ 3958.955      total actual memory usage
+
+unreached in proctype urcu_reader
+       line 250, "pan.___", state 30, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 52, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 61, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 77, "(1)"
+       line 231, "pan.___", state 85, "(1)"
+       line 235, "pan.___", state 97, "(1)"
+       line 239, "pan.___", state 105, "(1)"
+       line 395, "pan.___", state 131, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 163, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 177, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 196, "(1)"
+       line 421, "pan.___", state 226, "(1)"
+       line 425, "pan.___", state 239, "(1)"
+       line 670, "pan.___", state 260, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<1))"
+       line 395, "pan.___", state 267, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 299, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 313, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 332, "(1)"
+       line 421, "pan.___", state 362, "(1)"
+       line 425, "pan.___", state 375, "(1)"
+       line 395, "pan.___", state 396, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 428, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 442, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 461, "(1)"
+       line 421, "pan.___", state 491, "(1)"
+       line 425, "pan.___", state 504, "(1)"
+       line 395, "pan.___", state 527, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 529, "(1)"
+       line 395, "pan.___", state 530, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 530, "else"
+       line 395, "pan.___", state 533, "(1)"
+       line 399, "pan.___", state 541, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 543, "(1)"
+       line 399, "pan.___", state 544, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 544, "else"
+       line 399, "pan.___", state 547, "(1)"
+       line 399, "pan.___", state 548, "(1)"
+       line 399, "pan.___", state 548, "(1)"
+       line 397, "pan.___", state 553, "((i<1))"
+       line 397, "pan.___", state 553, "((i>=1))"
+       line 404, "pan.___", state 559, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 561, "(1)"
+       line 404, "pan.___", state 562, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 562, "else"
+       line 404, "pan.___", state 565, "(1)"
+       line 404, "pan.___", state 566, "(1)"
+       line 404, "pan.___", state 566, "(1)"
+       line 408, "pan.___", state 573, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 575, "(1)"
+       line 408, "pan.___", state 576, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 576, "else"
+       line 408, "pan.___", state 579, "(1)"
+       line 408, "pan.___", state 580, "(1)"
+       line 408, "pan.___", state 580, "(1)"
+       line 406, "pan.___", state 585, "((i<2))"
+       line 406, "pan.___", state 585, "((i>=2))"
+       line 412, "pan.___", state 592, "(1)"
+       line 412, "pan.___", state 593, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 593, "else"
+       line 412, "pan.___", state 596, "(1)"
+       line 412, "pan.___", state 597, "(1)"
+       line 412, "pan.___", state 597, "(1)"
+       line 416, "pan.___", state 605, "(1)"
+       line 416, "pan.___", state 606, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 606, "else"
+       line 416, "pan.___", state 609, "(1)"
+       line 416, "pan.___", state 610, "(1)"
+       line 416, "pan.___", state 610, "(1)"
+       line 414, "pan.___", state 615, "((i<1))"
+       line 414, "pan.___", state 615, "((i>=1))"
+       line 421, "pan.___", state 622, "(1)"
+       line 421, "pan.___", state 623, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 623, "else"
+       line 421, "pan.___", state 626, "(1)"
+       line 421, "pan.___", state 627, "(1)"
+       line 421, "pan.___", state 627, "(1)"
+       line 425, "pan.___", state 635, "(1)"
+       line 425, "pan.___", state 636, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 636, "else"
+       line 425, "pan.___", state 639, "(1)"
+       line 425, "pan.___", state 640, "(1)"
+       line 425, "pan.___", state 640, "(1)"
+       line 423, "pan.___", state 645, "((i<2))"
+       line 423, "pan.___", state 645, "((i>=2))"
+       line 430, "pan.___", state 649, "(1)"
+       line 430, "pan.___", state 649, "(1)"
+       line 670, "pan.___", state 652, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 670, "pan.___", state 653, "_proc_urcu_reader = (_proc_urcu_reader|(1<<5))"
+       line 670, "pan.___", state 654, "(1)"
+       line 395, "pan.___", state 661, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 693, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 707, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 726, "(1)"
+       line 421, "pan.___", state 756, "(1)"
+       line 425, "pan.___", state 769, "(1)"
+       line 395, "pan.___", state 797, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 799, "(1)"
+       line 395, "pan.___", state 800, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 800, "else"
+       line 395, "pan.___", state 803, "(1)"
+       line 399, "pan.___", state 811, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 813, "(1)"
+       line 399, "pan.___", state 814, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 814, "else"
+       line 399, "pan.___", state 817, "(1)"
+       line 399, "pan.___", state 818, "(1)"
+       line 399, "pan.___", state 818, "(1)"
+       line 397, "pan.___", state 823, "((i<1))"
+       line 397, "pan.___", state 823, "((i>=1))"
+       line 404, "pan.___", state 829, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 831, "(1)"
+       line 404, "pan.___", state 832, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 832, "else"
+       line 404, "pan.___", state 835, "(1)"
+       line 404, "pan.___", state 836, "(1)"
+       line 404, "pan.___", state 836, "(1)"
+       line 408, "pan.___", state 843, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 845, "(1)"
+       line 408, "pan.___", state 846, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 846, "else"
+       line 408, "pan.___", state 849, "(1)"
+       line 408, "pan.___", state 850, "(1)"
+       line 408, "pan.___", state 850, "(1)"
+       line 406, "pan.___", state 855, "((i<2))"
+       line 406, "pan.___", state 855, "((i>=2))"
+       line 412, "pan.___", state 862, "(1)"
+       line 412, "pan.___", state 863, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 863, "else"
+       line 412, "pan.___", state 866, "(1)"
+       line 412, "pan.___", state 867, "(1)"
+       line 412, "pan.___", state 867, "(1)"
+       line 416, "pan.___", state 875, "(1)"
+       line 416, "pan.___", state 876, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 876, "else"
+       line 416, "pan.___", state 879, "(1)"
+       line 416, "pan.___", state 880, "(1)"
+       line 416, "pan.___", state 880, "(1)"
+       line 414, "pan.___", state 885, "((i<1))"
+       line 414, "pan.___", state 885, "((i>=1))"
+       line 421, "pan.___", state 892, "(1)"
+       line 421, "pan.___", state 893, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 893, "else"
+       line 421, "pan.___", state 896, "(1)"
+       line 421, "pan.___", state 897, "(1)"
+       line 421, "pan.___", state 897, "(1)"
+       line 425, "pan.___", state 905, "(1)"
+       line 425, "pan.___", state 906, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 906, "else"
+       line 425, "pan.___", state 909, "(1)"
+       line 425, "pan.___", state 910, "(1)"
+       line 425, "pan.___", state 910, "(1)"
+       line 430, "pan.___", state 919, "(1)"
+       line 430, "pan.___", state 919, "(1)"
+       line 395, "pan.___", state 926, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 928, "(1)"
+       line 395, "pan.___", state 929, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 929, "else"
+       line 395, "pan.___", state 932, "(1)"
+       line 399, "pan.___", state 940, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 942, "(1)"
+       line 399, "pan.___", state 943, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 943, "else"
+       line 399, "pan.___", state 946, "(1)"
+       line 399, "pan.___", state 947, "(1)"
+       line 399, "pan.___", state 947, "(1)"
+       line 397, "pan.___", state 952, "((i<1))"
+       line 397, "pan.___", state 952, "((i>=1))"
+       line 404, "pan.___", state 958, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 960, "(1)"
+       line 404, "pan.___", state 961, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 961, "else"
+       line 404, "pan.___", state 964, "(1)"
+       line 404, "pan.___", state 965, "(1)"
+       line 404, "pan.___", state 965, "(1)"
+       line 408, "pan.___", state 972, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 974, "(1)"
+       line 408, "pan.___", state 975, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 975, "else"
+       line 408, "pan.___", state 978, "(1)"
+       line 408, "pan.___", state 979, "(1)"
+       line 408, "pan.___", state 979, "(1)"
+       line 406, "pan.___", state 984, "((i<2))"
+       line 406, "pan.___", state 984, "((i>=2))"
+       line 412, "pan.___", state 991, "(1)"
+       line 412, "pan.___", state 992, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 992, "else"
+       line 412, "pan.___", state 995, "(1)"
+       line 412, "pan.___", state 996, "(1)"
+       line 412, "pan.___", state 996, "(1)"
+       line 416, "pan.___", state 1004, "(1)"
+       line 416, "pan.___", state 1005, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 1005, "else"
+       line 416, "pan.___", state 1008, "(1)"
+       line 416, "pan.___", state 1009, "(1)"
+       line 416, "pan.___", state 1009, "(1)"
+       line 414, "pan.___", state 1014, "((i<1))"
+       line 414, "pan.___", state 1014, "((i>=1))"
+       line 421, "pan.___", state 1021, "(1)"
+       line 421, "pan.___", state 1022, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 1022, "else"
+       line 421, "pan.___", state 1025, "(1)"
+       line 421, "pan.___", state 1026, "(1)"
+       line 421, "pan.___", state 1026, "(1)"
+       line 425, "pan.___", state 1034, "(1)"
+       line 425, "pan.___", state 1035, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 1035, "else"
+       line 425, "pan.___", state 1038, "(1)"
+       line 425, "pan.___", state 1039, "(1)"
+       line 425, "pan.___", state 1039, "(1)"
+       line 423, "pan.___", state 1044, "((i<2))"
+       line 423, "pan.___", state 1044, "((i>=2))"
+       line 430, "pan.___", state 1048, "(1)"
+       line 430, "pan.___", state 1048, "(1)"
+       line 678, "pan.___", state 1052, "_proc_urcu_reader = (_proc_urcu_reader|(1<<11))"
+       line 395, "pan.___", state 1057, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1089, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1103, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1122, "(1)"
+       line 421, "pan.___", state 1152, "(1)"
+       line 425, "pan.___", state 1165, "(1)"
+       line 395, "pan.___", state 1189, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1221, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1235, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1254, "(1)"
+       line 421, "pan.___", state 1284, "(1)"
+       line 425, "pan.___", state 1297, "(1)"
+       line 395, "pan.___", state 1322, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1354, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1368, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1387, "(1)"
+       line 421, "pan.___", state 1417, "(1)"
+       line 425, "pan.___", state 1430, "(1)"
+       line 395, "pan.___", state 1451, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1483, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1497, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1516, "(1)"
+       line 421, "pan.___", state 1546, "(1)"
+       line 425, "pan.___", state 1559, "(1)"
+       line 395, "pan.___", state 1585, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1617, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1631, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1650, "(1)"
+       line 421, "pan.___", state 1680, "(1)"
+       line 425, "pan.___", state 1693, "(1)"
+       line 395, "pan.___", state 1714, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1746, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1760, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1779, "(1)"
+       line 421, "pan.___", state 1809, "(1)"
+       line 425, "pan.___", state 1822, "(1)"
+       line 395, "pan.___", state 1846, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1878, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1892, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1911, "(1)"
+       line 421, "pan.___", state 1941, "(1)"
+       line 425, "pan.___", state 1954, "(1)"
+       line 717, "pan.___", state 1975, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<19))"
+       line 395, "pan.___", state 1982, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2014, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2028, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2047, "(1)"
+       line 421, "pan.___", state 2077, "(1)"
+       line 425, "pan.___", state 2090, "(1)"
+       line 395, "pan.___", state 2111, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2143, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2157, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2176, "(1)"
+       line 421, "pan.___", state 2206, "(1)"
+       line 425, "pan.___", state 2219, "(1)"
+       line 395, "pan.___", state 2242, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 2244, "(1)"
+       line 395, "pan.___", state 2245, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 2245, "else"
+       line 395, "pan.___", state 2248, "(1)"
+       line 399, "pan.___", state 2256, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 2258, "(1)"
+       line 399, "pan.___", state 2259, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 2259, "else"
+       line 399, "pan.___", state 2262, "(1)"
+       line 399, "pan.___", state 2263, "(1)"
+       line 399, "pan.___", state 2263, "(1)"
+       line 397, "pan.___", state 2268, "((i<1))"
+       line 397, "pan.___", state 2268, "((i>=1))"
+       line 404, "pan.___", state 2274, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2276, "(1)"
+       line 404, "pan.___", state 2277, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 2277, "else"
+       line 404, "pan.___", state 2280, "(1)"
+       line 404, "pan.___", state 2281, "(1)"
+       line 404, "pan.___", state 2281, "(1)"
+       line 408, "pan.___", state 2288, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2290, "(1)"
+       line 408, "pan.___", state 2291, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 2291, "else"
+       line 408, "pan.___", state 2294, "(1)"
+       line 408, "pan.___", state 2295, "(1)"
+       line 408, "pan.___", state 2295, "(1)"
+       line 406, "pan.___", state 2300, "((i<2))"
+       line 406, "pan.___", state 2300, "((i>=2))"
+       line 412, "pan.___", state 2307, "(1)"
+       line 412, "pan.___", state 2308, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 2308, "else"
+       line 412, "pan.___", state 2311, "(1)"
+       line 412, "pan.___", state 2312, "(1)"
+       line 412, "pan.___", state 2312, "(1)"
+       line 416, "pan.___", state 2320, "(1)"
+       line 416, "pan.___", state 2321, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 2321, "else"
+       line 416, "pan.___", state 2324, "(1)"
+       line 416, "pan.___", state 2325, "(1)"
+       line 416, "pan.___", state 2325, "(1)"
+       line 414, "pan.___", state 2330, "((i<1))"
+       line 414, "pan.___", state 2330, "((i>=1))"
+       line 421, "pan.___", state 2337, "(1)"
+       line 421, "pan.___", state 2338, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 2338, "else"
+       line 421, "pan.___", state 2341, "(1)"
+       line 421, "pan.___", state 2342, "(1)"
+       line 421, "pan.___", state 2342, "(1)"
+       line 425, "pan.___", state 2350, "(1)"
+       line 425, "pan.___", state 2351, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 2351, "else"
+       line 425, "pan.___", state 2354, "(1)"
+       line 425, "pan.___", state 2355, "(1)"
+       line 425, "pan.___", state 2355, "(1)"
+       line 423, "pan.___", state 2360, "((i<2))"
+       line 423, "pan.___", state 2360, "((i>=2))"
+       line 430, "pan.___", state 2364, "(1)"
+       line 430, "pan.___", state 2364, "(1)"
+       line 717, "pan.___", state 2367, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 717, "pan.___", state 2368, "_proc_urcu_reader = (_proc_urcu_reader|(1<<23))"
+       line 717, "pan.___", state 2369, "(1)"
+       line 395, "pan.___", state 2376, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2408, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2422, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2441, "(1)"
+       line 421, "pan.___", state 2471, "(1)"
+       line 425, "pan.___", state 2484, "(1)"
+       line 395, "pan.___", state 2511, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2543, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2557, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2576, "(1)"
+       line 421, "pan.___", state 2606, "(1)"
+       line 425, "pan.___", state 2619, "(1)"
+       line 395, "pan.___", state 2640, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2672, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2686, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2705, "(1)"
+       line 421, "pan.___", state 2735, "(1)"
+       line 425, "pan.___", state 2748, "(1)"
+       line 227, "pan.___", state 2781, "(1)"
+       line 235, "pan.___", state 2801, "(1)"
+       line 239, "pan.___", state 2809, "(1)"
+       line 227, "pan.___", state 2824, "(1)"
+       line 235, "pan.___", state 2844, "(1)"
+       line 239, "pan.___", state 2852, "(1)"
+       line 877, "pan.___", state 2869, "-end-"
+       (278 of 2869 states)
+unreached in proctype urcu_writer
+       line 395, "pan.___", state 18, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 32, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 50, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 83, "(1)"
+       line 416, "pan.___", state 96, "(1)"
+       line 421, "pan.___", state 113, "(1)"
+       line 250, "pan.___", state 149, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 158, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 171, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 211, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 225, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 243, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 257, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 276, "(1)"
+       line 416, "pan.___", state 289, "(1)"
+       line 421, "pan.___", state 306, "(1)"
+       line 425, "pan.___", state 319, "(1)"
+       line 399, "pan.___", state 356, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 374, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 388, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 420, "(1)"
+       line 421, "pan.___", state 437, "(1)"
+       line 425, "pan.___", state 450, "(1)"
+       line 399, "pan.___", state 494, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 512, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 526, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 558, "(1)"
+       line 421, "pan.___", state 575, "(1)"
+       line 425, "pan.___", state 588, "(1)"
+       line 399, "pan.___", state 623, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 641, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 655, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 687, "(1)"
+       line 421, "pan.___", state 704, "(1)"
+       line 425, "pan.___", state 717, "(1)"
+       line 399, "pan.___", state 754, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 772, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 786, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 818, "(1)"
+       line 421, "pan.___", state 835, "(1)"
+       line 425, "pan.___", state 848, "(1)"
+       line 250, "pan.___", state 898, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 907, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 920, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 945, "(1)"
+       line 231, "pan.___", state 953, "(1)"
+       line 235, "pan.___", state 965, "(1)"
+       line 239, "pan.___", state 973, "(1)"
+       line 250, "pan.___", state 1004, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1013, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1026, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1035, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1051, "(1)"
+       line 231, "pan.___", state 1059, "(1)"
+       line 235, "pan.___", state 1071, "(1)"
+       line 239, "pan.___", state 1079, "(1)"
+       line 250, "pan.___", state 1100, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1109, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1124, "(1)"
+       line 262, "pan.___", state 1131, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1147, "(1)"
+       line 231, "pan.___", state 1155, "(1)"
+       line 235, "pan.___", state 1167, "(1)"
+       line 239, "pan.___", state 1175, "(1)"
+       line 250, "pan.___", state 1206, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1215, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1228, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1237, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1253, "(1)"
+       line 231, "pan.___", state 1261, "(1)"
+       line 235, "pan.___", state 1273, "(1)"
+       line 239, "pan.___", state 1281, "(1)"
+       line 254, "pan.___", state 1307, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1320, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1329, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1345, "(1)"
+       line 231, "pan.___", state 1353, "(1)"
+       line 235, "pan.___", state 1365, "(1)"
+       line 239, "pan.___", state 1373, "(1)"
+       line 250, "pan.___", state 1404, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1413, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1426, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1435, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1451, "(1)"
+       line 231, "pan.___", state 1459, "(1)"
+       line 235, "pan.___", state 1471, "(1)"
+       line 239, "pan.___", state 1479, "(1)"
+       line 254, "pan.___", state 1505, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1518, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1527, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1543, "(1)"
+       line 231, "pan.___", state 1551, "(1)"
+       line 235, "pan.___", state 1563, "(1)"
+       line 239, "pan.___", state 1571, "(1)"
+       line 250, "pan.___", state 1602, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1611, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1624, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1633, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1649, "(1)"
+       line 231, "pan.___", state 1657, "(1)"
+       line 235, "pan.___", state 1669, "(1)"
+       line 239, "pan.___", state 1677, "(1)"
+       line 254, "pan.___", state 1703, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1716, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1725, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1741, "(1)"
+       line 231, "pan.___", state 1749, "(1)"
+       line 235, "pan.___", state 1761, "(1)"
+       line 239, "pan.___", state 1769, "(1)"
+       line 250, "pan.___", state 1800, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1809, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1822, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1831, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1847, "(1)"
+       line 231, "pan.___", state 1855, "(1)"
+       line 235, "pan.___", state 1867, "(1)"
+       line 239, "pan.___", state 1875, "(1)"
+       line 1204, "pan.___", state 1891, "-end-"
+       (118 of 1891 states)
+unreached in proctype :init:
+       (0 of 78 states)
+unreached in proctype :never:
+       line 1265, "pan.___", state 11, "-end-"
+       (1 of 11 states)
+
+pan: elapsed time 3.42e+04 seconds
+pan: rate 1751.5295 states/second
+pan: avg transition delay 1.3345e-06 usec
+cp .input.spin urcu_progress_reader.spin.input
+cp .input.spin.trail urcu_progress_reader.spin.input.trail
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_progress_reader.spin.input b/formal-model/results/urcu-controldataflow-ipi/urcu_progress_reader.spin.input
new file mode 100644 (file)
index 0000000..fc0b3ae
--- /dev/null
@@ -0,0 +1,1240 @@
+#define READER_PROGRESS
+
+// Poison value for freed memory
+#define POISON 1
+// Memory with correct data
+#define WINE 0
+#define SLAB_SIZE 2
+
+#define read_poison    (data_read_first[0] == POISON || data_read_second[0] == POISON)
+
+#define RCU_GP_CTR_BIT (1 << 7)
+#define RCU_GP_CTR_NEST_MASK (RCU_GP_CTR_BIT - 1)
+
+//disabled
+#define REMOTE_BARRIERS
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+typedef per_proc_bit {
+       bit val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bitfield {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bitfield cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               /*
+                * 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, j);
+               reader_barrier[get_readerid()] = 0;
+       :: 1 ->
+               /*
+                * 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)
+//#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);                                                           \
+       i = 0;                                                                  \
+       do                                                                      \
+       :: i < NR_READERS ->                                                    \
+               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.                                            \
+                */                                                             \
+               do                                                              \
+               :: (reader_barrier[i] == 1) ->                                  \
+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(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, smp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only one reader */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* RCU data */
+DECLARE_CACHED_VAR(bit, rcu_data[SLAB_SIZE]);
+
+/* RCU pointer */
+#if (SLAB_SIZE == 2)
+DECLARE_CACHED_VAR(bit, rcu_ptr);
+bit ptr_read_first[NR_READERS];
+bit ptr_read_second[NR_READERS];
+#else
+DECLARE_CACHED_VAR(byte, rcu_ptr);
+byte ptr_read_first[NR_READERS];
+byte ptr_read_second[NR_READERS];
+#endif
+
+bit data_read_first[NR_READERS];
+bit data_read_second[NR_READERS];
+
+bit init_done = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               ptr_read_first[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb1;
+rmb1_end:
+                               data_read_first[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_first[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               ptr_read_second[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb2;
+rmb2_end:
+                               data_read_second[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_second[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+rmb1:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb1_end;
+rmb2:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_DATA                     (1 << 1)
+#define WRITE_PROC_WMB                 (1 << 2)
+#define WRITE_XCHG_PTR                 (1 << 3)
+
+#define WRITE_PROC_FIRST_MB            (1 << 4)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 5)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 6)
+#define WRITE_PROC_FIRST_WAIT          (1 << 7)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 8)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 9)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 10)
+#define WRITE_PROC_SECOND_WAIT         (1 << 11)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 12)
+
+#define WRITE_PROC_SECOND_MB           (1 << 13)
+
+#define WRITE_FREE                     (1 << 14)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_DATA                    \
+                                       | WRITE_PROC_WMB                \
+                                       | WRITE_XCHG_PTR                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB          \
+                                       | WRITE_FREE)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 15) - 1)
+
+/*
+ * Mutexes are implied around writer execution. A single writer at a time.
+ */
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte cur_data = 0, old_data, loop_nr = 0;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (loop_nr < 3) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               loop_nr = loop_nr + 1;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_WMB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+#endif
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_DATA) ->
+                       ooo_mem(i);
+                       cur_data = (cur_data + 1) % SLAB_SIZE;
+                       WRITE_CACHED_VAR(rcu_data[cur_data], WINE);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_DATA);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA,
+                                 WRITE_PROC_WMB) ->
+                       smp_wmb(i, j);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_WMB,
+                                 WRITE_XCHG_PTR) ->
+                       /* rcu_xchg_pointer() */
+                       atomic {
+                               old_data = READ_CACHED_VAR(rcu_ptr);
+                               WRITE_CACHED_VAR(rcu_ptr, cur_data);
+                       }
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_XCHG_PTR);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_WMB      /* No dependency on
+                                                        * WRITE_DATA because we
+                                                        * write to a
+                                                        * different location. */
+                                 | WRITE_PROC_SECOND_MB
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_FREE) ->
+                       WRITE_CACHED_VAR(rcu_data[old_data], POISON);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_FREE);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+               /*
+                * Note : Promela model adds implicit serialization of the
+                * WRITE_FREE instruction. Normally, it would be permitted to
+                * spill on the next loop execution. Given the validation we do
+                * checks for the data entry read to be poisoned, it's ok if
+                * we do not check "late arriving" memory poisoning.
+                */
+       :: 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
+#ifdef READER_PROGRESS
+               /*
+                * Make sure we don't block the reader's progress.
+                */
+               smp_mb_send(i, j, 5);
+#endif
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(rcu_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       ptr_read_first[i] = 1;
+                       ptr_read_second[i] = 1;
+                       data_read_first[i] = WINE;
+                       data_read_second[i] = WINE;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               INIT_CACHED_VAR(rcu_data[0], WINE, j);
+               i = 1;
+               do
+               :: i < SLAB_SIZE ->
+                       INIT_CACHED_VAR(rcu_data[i], POISON, j);
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_progress_reader.spin.input.trail b/formal-model/results/urcu-controldataflow-ipi/urcu_progress_reader.spin.input.trail
new file mode 100644 (file)
index 0000000..a0cf98c
--- /dev/null
@@ -0,0 +1,1767 @@
+-2:3:-2
+-4:-4:-4
+1:0:4840
+2:3:4760
+3:3:4763
+4:3:4763
+5:3:4766
+6:3:4774
+7:3:4774
+8:3:4777
+9:3:4783
+10:3:4787
+11:3:4787
+12:3:4790
+13:3:4800
+14:3:4808
+15:3:4808
+16:3:4811
+17:3:4817
+18:3:4821
+19:3:4821
+20:3:4824
+21:3:4830
+22:3:4834
+23:3:4835
+24:0:4840
+25:3:4837
+26:0:4840
+27:2:2871
+28:0:4840
+29:2:2877
+30:0:4840
+31:2:2878
+32:0:4840
+33:2:2880
+34:0:4840
+35:2:2881
+36:0:4840
+37:2:2882
+38:2:2883
+39:2:2887
+40:2:2888
+41:2:2896
+42:2:2897
+43:2:2901
+44:2:2902
+45:2:2910
+46:2:2915
+47:2:2919
+48:2:2920
+49:2:2928
+50:2:2929
+51:2:2933
+52:2:2934
+53:2:2928
+54:2:2929
+55:2:2933
+56:2:2934
+57:2:2942
+58:2:2947
+59:2:2948
+60:2:2959
+61:2:2960
+62:2:2961
+63:2:2972
+64:2:2977
+65:2:2978
+66:2:2989
+67:2:2990
+68:2:2991
+69:2:2989
+70:2:2990
+71:2:2991
+72:2:3002
+73:2:3010
+74:0:4840
+75:2:2881
+76:0:4840
+77:2:3014
+78:2:3018
+79:2:3019
+80:2:3023
+81:2:3027
+82:2:3028
+83:2:3032
+84:2:3040
+85:2:3041
+86:2:3045
+87:2:3049
+88:2:3050
+89:2:3045
+90:2:3046
+91:2:3054
+92:0:4840
+93:2:2881
+94:0:4840
+95:2:3062
+96:2:3063
+97:2:3064
+98:0:4840
+99:2:2881
+100:0:4840
+101:2:3069
+102:0:4840
+103:2:3969
+104:2:3970
+105:2:3974
+106:2:3978
+107:2:3979
+108:2:3983
+109:2:3988
+110:2:3996
+111:2:4000
+112:2:4001
+113:2:3996
+114:2:4000
+115:2:4001
+116:2:4005
+117:2:4012
+118:2:4019
+119:2:4020
+120:2:4027
+121:2:4032
+122:2:4039
+123:2:4040
+124:2:4039
+125:2:4040
+126:2:4047
+127:2:4051
+128:0:4840
+129:2:4056
+130:0:4840
+131:2:4057
+132:0:4840
+133:2:4058
+134:0:4840
+135:2:4059
+136:0:4840
+137:1:2
+138:0:4840
+139:1:8
+140:0:4840
+141:2:4060
+142:0:4840
+143:1:9
+144:0:4840
+145:2:4059
+146:0:4840
+147:1:10
+148:0:4840
+149:2:4060
+150:0:4838
+151:1:11
+152:0:4844
+153:1:12
+154:0:4844
+155:1:13
+156:0:4844
+157:1:14
+158:0:4844
+159:1:15
+160:0:4844
+161:1:16
+162:0:4844
+163:1:17
+164:0:4844
+165:1:26
+166:0:4844
+167:1:30
+168:1:31
+169:1:35
+170:1:39
+171:1:40
+172:1:44
+173:1:52
+174:1:53
+175:1:57
+176:1:61
+177:1:62
+178:1:57
+179:1:61
+180:1:62
+181:1:66
+182:1:73
+183:1:80
+184:1:81
+185:1:88
+186:1:93
+187:1:100
+188:1:101
+189:1:100
+190:1:101
+191:1:108
+192:1:112
+193:0:4844
+194:1:117
+195:0:4844
+196:2:4061
+197:0:4844
+198:2:4066
+199:0:4844
+200:2:4067
+201:0:4844
+202:2:4075
+203:2:4076
+204:2:4080
+205:2:4084
+206:2:4085
+207:2:4089
+208:2:4097
+209:2:4098
+210:2:4102
+211:2:4106
+212:2:4107
+213:2:4102
+214:2:4106
+215:2:4107
+216:2:4111
+217:2:4118
+218:2:4125
+219:2:4126
+220:2:4133
+221:2:4138
+222:2:4145
+223:2:4146
+224:2:4145
+225:2:4146
+226:2:4153
+227:2:4157
+228:0:4844
+229:2:3071
+230:2:3753
+231:0:4844
+232:2:2881
+233:0:4844
+234:2:3072
+235:0:4844
+236:2:2881
+237:0:4844
+238:2:3075
+239:2:3076
+240:2:3080
+241:2:3081
+242:2:3089
+243:2:3090
+244:2:3094
+245:2:3095
+246:2:3103
+247:2:3108
+248:2:3112
+249:2:3113
+250:2:3121
+251:2:3122
+252:2:3126
+253:2:3127
+254:2:3121
+255:2:3122
+256:2:3126
+257:2:3127
+258:2:3135
+259:2:3140
+260:2:3141
+261:2:3152
+262:2:3153
+263:2:3154
+264:2:3165
+265:2:3170
+266:2:3171
+267:2:3182
+268:2:3183
+269:2:3184
+270:2:3182
+271:2:3183
+272:2:3184
+273:2:3195
+274:2:3202
+275:0:4844
+276:2:2881
+277:0:4844
+278:2:3206
+279:2:3207
+280:2:3208
+281:2:3220
+282:2:3221
+283:2:3225
+284:2:3226
+285:2:3234
+286:2:3239
+287:2:3243
+288:2:3244
+289:2:3252
+290:2:3253
+291:2:3257
+292:2:3258
+293:2:3252
+294:2:3253
+295:2:3257
+296:2:3258
+297:2:3266
+298:2:3271
+299:2:3272
+300:2:3283
+301:2:3284
+302:2:3285
+303:2:3296
+304:2:3301
+305:2:3302
+306:2:3313
+307:2:3314
+308:2:3315
+309:2:3313
+310:2:3314
+311:2:3315
+312:2:3326
+313:2:3337
+314:2:3338
+315:0:4844
+316:2:2881
+317:0:4844
+318:2:3344
+319:2:3345
+320:2:3349
+321:2:3350
+322:2:3358
+323:2:3359
+324:2:3363
+325:2:3364
+326:2:3372
+327:2:3377
+328:2:3381
+329:2:3382
+330:2:3390
+331:2:3391
+332:2:3395
+333:2:3396
+334:2:3390
+335:2:3391
+336:2:3395
+337:2:3396
+338:2:3404
+339:2:3409
+340:2:3410
+341:2:3421
+342:2:3422
+343:2:3423
+344:2:3434
+345:2:3439
+346:2:3440
+347:2:3451
+348:2:3452
+349:2:3453
+350:2:3451
+351:2:3452
+352:2:3453
+353:2:3464
+354:0:4844
+355:2:2881
+356:0:4844
+357:2:3473
+358:2:3474
+359:2:3478
+360:2:3479
+361:2:3487
+362:2:3488
+363:2:3492
+364:2:3493
+365:2:3501
+366:2:3506
+367:2:3510
+368:2:3511
+369:2:3519
+370:2:3520
+371:2:3524
+372:2:3525
+373:2:3519
+374:2:3520
+375:2:3524
+376:2:3525
+377:2:3533
+378:2:3538
+379:2:3539
+380:2:3550
+381:2:3551
+382:2:3552
+383:2:3563
+384:2:3568
+385:2:3569
+386:2:3580
+387:2:3581
+388:2:3582
+389:2:3580
+390:2:3581
+391:2:3582
+392:2:3593
+393:2:3600
+394:0:4844
+395:2:2881
+396:0:4844
+397:2:3604
+398:2:3605
+399:2:3606
+400:2:3618
+401:2:3619
+402:2:3623
+403:2:3624
+404:2:3632
+405:2:3637
+406:2:3641
+407:2:3642
+408:2:3650
+409:2:3651
+410:2:3655
+411:2:3656
+412:2:3650
+413:2:3651
+414:2:3655
+415:2:3656
+416:2:3664
+417:2:3669
+418:2:3670
+419:2:3681
+420:2:3682
+421:2:3683
+422:2:3694
+423:2:3699
+424:2:3700
+425:2:3711
+426:2:3712
+427:2:3713
+428:2:3711
+429:2:3712
+430:2:3713
+431:2:3724
+432:2:3734
+433:2:3735
+434:0:4844
+435:2:2881
+436:0:4844
+437:2:3741
+438:0:4844
+439:2:4563
+440:2:4564
+441:2:4568
+442:2:4572
+443:2:4573
+444:2:4577
+445:2:4585
+446:2:4586
+447:2:4590
+448:2:4594
+449:2:4595
+450:2:4590
+451:2:4594
+452:2:4595
+453:2:4599
+454:2:4606
+455:2:4613
+456:2:4614
+457:2:4621
+458:2:4626
+459:2:4633
+460:2:4634
+461:2:4633
+462:2:4634
+463:2:4641
+464:2:4645
+465:0:4844
+466:2:4650
+467:0:4844
+468:2:4651
+469:0:4844
+470:2:4652
+471:0:4844
+472:1:26
+473:0:4844
+474:1:30
+475:1:31
+476:1:35
+477:1:39
+478:1:40
+479:1:44
+480:1:52
+481:1:53
+482:1:57
+483:1:61
+484:1:62
+485:1:57
+486:1:61
+487:1:62
+488:1:66
+489:1:73
+490:1:80
+491:1:81
+492:1:88
+493:1:93
+494:1:100
+495:1:101
+496:1:100
+497:1:101
+498:1:108
+499:1:112
+500:0:4844
+501:1:117
+502:0:4844
+503:2:4655
+504:0:4844
+505:2:4660
+506:0:4844
+507:2:4661
+508:0:4844
+509:2:4669
+510:2:4670
+511:2:4674
+512:2:4678
+513:2:4679
+514:2:4683
+515:2:4691
+516:2:4692
+517:2:4696
+518:2:4700
+519:2:4701
+520:2:4696
+521:2:4700
+522:2:4701
+523:2:4705
+524:2:4712
+525:2:4719
+526:2:4720
+527:2:4727
+528:2:4732
+529:2:4739
+530:2:4740
+531:2:4739
+532:2:4740
+533:2:4747
+534:2:4751
+535:0:4844
+536:2:3743
+537:2:3753
+538:0:4844
+539:2:2881
+540:0:4844
+541:2:3744
+542:2:3745
+543:0:4844
+544:2:2881
+545:0:4844
+546:2:3749
+547:0:4844
+548:2:3757
+549:0:4844
+550:2:2878
+551:0:4844
+552:2:2880
+553:0:4844
+554:2:2881
+555:0:4844
+556:2:2882
+557:2:2883
+558:2:2887
+559:2:2888
+560:2:2896
+561:2:2897
+562:2:2901
+563:2:2902
+564:2:2910
+565:2:2915
+566:2:2919
+567:2:2920
+568:2:2928
+569:2:2929
+570:2:2930
+571:2:2928
+572:2:2929
+573:2:2933
+574:2:2934
+575:2:2942
+576:2:2947
+577:2:2948
+578:2:2959
+579:2:2960
+580:2:2961
+581:2:2972
+582:2:2977
+583:2:2978
+584:2:2989
+585:2:2990
+586:2:2991
+587:2:2989
+588:2:2990
+589:2:2991
+590:2:3002
+591:2:3010
+592:0:4844
+593:2:2881
+594:0:4844
+595:2:3014
+596:2:3018
+597:2:3019
+598:2:3023
+599:2:3027
+600:2:3028
+601:2:3032
+602:2:3040
+603:2:3041
+604:2:3045
+605:2:3046
+606:2:3045
+607:2:3049
+608:2:3050
+609:2:3054
+610:0:4844
+611:2:2881
+612:0:4844
+613:2:3062
+614:2:3063
+615:2:3064
+616:0:4844
+617:2:2881
+618:0:4844
+619:2:3069
+620:0:4844
+621:2:3969
+622:2:3970
+623:2:3974
+624:2:3978
+625:2:3979
+626:2:3983
+627:2:3988
+628:2:3996
+629:2:4000
+630:2:4001
+631:2:3996
+632:2:4000
+633:2:4001
+634:2:4005
+635:2:4012
+636:2:4019
+637:2:4020
+638:2:4027
+639:2:4032
+640:2:4039
+641:2:4040
+642:2:4039
+643:2:4040
+644:2:4047
+645:2:4051
+646:0:4844
+647:2:4056
+648:0:4844
+649:2:4057
+650:0:4844
+651:2:4058
+652:0:4844
+653:1:26
+654:0:4844
+655:1:30
+656:1:31
+657:1:35
+658:1:39
+659:1:40
+660:1:44
+661:1:52
+662:1:53
+663:1:57
+664:1:61
+665:1:62
+666:1:57
+667:1:61
+668:1:62
+669:1:66
+670:1:73
+671:1:80
+672:1:81
+673:1:88
+674:1:93
+675:1:100
+676:1:101
+677:1:100
+678:1:101
+679:1:108
+680:1:112
+681:0:4844
+682:1:117
+683:0:4844
+684:2:4061
+685:0:4844
+686:2:4066
+687:0:4844
+688:2:4067
+689:0:4844
+690:2:4075
+691:2:4076
+692:2:4080
+693:2:4084
+694:2:4085
+695:2:4089
+696:2:4097
+697:2:4098
+698:2:4102
+699:2:4106
+700:2:4107
+701:2:4102
+702:2:4106
+703:2:4107
+704:2:4111
+705:2:4118
+706:2:4125
+707:2:4126
+708:2:4133
+709:2:4138
+710:2:4145
+711:2:4146
+712:2:4145
+713:2:4146
+714:2:4153
+715:2:4157
+716:0:4844
+717:2:3071
+718:2:3753
+719:0:4844
+720:2:2881
+721:0:4844
+722:2:3072
+723:0:4844
+724:2:2881
+725:0:4844
+726:2:3075
+727:2:3076
+728:2:3080
+729:2:3081
+730:2:3089
+731:2:3090
+732:2:3094
+733:2:3095
+734:2:3103
+735:2:3108
+736:2:3112
+737:2:3113
+738:2:3121
+739:2:3122
+740:2:3126
+741:2:3127
+742:2:3121
+743:2:3122
+744:2:3126
+745:2:3127
+746:2:3135
+747:2:3140
+748:2:3141
+749:2:3152
+750:2:3153
+751:2:3154
+752:2:3165
+753:2:3170
+754:2:3171
+755:2:3182
+756:2:3183
+757:2:3184
+758:2:3182
+759:2:3183
+760:2:3184
+761:2:3195
+762:2:3202
+763:0:4844
+764:2:2881
+765:0:4844
+766:2:3206
+767:2:3207
+768:2:3208
+769:2:3220
+770:2:3221
+771:2:3225
+772:2:3226
+773:2:3234
+774:2:3239
+775:2:3243
+776:2:3244
+777:2:3252
+778:2:3253
+779:2:3257
+780:2:3258
+781:2:3252
+782:2:3253
+783:2:3257
+784:2:3258
+785:2:3266
+786:2:3271
+787:2:3272
+788:2:3283
+789:2:3284
+790:2:3285
+791:2:3296
+792:2:3301
+793:2:3302
+794:2:3313
+795:2:3314
+796:2:3315
+797:2:3313
+798:2:3314
+799:2:3315
+800:2:3326
+801:2:3337
+802:2:3338
+803:0:4844
+804:2:2881
+805:0:4844
+806:2:3344
+807:2:3345
+808:2:3349
+809:2:3350
+810:2:3358
+811:2:3359
+812:2:3363
+813:2:3364
+814:2:3372
+815:2:3377
+816:2:3381
+817:2:3382
+818:2:3390
+819:2:3391
+820:2:3395
+821:2:3396
+822:2:3390
+823:2:3391
+824:2:3395
+825:2:3396
+826:2:3404
+827:2:3409
+828:2:3410
+829:2:3421
+830:2:3422
+831:2:3423
+832:2:3434
+833:2:3439
+834:2:3440
+835:2:3451
+836:2:3452
+837:2:3453
+838:2:3451
+839:2:3452
+840:2:3453
+841:2:3464
+842:0:4844
+843:2:2881
+844:0:4844
+845:2:3473
+846:2:3474
+847:2:3478
+848:2:3479
+849:2:3487
+850:2:3488
+851:2:3492
+852:2:3493
+853:2:3501
+854:2:3506
+855:2:3510
+856:2:3511
+857:2:3519
+858:2:3520
+859:2:3524
+860:2:3525
+861:2:3519
+862:2:3520
+863:2:3524
+864:2:3525
+865:2:3533
+866:2:3538
+867:2:3539
+868:2:3550
+869:2:3551
+870:2:3552
+871:2:3563
+872:2:3568
+873:2:3569
+874:2:3580
+875:2:3581
+876:2:3582
+877:2:3580
+878:2:3581
+879:2:3582
+880:2:3593
+881:2:3600
+882:0:4844
+883:2:2881
+884:0:4844
+885:2:3604
+886:2:3605
+887:2:3606
+888:2:3618
+889:2:3619
+890:2:3623
+891:2:3624
+892:2:3632
+893:2:3637
+894:2:3641
+895:2:3642
+896:2:3650
+897:2:3651
+898:2:3655
+899:2:3656
+900:2:3650
+901:2:3651
+902:2:3655
+903:2:3656
+904:2:3664
+905:2:3669
+906:2:3670
+907:2:3681
+908:2:3682
+909:2:3683
+910:2:3694
+911:2:3699
+912:2:3700
+913:2:3711
+914:2:3712
+915:2:3713
+916:2:3711
+917:2:3712
+918:2:3713
+919:2:3724
+920:2:3734
+921:2:3735
+922:0:4844
+923:2:2881
+924:0:4844
+925:2:3741
+926:0:4844
+927:2:4563
+928:2:4564
+929:2:4568
+930:2:4572
+931:2:4573
+932:2:4577
+933:2:4585
+934:2:4586
+935:2:4590
+936:2:4594
+937:2:4595
+938:2:4590
+939:2:4594
+940:2:4595
+941:2:4599
+942:2:4606
+943:2:4613
+944:2:4614
+945:2:4621
+946:2:4626
+947:2:4633
+948:2:4634
+949:2:4633
+950:2:4634
+951:2:4641
+952:2:4645
+953:0:4844
+954:2:4650
+955:0:4844
+956:2:4651
+957:0:4844
+958:2:4652
+959:0:4844
+960:1:26
+961:0:4844
+962:1:30
+963:1:31
+964:1:35
+965:1:39
+966:1:40
+967:1:44
+968:1:52
+969:1:53
+970:1:57
+971:1:61
+972:1:62
+973:1:57
+974:1:61
+975:1:62
+976:1:66
+977:1:73
+978:1:80
+979:1:81
+980:1:88
+981:1:93
+982:1:100
+983:1:101
+984:1:100
+985:1:101
+986:1:108
+987:1:112
+988:0:4844
+989:1:117
+990:0:4844
+991:2:4655
+992:0:4844
+993:2:4660
+994:0:4844
+995:2:4661
+996:0:4844
+997:2:4669
+998:2:4670
+999:2:4674
+1000:2:4678
+1001:2:4679
+1002:2:4683
+1003:2:4691
+1004:2:4692
+1005:2:4696
+1006:2:4700
+1007:2:4701
+1008:2:4696
+1009:2:4700
+1010:2:4701
+1011:2:4705
+1012:2:4712
+1013:2:4719
+1014:2:4720
+1015:2:4727
+1016:2:4732
+1017:2:4739
+1018:2:4740
+1019:2:4739
+1020:2:4740
+1021:2:4747
+1022:2:4751
+1023:0:4844
+1024:2:3743
+1025:2:3753
+1026:0:4844
+1027:2:2881
+1028:0:4844
+1029:2:3744
+1030:2:3745
+1031:0:4844
+1032:2:2881
+1033:0:4844
+1034:2:3749
+1035:0:4844
+1036:2:3757
+1037:0:4844
+1038:2:2878
+1039:0:4844
+1040:2:2880
+1041:0:4844
+1042:2:2881
+1043:0:4844
+1044:2:2882
+1045:2:2883
+1046:2:2887
+1047:2:2888
+1048:2:2896
+1049:2:2897
+1050:2:2901
+1051:2:2902
+1052:2:2910
+1053:2:2915
+1054:2:2919
+1055:2:2920
+1056:2:2928
+1057:2:2929
+1058:2:2933
+1059:2:2934
+1060:2:2928
+1061:2:2929
+1062:2:2930
+1063:2:2942
+1064:2:2947
+1065:2:2948
+1066:2:2959
+1067:2:2960
+1068:2:2961
+1069:2:2972
+1070:2:2977
+1071:2:2978
+1072:2:2989
+1073:2:2990
+1074:2:2991
+1075:2:2989
+1076:2:2990
+1077:2:2991
+1078:2:3002
+1079:2:3010
+1080:0:4844
+1081:2:2881
+1082:0:4844
+1083:2:3014
+1084:2:3018
+1085:2:3019
+1086:2:3023
+1087:2:3027
+1088:2:3028
+1089:2:3032
+1090:2:3040
+1091:2:3041
+1092:2:3045
+1093:2:3049
+1094:2:3050
+1095:2:3045
+1096:2:3046
+1097:2:3054
+1098:0:4844
+1099:2:2881
+1100:0:4844
+1101:2:3062
+1102:2:3063
+1103:2:3064
+1104:0:4844
+1105:2:2881
+1106:0:4844
+1107:2:3069
+1108:0:4844
+1109:2:3969
+1110:2:3970
+1111:2:3974
+1112:2:3978
+1113:2:3979
+1114:2:3983
+1115:2:3988
+1116:2:3996
+1117:2:4000
+1118:2:4001
+1119:2:3996
+1120:2:4000
+1121:2:4001
+1122:2:4005
+1123:2:4012
+1124:2:4019
+1125:2:4020
+1126:2:4027
+1127:2:4032
+1128:2:4039
+1129:2:4040
+1130:2:4039
+1131:2:4040
+1132:2:4047
+1133:2:4051
+1134:0:4844
+1135:2:4056
+1136:0:4844
+1137:2:4057
+1138:0:4844
+1139:2:4058
+1140:0:4844
+1141:1:26
+1142:0:4844
+1143:1:30
+1144:1:31
+1145:1:35
+1146:1:39
+1147:1:40
+1148:1:44
+1149:1:52
+1150:1:53
+1151:1:57
+1152:1:61
+1153:1:62
+1154:1:57
+1155:1:61
+1156:1:62
+1157:1:66
+1158:1:73
+1159:1:80
+1160:1:81
+1161:1:88
+1162:1:93
+1163:1:100
+1164:1:101
+1165:1:100
+1166:1:101
+1167:1:108
+1168:1:112
+1169:0:4844
+1170:1:117
+1171:0:4844
+1172:2:4061
+1173:0:4844
+1174:2:4066
+1175:0:4844
+1176:2:4067
+1177:0:4844
+1178:2:4075
+1179:2:4076
+1180:2:4080
+1181:2:4084
+1182:2:4085
+1183:2:4089
+1184:2:4097
+1185:2:4098
+1186:2:4102
+1187:2:4106
+1188:2:4107
+1189:2:4102
+1190:2:4106
+1191:2:4107
+1192:2:4111
+1193:2:4118
+1194:2:4125
+1195:2:4126
+1196:2:4133
+1197:2:4138
+1198:2:4145
+1199:2:4146
+1200:2:4145
+1201:2:4146
+1202:2:4153
+1203:2:4157
+1204:0:4844
+1205:2:3071
+1206:2:3753
+1207:0:4844
+1208:2:2881
+1209:0:4844
+1210:2:3072
+1211:0:4844
+1212:2:2881
+1213:0:4844
+1214:2:3075
+1215:2:3076
+1216:2:3080
+1217:2:3081
+1218:2:3089
+1219:2:3090
+1220:2:3094
+1221:2:3095
+1222:2:3103
+1223:2:3108
+1224:2:3112
+1225:2:3113
+1226:2:3121
+1227:2:3122
+1228:2:3126
+1229:2:3127
+1230:2:3121
+1231:2:3122
+1232:2:3126
+1233:2:3127
+1234:2:3135
+1235:2:3140
+1236:2:3141
+1237:2:3152
+1238:2:3153
+1239:2:3154
+1240:2:3165
+1241:2:3170
+1242:2:3171
+1243:2:3182
+1244:2:3183
+1245:2:3184
+1246:2:3182
+1247:2:3183
+1248:2:3184
+1249:2:3195
+1250:2:3202
+1251:0:4844
+1252:2:2881
+1253:0:4844
+1254:2:3206
+1255:2:3207
+1256:2:3208
+1257:2:3220
+1258:2:3221
+1259:2:3225
+1260:2:3226
+1261:2:3234
+1262:2:3239
+1263:2:3243
+1264:2:3244
+1265:2:3252
+1266:2:3253
+1267:2:3257
+1268:2:3258
+1269:2:3252
+1270:2:3253
+1271:2:3257
+1272:2:3258
+1273:2:3266
+1274:2:3271
+1275:2:3272
+1276:2:3283
+1277:2:3284
+1278:2:3285
+1279:2:3296
+1280:2:3301
+1281:2:3302
+1282:2:3313
+1283:2:3314
+1284:2:3315
+1285:2:3313
+1286:2:3314
+1287:2:3315
+1288:2:3326
+1289:2:3337
+1290:2:3338
+1291:0:4844
+1292:2:2881
+1293:0:4844
+1294:2:3344
+1295:2:3345
+1296:2:3349
+1297:2:3350
+1298:2:3358
+1299:2:3359
+1300:2:3363
+1301:2:3364
+1302:2:3372
+1303:2:3377
+1304:2:3381
+1305:2:3382
+1306:2:3390
+1307:2:3391
+1308:2:3395
+1309:2:3396
+1310:2:3390
+1311:2:3391
+1312:2:3395
+1313:2:3396
+1314:2:3404
+1315:2:3409
+1316:2:3410
+1317:2:3421
+1318:2:3422
+1319:2:3423
+1320:2:3434
+1321:2:3439
+1322:2:3440
+1323:2:3451
+1324:2:3452
+1325:2:3453
+1326:2:3451
+1327:2:3452
+1328:2:3453
+1329:2:3464
+1330:0:4844
+1331:2:2881
+1332:0:4844
+1333:2:3473
+1334:2:3474
+1335:2:3478
+1336:2:3479
+1337:2:3487
+1338:2:3488
+1339:2:3492
+1340:2:3493
+1341:2:3501
+1342:2:3506
+1343:2:3510
+1344:2:3511
+1345:2:3519
+1346:2:3520
+1347:2:3524
+1348:2:3525
+1349:2:3519
+1350:2:3520
+1351:2:3524
+1352:2:3525
+1353:2:3533
+1354:2:3538
+1355:2:3539
+1356:2:3550
+1357:2:3551
+1358:2:3552
+1359:2:3563
+1360:2:3568
+1361:2:3569
+1362:2:3580
+1363:2:3581
+1364:2:3582
+1365:2:3580
+1366:2:3581
+1367:2:3582
+1368:2:3593
+1369:2:3600
+1370:0:4844
+1371:2:2881
+1372:0:4844
+1373:2:3604
+1374:2:3605
+1375:2:3606
+1376:2:3618
+1377:2:3619
+1378:2:3623
+1379:2:3624
+1380:2:3632
+1381:2:3637
+1382:2:3641
+1383:2:3642
+1384:2:3650
+1385:2:3651
+1386:2:3655
+1387:2:3656
+1388:2:3650
+1389:2:3651
+1390:2:3655
+1391:2:3656
+1392:2:3664
+1393:2:3669
+1394:2:3670
+1395:2:3681
+1396:2:3682
+1397:2:3683
+1398:2:3694
+1399:2:3699
+1400:2:3700
+1401:2:3711
+1402:2:3712
+1403:2:3713
+1404:2:3711
+1405:2:3712
+1406:2:3713
+1407:2:3724
+1408:2:3734
+1409:2:3735
+1410:0:4844
+1411:2:2881
+1412:0:4844
+1413:2:3741
+1414:0:4844
+1415:2:4563
+1416:2:4564
+1417:2:4568
+1418:2:4572
+1419:2:4573
+1420:2:4577
+1421:2:4585
+1422:2:4586
+1423:2:4590
+1424:2:4594
+1425:2:4595
+1426:2:4590
+1427:2:4594
+1428:2:4595
+1429:2:4599
+1430:2:4606
+1431:2:4613
+1432:2:4614
+1433:2:4621
+1434:2:4626
+1435:2:4633
+1436:2:4634
+1437:2:4633
+1438:2:4634
+1439:2:4641
+1440:2:4645
+1441:0:4844
+1442:2:4650
+1443:0:4844
+1444:2:4651
+1445:0:4844
+1446:2:4652
+1447:0:4844
+1448:1:26
+1449:0:4844
+1450:1:30
+1451:1:31
+1452:1:35
+1453:1:39
+1454:1:40
+1455:1:44
+1456:1:52
+1457:1:53
+1458:1:57
+1459:1:61
+1460:1:62
+1461:1:57
+1462:1:61
+1463:1:62
+1464:1:66
+1465:1:73
+1466:1:80
+1467:1:81
+1468:1:88
+1469:1:93
+1470:1:100
+1471:1:101
+1472:1:100
+1473:1:101
+1474:1:108
+1475:1:112
+1476:0:4844
+1477:1:117
+1478:0:4844
+1479:2:4655
+1480:0:4844
+1481:2:4660
+1482:0:4844
+1483:2:4661
+1484:0:4844
+1485:2:4669
+1486:2:4670
+1487:2:4674
+1488:2:4678
+1489:2:4679
+1490:2:4683
+1491:2:4691
+1492:2:4692
+1493:2:4696
+1494:2:4700
+1495:2:4701
+1496:2:4696
+1497:2:4700
+1498:2:4701
+1499:2:4705
+1500:2:4712
+1501:2:4719
+1502:2:4720
+1503:2:4727
+1504:2:4732
+1505:2:4739
+1506:2:4740
+1507:2:4739
+1508:2:4740
+1509:2:4747
+1510:2:4751
+1511:0:4844
+1512:2:3743
+1513:2:3753
+1514:0:4844
+1515:2:2881
+1516:0:4844
+1517:2:3744
+1518:2:3745
+1519:0:4844
+1520:2:2881
+1521:0:4844
+1522:2:3749
+1523:0:4844
+1524:2:3757
+1525:0:4844
+1526:2:3758
+1527:0:4844
+1528:2:3763
+1529:0:4844
+1530:2:3767
+1531:2:3768
+1532:2:3772
+1533:2:3776
+1534:2:3777
+1535:2:3781
+1536:2:3789
+1537:2:3790
+1538:2:3794
+1539:2:3795
+1540:2:3794
+1541:2:3798
+1542:2:3799
+1543:2:3803
+1544:2:3810
+1545:2:3817
+1546:2:3818
+1547:2:3825
+1548:2:3830
+1549:2:3837
+1550:2:3838
+1551:2:3837
+1552:2:3838
+1553:2:3845
+1554:2:3849
+1555:0:4844
+1556:2:3854
+1557:0:4844
+1558:2:3855
+1559:0:4844
+1560:2:3856
+1561:0:4844
+1562:1:26
+1563:0:4844
+1564:1:30
+1565:1:31
+1566:1:35
+1567:1:39
+1568:1:40
+1569:1:44
+1570:1:52
+1571:1:53
+1572:1:57
+1573:1:61
+1574:1:62
+1575:1:57
+1576:1:61
+1577:1:62
+1578:1:66
+1579:1:73
+1580:1:80
+1581:1:81
+1582:1:88
+1583:1:93
+1584:1:100
+1585:1:101
+1586:1:100
+1587:1:101
+1588:1:108
+1589:1:112
+1590:0:4844
+1591:1:117
+1592:0:4844
+1593:2:3859
+1594:0:4844
+1595:2:3864
+1596:0:4844
+1597:2:3865
+1598:0:4844
+1599:2:3873
+1600:2:3874
+1601:2:3878
+1602:2:3882
+1603:2:3883
+1604:2:3887
+1605:2:3895
+1606:2:3896
+1607:2:3900
+1608:2:3904
+1609:2:3905
+1610:2:3900
+1611:2:3904
+1612:2:3905
+1613:2:3909
+1614:2:3916
+1615:2:3923
+1616:2:3924
+1617:2:3931
+1618:2:3936
+1619:2:3943
+1620:2:3944
+1621:2:3943
+1622:2:3944
+1623:2:3951
+1624:2:3955
+1625:0:4844
+1626:2:3961
+1627:0:4844
+1628:2:3763
+1629:0:4844
+1630:2:3767
+1631:2:3768
+1632:2:3772
+1633:2:3776
+1634:2:3777
+1635:2:3781
+1636:2:3789
+1637:2:3790
+1638:2:3794
+1639:2:3798
+1640:2:3799
+1641:2:3794
+1642:2:3798
+1643:2:3799
+1644:2:3803
+1645:2:3810
+1646:2:3817
+1647:2:3818
+1648:2:3825
+1649:2:3830
+1650:2:3837
+1651:2:3838
+1652:2:3837
+1653:2:3838
+1654:2:3845
+1655:2:3849
+1656:0:4844
+1657:2:3854
+1658:0:4844
+1659:2:3855
+1660:0:4844
+1661:2:3856
+1662:0:4844
+1663:1:26
+-1:-1:-1
+1664:0:4844
+1665:1:30
+1666:1:31
+1667:1:35
+1668:1:39
+1669:1:40
+1670:1:44
+1671:1:52
+1672:1:53
+1673:1:57
+1674:1:61
+1675:1:62
+1676:1:57
+1677:1:61
+1678:1:62
+1679:1:66
+1680:1:73
+1681:1:80
+1682:1:81
+1683:1:88
+1684:1:93
+1685:1:100
+1686:1:101
+1687:1:100
+1688:1:101
+1689:1:108
+1690:1:112
+1691:0:4844
+1692:1:117
+1693:0:4844
+1694:2:3859
+1695:0:4844
+1696:2:3864
+1697:0:4844
+1698:2:3865
+1699:0:4844
+1700:2:3873
+1701:2:3874
+1702:2:3878
+1703:2:3882
+1704:2:3883
+1705:2:3887
+1706:2:3895
+1707:2:3896
+1708:2:3900
+1709:2:3904
+1710:2:3905
+1711:2:3900
+1712:2:3904
+1713:2:3905
+1714:2:3909
+1715:2:3916
+1716:2:3923
+1717:2:3924
+1718:2:3931
+1719:2:3936
+1720:2:3943
+1721:2:3944
+1722:2:3943
+1723:2:3944
+1724:2:3951
+1725:2:3955
+1726:0:4844
+1727:2:3961
+1728:0:4844
+1729:2:3763
+1730:0:4844
+1731:2:3767
+1732:2:3768
+1733:2:3772
+1734:2:3776
+1735:2:3777
+1736:2:3781
+1737:2:3789
+1738:2:3790
+1739:2:3794
+1740:2:3798
+1741:2:3799
+1742:2:3794
+1743:2:3798
+1744:2:3799
+1745:2:3803
+1746:2:3810
+1747:2:3817
+1748:2:3818
+1749:2:3825
+1750:2:3830
+1751:2:3837
+1752:2:3838
+1753:2:3837
+1754:2:3838
+1755:2:3845
+1756:2:3849
+1757:0:4844
+1758:2:3854
+1759:0:4844
+1760:2:3855
+1761:0:4844
+1762:2:3856
+1763:0:4844
+1764:1:26
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_progress_writer.define b/formal-model/results/urcu-controldataflow-ipi/urcu_progress_writer.define
new file mode 100644 (file)
index 0000000..1e4417f
--- /dev/null
@@ -0,0 +1 @@
+#define WRITER_PROGRESS
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_progress_writer.log b/formal-model/results/urcu-controldataflow-ipi/urcu_progress_writer.log
new file mode 100644 (file)
index 0000000..7a8b4c1
--- /dev/null
@@ -0,0 +1,581 @@
+rm -f pan* trail.out .input.spin* *.spin.trail .input.define
+touch .input.define
+cat .input.define > pan.ltl
+cat DEFINES >> pan.ltl
+spin -f "!(`cat urcu_progress.ltl | grep -v ^//`)" >> pan.ltl
+cp urcu_progress_writer.define .input.define
+cat .input.define > .input.spin
+cat DEFINES >> .input.spin
+cat urcu.spin >> .input.spin
+rm -f .input.spin.trail
+spin -a -X -N pan.ltl .input.spin
+Exit-Status 0
+gcc -O2 -w -DHASH64 -o pan pan.c
+./pan -a -f -v -c1 -X -m10000000 -w20
+warning: for p.o. reduction to be valid the never claim must be stutter-invariant
+(never claims generated from LTL formulae are stutter-invariant)
+depth 0: Claim reached state 5 (line 1258)
+depth 23: Claim reached state 9 (line 1263)
+depth 51: Claim reached state 9 (line 1262)
+Depth=    6084 States=    1e+06 Transitions=    2e+08 Memory=   516.838        t=    264 R=   4e+03
+Depth=    7018 States=    2e+06 Transitions= 4.38e+08 Memory=   566.154        t=    585 R=   3e+03
+Depth=    7018 States=    3e+06 Transitions= 6.49e+08 Memory=   616.545        t=    870 R=   3e+03
+pan: resizing hashtable to -w22..  done
+Depth=    7018 States=    4e+06 Transitions= 8.46e+08 Memory=   698.447        t= 1.13e+03 R=   4e+03
+Depth=    7018 States=    5e+06 Transitions= 1.29e+09 Memory=   742.979        t= 1.73e+03 R=   3e+03
+Depth=    7018 States=    6e+06 Transitions=  1.8e+09 Memory=   789.170        t= 2.44e+03 R=   2e+03
+Depth=    7018 States=    7e+06 Transitions= 2.27e+09 Memory=   833.506        t= 3.09e+03 R=   2e+03
+Depth=    7018 States=    8e+06 Transitions= 2.76e+09 Memory=   880.283        t= 3.76e+03 R=   2e+03
+Depth=    7018 States=    9e+06 Transitions= 3.05e+09 Memory=   928.135        t= 4.16e+03 R=   2e+03
+pan: resizing hashtable to -w24..  done
+Depth=    7018 States=    1e+07 Transitions=  3.3e+09 Memory=  1102.815        t= 4.5e+03 R=   2e+03
+Depth=    7018 States=  1.1e+07 Transitions= 3.74e+09 Memory=  1148.322        t= 5.08e+03 R=   2e+03
+Depth=    7018 States=  1.2e+07 Transitions= 4.65e+09 Memory=  1195.783        t= 6.37e+03 R=   2e+03
+Depth=    7018 States=  1.3e+07 Transitions= 5.63e+09 Memory=  1235.334        t= 7.72e+03 R=   2e+03
+Depth=    7018 States=  1.4e+07 Transitions= 6.21e+09 Memory=  1277.912        t= 8.53e+03 R=   2e+03
+Depth=    7018 States=  1.5e+07 Transitions= 6.77e+09 Memory=  1325.276        t= 9.3e+03 R=   2e+03
+Depth=    7018 States=  1.6e+07 Transitions= 7.05e+09 Memory=  1372.248        t= 9.68e+03 R=   2e+03
+Depth=    7018 States=  1.7e+07 Transitions= 7.66e+09 Memory=  1417.463        t= 1.05e+04 R=   2e+03
+Depth=    7018 States=  1.8e+07 Transitions= 8.25e+09 Memory=  1463.264        t= 1.13e+04 R=   2e+03
+Depth=    7018 States=  1.9e+07 Transitions= 8.65e+09 Memory=  1513.068        t= 1.19e+04 R=   2e+03
+Depth=    7018 States=    2e+07 Transitions= 8.97e+09 Memory=  1561.408        t= 1.23e+04 R=   2e+03
+Depth=    7018 States=  2.1e+07 Transitions= 9.29e+09 Memory=  1609.651        t= 1.28e+04 R=   2e+03
+Depth=    7018 States=  2.2e+07 Transitions= 9.65e+09 Memory=  1659.065        t= 1.33e+04 R=   2e+03
+Depth=    7018 States=  2.3e+07 Transitions= 9.91e+09 Memory=  1708.186        t= 1.36e+04 R=   2e+03
+Depth=    7018 States=  2.4e+07 Transitions= 1.03e+10 Memory=  1757.307        t= 1.41e+04 R=   2e+03
+Depth=    7018 States=  2.5e+07 Transitions= 1.05e+10 Memory=  1807.014        t= 1.45e+04 R=   2e+03
+Depth=    7018 States=  2.6e+07 Transitions= 1.09e+10 Memory=  1856.623        t= 1.49e+04 R=   2e+03
+Depth=    7018 States=  2.7e+07 Transitions= 1.12e+10 Memory=  1906.428        t= 1.54e+04 R=   2e+03
+Depth=    7018 States=  2.8e+07 Transitions= 1.16e+10 Memory=  1951.838        t= 1.59e+04 R=   2e+03
+Depth=    7018 States=  2.9e+07 Transitions=  1.2e+10 Memory=  1998.615        t= 1.65e+04 R=   2e+03
+Depth=    7018 States=    3e+07 Transitions= 1.25e+10 Memory=  2044.026        t= 1.73e+04 R=   2e+03
+Depth=    7018 States=  3.1e+07 Transitions= 1.31e+10 Memory=  2087.971        t= 1.8e+04 R=   2e+03
+Depth=    7018 States=  3.2e+07 Transitions= 1.36e+10 Memory=  2134.455        t= 1.87e+04 R=   2e+03
+Depth=    7018 States=  3.3e+07 Transitions= 1.39e+10 Memory=  2181.818        t= 1.92e+04 R=   2e+03
+Depth=    7018 States=  3.4e+07 Transitions= 1.42e+10 Memory=  2232.795        t= 1.95e+04 R=   2e+03
+pan: resizing hashtable to -w26..  done
+Depth=    7018 States=  3.5e+07 Transitions= 1.45e+10 Memory=  2776.338        t= 1.99e+04 R=   2e+03
+Depth=    7018 States=  3.6e+07 Transitions= 1.52e+10 Memory=  2822.041        t= 2.09e+04 R=   2e+03
+Depth=    7018 States=  3.7e+07 Transitions= 1.62e+10 Memory=  2866.182        t= 2.23e+04 R=   2e+03
+Depth=    7018 States=  3.8e+07 Transitions=  1.7e+10 Memory=  2904.365        t= 2.35e+04 R=   2e+03
+Depth=    7018 States=  3.9e+07 Transitions= 1.76e+10 Memory=  2950.361        t= 2.43e+04 R=   2e+03
+Depth=    7018 States=    4e+07 Transitions= 1.79e+10 Memory=  2998.701        t= 2.47e+04 R=   2e+03
+Depth=    7018 States=  4.1e+07 Transitions= 1.84e+10 Memory=  3044.600        t= 2.53e+04 R=   2e+03
+Depth=    7018 States=  4.2e+07 Transitions= 1.89e+10 Memory=  3090.498        t= 2.61e+04 R=   2e+03
+Depth=    7018 States=  4.3e+07 Transitions= 1.95e+10 Memory=  3136.885        t= 2.68e+04 R=   2e+03
+Depth=    7018 States=  4.4e+07 Transitions= 1.98e+10 Memory=  3186.299        t= 2.73e+04 R=   2e+03
+Depth=    7018 States=  4.5e+07 Transitions= 2.01e+10 Memory=  3235.225        t= 2.77e+04 R=   2e+03
+Depth=    7018 States=  4.6e+07 Transitions= 2.04e+10 Memory=  3284.541        t= 2.82e+04 R=   2e+03
+Depth=    7018 States=  4.7e+07 Transitions= 2.08e+10 Memory=  3334.541        t= 2.87e+04 R=   2e+03
+Depth=    7018 States=  4.8e+07 Transitions= 2.11e+10 Memory=  3383.565        t= 2.91e+04 R=   2e+03
+Depth=    7018 States=  4.9e+07 Transitions= 2.14e+10 Memory=  3432.588        t= 2.95e+04 R=   2e+03
+Depth=    7018 States=    5e+07 Transitions= 2.17e+10 Memory=  3483.369        t= 2.99e+04 R=   2e+03
+Depth=    7018 States=  5.1e+07 Transitions= 2.21e+10 Memory=  3532.490        t= 3.04e+04 R=   2e+03
+Depth=    7018 States=  5.2e+07 Transitions= 2.23e+10 Memory=  3580.147        t= 3.07e+04 R=   2e+03
+Depth=    7018 States=  5.3e+07 Transitions= 2.27e+10 Memory=  3625.752        t= 3.13e+04 R=   2e+03
+Depth=    7018 States=  5.4e+07 Transitions= 2.32e+10 Memory=  3671.943        t= 3.2e+04 R=   2e+03
+Depth=    7018 States=  5.5e+07 Transitions= 2.38e+10 Memory=  3715.693        t= 3.27e+04 R=   2e+03
+Depth=    7018 States=  5.6e+07 Transitions= 2.42e+10 Memory=  3762.276        t= 3.33e+04 R=   2e+03
+Depth=    7018 States=  5.7e+07 Transitions= 2.48e+10 Memory=  3808.565        t= 3.41e+04 R=   2e+03
+Depth=    7018 States=  5.8e+07 Transitions= 2.53e+10 Memory=  3855.440        t= 3.48e+04 R=   2e+03
+
+(Spin Version 5.1.7 -- 23 December 2008)
+       + Partial Order Reduction
+
+Full statespace search for:
+       never claim             +
+       assertion violations    + (if within scope of claim)
+       acceptance   cycles     + (fairness enabled)
+       invalid end states      - (disabled by never claim)
+
+State-vector 88 byte, depth reached 7018, errors: 0
+ 32735820 states, stored (5.82355e+07 visited)
+2.5283515e+10 states, matched
+2.534175e+10 transitions (= visited+matched)
+1.4761827e+11 atomic steps
+hash conflicts: 8.6523014e+09 (resolved)
+
+Stats on memory usage (in Megabytes):
+ 3621.440      equivalent memory usage for states (stored*(State-vector + overhead))
+ 2898.114      actual memory usage for states (compression: 80.03%)
+               state-vector as stored = 65 byte + 28 byte overhead
+  512.000      memory used for hash table (-w26)
+  457.764      memory used for DFS stack (-m10000000)
+    1.598      memory lost to fragmentation
+ 3866.279      total actual memory usage
+
+unreached in proctype urcu_reader
+       line 250, "pan.___", state 30, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 52, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 61, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 77, "(1)"
+       line 231, "pan.___", state 85, "(1)"
+       line 235, "pan.___", state 97, "(1)"
+       line 239, "pan.___", state 105, "(1)"
+       line 395, "pan.___", state 131, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 163, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 177, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 196, "(1)"
+       line 421, "pan.___", state 226, "(1)"
+       line 425, "pan.___", state 239, "(1)"
+       line 670, "pan.___", state 260, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<1))"
+       line 395, "pan.___", state 267, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 299, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 313, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 332, "(1)"
+       line 421, "pan.___", state 362, "(1)"
+       line 425, "pan.___", state 375, "(1)"
+       line 395, "pan.___", state 396, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 428, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 442, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 461, "(1)"
+       line 421, "pan.___", state 491, "(1)"
+       line 425, "pan.___", state 504, "(1)"
+       line 395, "pan.___", state 527, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 529, "(1)"
+       line 395, "pan.___", state 530, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 530, "else"
+       line 395, "pan.___", state 533, "(1)"
+       line 399, "pan.___", state 541, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 543, "(1)"
+       line 399, "pan.___", state 544, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 544, "else"
+       line 399, "pan.___", state 547, "(1)"
+       line 399, "pan.___", state 548, "(1)"
+       line 399, "pan.___", state 548, "(1)"
+       line 397, "pan.___", state 553, "((i<1))"
+       line 397, "pan.___", state 553, "((i>=1))"
+       line 404, "pan.___", state 559, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 561, "(1)"
+       line 404, "pan.___", state 562, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 562, "else"
+       line 404, "pan.___", state 565, "(1)"
+       line 404, "pan.___", state 566, "(1)"
+       line 404, "pan.___", state 566, "(1)"
+       line 408, "pan.___", state 573, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 575, "(1)"
+       line 408, "pan.___", state 576, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 576, "else"
+       line 408, "pan.___", state 579, "(1)"
+       line 408, "pan.___", state 580, "(1)"
+       line 408, "pan.___", state 580, "(1)"
+       line 406, "pan.___", state 585, "((i<2))"
+       line 406, "pan.___", state 585, "((i>=2))"
+       line 412, "pan.___", state 592, "(1)"
+       line 412, "pan.___", state 593, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 593, "else"
+       line 412, "pan.___", state 596, "(1)"
+       line 412, "pan.___", state 597, "(1)"
+       line 412, "pan.___", state 597, "(1)"
+       line 416, "pan.___", state 605, "(1)"
+       line 416, "pan.___", state 606, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 606, "else"
+       line 416, "pan.___", state 609, "(1)"
+       line 416, "pan.___", state 610, "(1)"
+       line 416, "pan.___", state 610, "(1)"
+       line 414, "pan.___", state 615, "((i<1))"
+       line 414, "pan.___", state 615, "((i>=1))"
+       line 421, "pan.___", state 622, "(1)"
+       line 421, "pan.___", state 623, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 623, "else"
+       line 421, "pan.___", state 626, "(1)"
+       line 421, "pan.___", state 627, "(1)"
+       line 421, "pan.___", state 627, "(1)"
+       line 425, "pan.___", state 635, "(1)"
+       line 425, "pan.___", state 636, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 636, "else"
+       line 425, "pan.___", state 639, "(1)"
+       line 425, "pan.___", state 640, "(1)"
+       line 425, "pan.___", state 640, "(1)"
+       line 423, "pan.___", state 645, "((i<2))"
+       line 423, "pan.___", state 645, "((i>=2))"
+       line 430, "pan.___", state 649, "(1)"
+       line 430, "pan.___", state 649, "(1)"
+       line 670, "pan.___", state 652, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 670, "pan.___", state 653, "_proc_urcu_reader = (_proc_urcu_reader|(1<<5))"
+       line 670, "pan.___", state 654, "(1)"
+       line 395, "pan.___", state 661, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 693, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 707, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 726, "(1)"
+       line 421, "pan.___", state 756, "(1)"
+       line 425, "pan.___", state 769, "(1)"
+       line 395, "pan.___", state 797, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 799, "(1)"
+       line 395, "pan.___", state 800, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 800, "else"
+       line 395, "pan.___", state 803, "(1)"
+       line 399, "pan.___", state 811, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 813, "(1)"
+       line 399, "pan.___", state 814, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 814, "else"
+       line 399, "pan.___", state 817, "(1)"
+       line 399, "pan.___", state 818, "(1)"
+       line 399, "pan.___", state 818, "(1)"
+       line 397, "pan.___", state 823, "((i<1))"
+       line 397, "pan.___", state 823, "((i>=1))"
+       line 404, "pan.___", state 829, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 831, "(1)"
+       line 404, "pan.___", state 832, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 832, "else"
+       line 404, "pan.___", state 835, "(1)"
+       line 404, "pan.___", state 836, "(1)"
+       line 404, "pan.___", state 836, "(1)"
+       line 408, "pan.___", state 843, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 845, "(1)"
+       line 408, "pan.___", state 846, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 846, "else"
+       line 408, "pan.___", state 849, "(1)"
+       line 408, "pan.___", state 850, "(1)"
+       line 408, "pan.___", state 850, "(1)"
+       line 406, "pan.___", state 855, "((i<2))"
+       line 406, "pan.___", state 855, "((i>=2))"
+       line 412, "pan.___", state 862, "(1)"
+       line 412, "pan.___", state 863, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 863, "else"
+       line 412, "pan.___", state 866, "(1)"
+       line 412, "pan.___", state 867, "(1)"
+       line 412, "pan.___", state 867, "(1)"
+       line 416, "pan.___", state 875, "(1)"
+       line 416, "pan.___", state 876, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 876, "else"
+       line 416, "pan.___", state 879, "(1)"
+       line 416, "pan.___", state 880, "(1)"
+       line 416, "pan.___", state 880, "(1)"
+       line 414, "pan.___", state 885, "((i<1))"
+       line 414, "pan.___", state 885, "((i>=1))"
+       line 421, "pan.___", state 892, "(1)"
+       line 421, "pan.___", state 893, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 893, "else"
+       line 421, "pan.___", state 896, "(1)"
+       line 421, "pan.___", state 897, "(1)"
+       line 421, "pan.___", state 897, "(1)"
+       line 425, "pan.___", state 905, "(1)"
+       line 425, "pan.___", state 906, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 906, "else"
+       line 425, "pan.___", state 909, "(1)"
+       line 425, "pan.___", state 910, "(1)"
+       line 425, "pan.___", state 910, "(1)"
+       line 430, "pan.___", state 919, "(1)"
+       line 430, "pan.___", state 919, "(1)"
+       line 395, "pan.___", state 926, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 928, "(1)"
+       line 395, "pan.___", state 929, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 929, "else"
+       line 395, "pan.___", state 932, "(1)"
+       line 399, "pan.___", state 940, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 942, "(1)"
+       line 399, "pan.___", state 943, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 943, "else"
+       line 399, "pan.___", state 946, "(1)"
+       line 399, "pan.___", state 947, "(1)"
+       line 399, "pan.___", state 947, "(1)"
+       line 397, "pan.___", state 952, "((i<1))"
+       line 397, "pan.___", state 952, "((i>=1))"
+       line 404, "pan.___", state 958, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 960, "(1)"
+       line 404, "pan.___", state 961, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 961, "else"
+       line 404, "pan.___", state 964, "(1)"
+       line 404, "pan.___", state 965, "(1)"
+       line 404, "pan.___", state 965, "(1)"
+       line 408, "pan.___", state 972, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 974, "(1)"
+       line 408, "pan.___", state 975, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 975, "else"
+       line 408, "pan.___", state 978, "(1)"
+       line 408, "pan.___", state 979, "(1)"
+       line 408, "pan.___", state 979, "(1)"
+       line 406, "pan.___", state 984, "((i<2))"
+       line 406, "pan.___", state 984, "((i>=2))"
+       line 412, "pan.___", state 991, "(1)"
+       line 412, "pan.___", state 992, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 992, "else"
+       line 412, "pan.___", state 995, "(1)"
+       line 412, "pan.___", state 996, "(1)"
+       line 412, "pan.___", state 996, "(1)"
+       line 416, "pan.___", state 1004, "(1)"
+       line 416, "pan.___", state 1005, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 1005, "else"
+       line 416, "pan.___", state 1008, "(1)"
+       line 416, "pan.___", state 1009, "(1)"
+       line 416, "pan.___", state 1009, "(1)"
+       line 414, "pan.___", state 1014, "((i<1))"
+       line 414, "pan.___", state 1014, "((i>=1))"
+       line 421, "pan.___", state 1021, "(1)"
+       line 421, "pan.___", state 1022, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 1022, "else"
+       line 421, "pan.___", state 1025, "(1)"
+       line 421, "pan.___", state 1026, "(1)"
+       line 421, "pan.___", state 1026, "(1)"
+       line 425, "pan.___", state 1034, "(1)"
+       line 425, "pan.___", state 1035, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 1035, "else"
+       line 425, "pan.___", state 1038, "(1)"
+       line 425, "pan.___", state 1039, "(1)"
+       line 425, "pan.___", state 1039, "(1)"
+       line 423, "pan.___", state 1044, "((i<2))"
+       line 423, "pan.___", state 1044, "((i>=2))"
+       line 430, "pan.___", state 1048, "(1)"
+       line 430, "pan.___", state 1048, "(1)"
+       line 678, "pan.___", state 1052, "_proc_urcu_reader = (_proc_urcu_reader|(1<<11))"
+       line 395, "pan.___", state 1057, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1089, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1103, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1122, "(1)"
+       line 421, "pan.___", state 1152, "(1)"
+       line 425, "pan.___", state 1165, "(1)"
+       line 395, "pan.___", state 1189, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1221, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1235, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1254, "(1)"
+       line 421, "pan.___", state 1284, "(1)"
+       line 425, "pan.___", state 1297, "(1)"
+       line 395, "pan.___", state 1322, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1354, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1368, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1387, "(1)"
+       line 421, "pan.___", state 1417, "(1)"
+       line 425, "pan.___", state 1430, "(1)"
+       line 395, "pan.___", state 1451, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1483, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1497, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1516, "(1)"
+       line 421, "pan.___", state 1546, "(1)"
+       line 425, "pan.___", state 1559, "(1)"
+       line 395, "pan.___", state 1585, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1617, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1631, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1650, "(1)"
+       line 421, "pan.___", state 1680, "(1)"
+       line 425, "pan.___", state 1693, "(1)"
+       line 395, "pan.___", state 1714, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1746, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1760, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1779, "(1)"
+       line 421, "pan.___", state 1809, "(1)"
+       line 425, "pan.___", state 1822, "(1)"
+       line 395, "pan.___", state 1846, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1878, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1892, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1911, "(1)"
+       line 421, "pan.___", state 1941, "(1)"
+       line 425, "pan.___", state 1954, "(1)"
+       line 717, "pan.___", state 1975, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<19))"
+       line 395, "pan.___", state 1982, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2014, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2028, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2047, "(1)"
+       line 421, "pan.___", state 2077, "(1)"
+       line 425, "pan.___", state 2090, "(1)"
+       line 395, "pan.___", state 2111, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2143, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2157, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2176, "(1)"
+       line 421, "pan.___", state 2206, "(1)"
+       line 425, "pan.___", state 2219, "(1)"
+       line 395, "pan.___", state 2242, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 2244, "(1)"
+       line 395, "pan.___", state 2245, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 2245, "else"
+       line 395, "pan.___", state 2248, "(1)"
+       line 399, "pan.___", state 2256, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 2258, "(1)"
+       line 399, "pan.___", state 2259, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 2259, "else"
+       line 399, "pan.___", state 2262, "(1)"
+       line 399, "pan.___", state 2263, "(1)"
+       line 399, "pan.___", state 2263, "(1)"
+       line 397, "pan.___", state 2268, "((i<1))"
+       line 397, "pan.___", state 2268, "((i>=1))"
+       line 404, "pan.___", state 2274, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2276, "(1)"
+       line 404, "pan.___", state 2277, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 2277, "else"
+       line 404, "pan.___", state 2280, "(1)"
+       line 404, "pan.___", state 2281, "(1)"
+       line 404, "pan.___", state 2281, "(1)"
+       line 408, "pan.___", state 2288, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2290, "(1)"
+       line 408, "pan.___", state 2291, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 2291, "else"
+       line 408, "pan.___", state 2294, "(1)"
+       line 408, "pan.___", state 2295, "(1)"
+       line 408, "pan.___", state 2295, "(1)"
+       line 406, "pan.___", state 2300, "((i<2))"
+       line 406, "pan.___", state 2300, "((i>=2))"
+       line 412, "pan.___", state 2307, "(1)"
+       line 412, "pan.___", state 2308, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 2308, "else"
+       line 412, "pan.___", state 2311, "(1)"
+       line 412, "pan.___", state 2312, "(1)"
+       line 412, "pan.___", state 2312, "(1)"
+       line 416, "pan.___", state 2320, "(1)"
+       line 416, "pan.___", state 2321, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 2321, "else"
+       line 416, "pan.___", state 2324, "(1)"
+       line 416, "pan.___", state 2325, "(1)"
+       line 416, "pan.___", state 2325, "(1)"
+       line 414, "pan.___", state 2330, "((i<1))"
+       line 414, "pan.___", state 2330, "((i>=1))"
+       line 421, "pan.___", state 2337, "(1)"
+       line 421, "pan.___", state 2338, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 2338, "else"
+       line 421, "pan.___", state 2341, "(1)"
+       line 421, "pan.___", state 2342, "(1)"
+       line 421, "pan.___", state 2342, "(1)"
+       line 425, "pan.___", state 2350, "(1)"
+       line 425, "pan.___", state 2351, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 2351, "else"
+       line 425, "pan.___", state 2354, "(1)"
+       line 425, "pan.___", state 2355, "(1)"
+       line 425, "pan.___", state 2355, "(1)"
+       line 423, "pan.___", state 2360, "((i<2))"
+       line 423, "pan.___", state 2360, "((i>=2))"
+       line 430, "pan.___", state 2364, "(1)"
+       line 430, "pan.___", state 2364, "(1)"
+       line 717, "pan.___", state 2367, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 717, "pan.___", state 2368, "_proc_urcu_reader = (_proc_urcu_reader|(1<<23))"
+       line 717, "pan.___", state 2369, "(1)"
+       line 395, "pan.___", state 2376, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2408, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2422, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2441, "(1)"
+       line 421, "pan.___", state 2471, "(1)"
+       line 425, "pan.___", state 2484, "(1)"
+       line 395, "pan.___", state 2511, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2543, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2557, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2576, "(1)"
+       line 421, "pan.___", state 2606, "(1)"
+       line 425, "pan.___", state 2619, "(1)"
+       line 395, "pan.___", state 2640, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2672, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2686, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2705, "(1)"
+       line 421, "pan.___", state 2735, "(1)"
+       line 425, "pan.___", state 2748, "(1)"
+       line 227, "pan.___", state 2781, "(1)"
+       line 235, "pan.___", state 2801, "(1)"
+       line 239, "pan.___", state 2809, "(1)"
+       line 227, "pan.___", state 2824, "(1)"
+       line 235, "pan.___", state 2844, "(1)"
+       line 239, "pan.___", state 2852, "(1)"
+       line 877, "pan.___", state 2869, "-end-"
+       (278 of 2869 states)
+unreached in proctype urcu_writer
+       line 395, "pan.___", state 18, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 32, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 50, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 83, "(1)"
+       line 416, "pan.___", state 96, "(1)"
+       line 421, "pan.___", state 113, "(1)"
+       line 250, "pan.___", state 149, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 158, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 171, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 211, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 225, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 243, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 257, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 276, "(1)"
+       line 416, "pan.___", state 289, "(1)"
+       line 421, "pan.___", state 306, "(1)"
+       line 425, "pan.___", state 319, "(1)"
+       line 399, "pan.___", state 356, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 374, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 388, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 420, "(1)"
+       line 421, "pan.___", state 437, "(1)"
+       line 425, "pan.___", state 450, "(1)"
+       line 399, "pan.___", state 494, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 512, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 526, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 558, "(1)"
+       line 421, "pan.___", state 575, "(1)"
+       line 425, "pan.___", state 588, "(1)"
+       line 399, "pan.___", state 623, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 641, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 655, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 687, "(1)"
+       line 421, "pan.___", state 704, "(1)"
+       line 425, "pan.___", state 717, "(1)"
+       line 399, "pan.___", state 754, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 772, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 786, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 818, "(1)"
+       line 421, "pan.___", state 835, "(1)"
+       line 425, "pan.___", state 848, "(1)"
+       line 250, "pan.___", state 903, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 912, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 927, "(1)"
+       line 262, "pan.___", state 934, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 950, "(1)"
+       line 231, "pan.___", state 958, "(1)"
+       line 235, "pan.___", state 970, "(1)"
+       line 239, "pan.___", state 978, "(1)"
+       line 250, "pan.___", state 1009, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1018, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1031, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1040, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1056, "(1)"
+       line 231, "pan.___", state 1064, "(1)"
+       line 235, "pan.___", state 1076, "(1)"
+       line 239, "pan.___", state 1084, "(1)"
+       line 254, "pan.___", state 1110, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1123, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1132, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1148, "(1)"
+       line 231, "pan.___", state 1156, "(1)"
+       line 235, "pan.___", state 1168, "(1)"
+       line 239, "pan.___", state 1176, "(1)"
+       line 250, "pan.___", state 1207, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1216, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1229, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1238, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1254, "(1)"
+       line 231, "pan.___", state 1262, "(1)"
+       line 235, "pan.___", state 1274, "(1)"
+       line 239, "pan.___", state 1282, "(1)"
+       line 254, "pan.___", state 1308, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1321, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1330, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1346, "(1)"
+       line 231, "pan.___", state 1354, "(1)"
+       line 235, "pan.___", state 1366, "(1)"
+       line 239, "pan.___", state 1374, "(1)"
+       line 250, "pan.___", state 1405, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1414, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1427, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1436, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1452, "(1)"
+       line 231, "pan.___", state 1460, "(1)"
+       line 235, "pan.___", state 1472, "(1)"
+       line 239, "pan.___", state 1480, "(1)"
+       line 254, "pan.___", state 1506, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1519, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1528, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1544, "(1)"
+       line 231, "pan.___", state 1552, "(1)"
+       line 235, "pan.___", state 1564, "(1)"
+       line 239, "pan.___", state 1572, "(1)"
+       line 250, "pan.___", state 1603, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1612, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1625, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1634, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1650, "(1)"
+       line 231, "pan.___", state 1658, "(1)"
+       line 235, "pan.___", state 1670, "(1)"
+       line 239, "pan.___", state 1678, "(1)"
+       line 1204, "pan.___", state 1694, "-end-"
+       (103 of 1694 states)
+unreached in proctype :init:
+       (0 of 78 states)
+unreached in proctype :never:
+       line 1265, "pan.___", state 11, "-end-"
+       (1 of 11 states)
+
+pan: elapsed time 3.48e+04 seconds
+pan: rate 1671.9756 states/second
+pan: avg transition delay 1.3744e-06 usec
+cp .input.spin urcu_progress_writer.spin.input
+cp .input.spin.trail urcu_progress_writer.spin.input.trail
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_progress_writer.spin.input b/formal-model/results/urcu-controldataflow-ipi/urcu_progress_writer.spin.input
new file mode 100644 (file)
index 0000000..05d09b7
--- /dev/null
@@ -0,0 +1,1240 @@
+#define WRITER_PROGRESS
+
+// Poison value for freed memory
+#define POISON 1
+// Memory with correct data
+#define WINE 0
+#define SLAB_SIZE 2
+
+#define read_poison    (data_read_first[0] == POISON || data_read_second[0] == POISON)
+
+#define RCU_GP_CTR_BIT (1 << 7)
+#define RCU_GP_CTR_NEST_MASK (RCU_GP_CTR_BIT - 1)
+
+//disabled
+#define REMOTE_BARRIERS
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+typedef per_proc_bit {
+       bit val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bitfield {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bitfield cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               /*
+                * 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, j);
+               reader_barrier[get_readerid()] = 0;
+       :: 1 ->
+               /*
+                * 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)
+//#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);                                                           \
+       i = 0;                                                                  \
+       do                                                                      \
+       :: i < NR_READERS ->                                                    \
+               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.                                            \
+                */                                                             \
+               do                                                              \
+               :: (reader_barrier[i] == 1) ->                                  \
+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(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, smp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only one reader */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* RCU data */
+DECLARE_CACHED_VAR(bit, rcu_data[SLAB_SIZE]);
+
+/* RCU pointer */
+#if (SLAB_SIZE == 2)
+DECLARE_CACHED_VAR(bit, rcu_ptr);
+bit ptr_read_first[NR_READERS];
+bit ptr_read_second[NR_READERS];
+#else
+DECLARE_CACHED_VAR(byte, rcu_ptr);
+byte ptr_read_first[NR_READERS];
+byte ptr_read_second[NR_READERS];
+#endif
+
+bit data_read_first[NR_READERS];
+bit data_read_second[NR_READERS];
+
+bit init_done = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               ptr_read_first[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb1;
+rmb1_end:
+                               data_read_first[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_first[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               ptr_read_second[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb2;
+rmb2_end:
+                               data_read_second[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_second[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+rmb1:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb1_end;
+rmb2:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_DATA                     (1 << 1)
+#define WRITE_PROC_WMB                 (1 << 2)
+#define WRITE_XCHG_PTR                 (1 << 3)
+
+#define WRITE_PROC_FIRST_MB            (1 << 4)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 5)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 6)
+#define WRITE_PROC_FIRST_WAIT          (1 << 7)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 8)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 9)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 10)
+#define WRITE_PROC_SECOND_WAIT         (1 << 11)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 12)
+
+#define WRITE_PROC_SECOND_MB           (1 << 13)
+
+#define WRITE_FREE                     (1 << 14)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_DATA                    \
+                                       | WRITE_PROC_WMB                \
+                                       | WRITE_XCHG_PTR                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB          \
+                                       | WRITE_FREE)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 15) - 1)
+
+/*
+ * Mutexes are implied around writer execution. A single writer at a time.
+ */
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte cur_data = 0, old_data, loop_nr = 0;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (loop_nr < 3) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               loop_nr = loop_nr + 1;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_WMB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+#endif
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_DATA) ->
+                       ooo_mem(i);
+                       cur_data = (cur_data + 1) % SLAB_SIZE;
+                       WRITE_CACHED_VAR(rcu_data[cur_data], WINE);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_DATA);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA,
+                                 WRITE_PROC_WMB) ->
+                       smp_wmb(i, j);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_WMB,
+                                 WRITE_XCHG_PTR) ->
+                       /* rcu_xchg_pointer() */
+                       atomic {
+                               old_data = READ_CACHED_VAR(rcu_ptr);
+                               WRITE_CACHED_VAR(rcu_ptr, cur_data);
+                       }
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_XCHG_PTR);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_WMB      /* No dependency on
+                                                        * WRITE_DATA because we
+                                                        * write to a
+                                                        * different location. */
+                                 | WRITE_PROC_SECOND_MB
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_FREE) ->
+                       WRITE_CACHED_VAR(rcu_data[old_data], POISON);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_FREE);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+               /*
+                * Note : Promela model adds implicit serialization of the
+                * WRITE_FREE instruction. Normally, it would be permitted to
+                * spill on the next loop execution. Given the validation we do
+                * checks for the data entry read to be poisoned, it's ok if
+                * we do not check "late arriving" memory poisoning.
+                */
+       :: 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
+#ifdef READER_PROGRESS
+               /*
+                * Make sure we don't block the reader's progress.
+                */
+               smp_mb_send(i, j, 5);
+#endif
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(rcu_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       ptr_read_first[i] = 1;
+                       ptr_read_second[i] = 1;
+                       data_read_first[i] = WINE;
+                       data_read_second[i] = WINE;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               INIT_CACHED_VAR(rcu_data[0], WINE, j);
+               i = 1;
+               do
+               :: i < SLAB_SIZE ->
+                       INIT_CACHED_VAR(rcu_data[i], POISON, j);
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_progress_writer.spin.input.trail b/formal-model/results/urcu-controldataflow-ipi/urcu_progress_writer.spin.input.trail
new file mode 100644 (file)
index 0000000..e8b02f0
--- /dev/null
@@ -0,0 +1,884 @@
+-2:3:-2
+-4:-4:-4
+1:0:4645
+2:3:4565
+3:3:4568
+4:3:4568
+5:3:4571
+6:3:4579
+7:3:4579
+8:3:4582
+9:3:4588
+10:3:4592
+11:3:4592
+12:3:4595
+13:3:4605
+14:3:4613
+15:3:4613
+16:3:4616
+17:3:4622
+18:3:4626
+19:3:4626
+20:3:4629
+21:3:4635
+22:3:4639
+23:3:4640
+24:0:4645
+25:3:4642
+26:0:4645
+27:2:2873
+28:0:4645
+29:2:2879
+30:0:4645
+31:2:2880
+32:0:4645
+33:2:2881
+34:0:4643
+35:2:2882
+36:0:4649
+37:2:2883
+38:0:4649
+39:2:2884
+40:2:2885
+41:2:2889
+42:2:2890
+43:2:2898
+44:2:2899
+45:2:2903
+46:2:2904
+47:2:2912
+48:2:2917
+49:2:2921
+50:2:2922
+51:2:2930
+52:2:2931
+53:2:2935
+54:2:2936
+55:2:2930
+56:2:2931
+57:2:2935
+58:2:2936
+59:2:2944
+60:2:2949
+61:2:2950
+62:2:2961
+63:2:2962
+64:2:2963
+65:2:2974
+66:2:2979
+67:2:2980
+68:2:2991
+69:2:2992
+70:2:2993
+71:2:2991
+72:2:2992
+73:2:2993
+74:2:3004
+75:2:3012
+76:0:4649
+77:2:2883
+78:0:4649
+79:2:3016
+80:2:3020
+81:2:3021
+82:2:3025
+83:2:3029
+84:2:3030
+85:2:3034
+86:2:3042
+87:2:3043
+88:2:3047
+89:2:3051
+90:2:3052
+91:2:3047
+92:2:3048
+93:2:3056
+94:0:4649
+95:2:2883
+96:0:4649
+97:2:3064
+98:2:3065
+99:2:3066
+100:0:4649
+101:2:2883
+102:0:4649
+103:2:3071
+104:0:4649
+105:2:3774
+106:2:3775
+107:2:3779
+108:2:3783
+109:2:3784
+110:2:3788
+111:2:3793
+112:2:3801
+113:2:3805
+114:2:3806
+115:2:3801
+116:2:3805
+117:2:3806
+118:2:3810
+119:2:3817
+120:2:3824
+121:2:3825
+122:2:3832
+123:2:3837
+124:2:3844
+125:2:3845
+126:2:3844
+127:2:3845
+128:2:3852
+129:2:3856
+130:0:4649
+131:2:3861
+132:0:4649
+133:2:3862
+134:0:4649
+135:2:3863
+136:0:4649
+137:2:3864
+138:0:4649
+139:1:2
+140:0:4649
+141:2:3865
+142:0:4649
+143:1:8
+144:0:4649
+145:1:9
+146:0:4649
+147:2:3864
+148:0:4649
+149:2:3865
+150:0:4649
+151:1:10
+152:0:4649
+153:2:3864
+154:0:4649
+155:2:3865
+156:0:4649
+157:1:11
+158:0:4649
+159:2:3864
+160:0:4649
+161:2:3865
+162:0:4649
+163:1:12
+164:0:4649
+165:2:3864
+166:0:4649
+167:2:3865
+168:0:4649
+169:1:13
+170:0:4649
+171:2:3864
+172:0:4649
+173:2:3865
+174:0:4649
+175:1:14
+176:0:4649
+177:1:15
+178:0:4649
+179:1:23
+180:0:4649
+181:1:24
+182:0:4649
+183:2:3864
+184:0:4649
+185:2:3865
+186:0:4649
+187:1:128
+188:1:129
+189:1:133
+190:1:134
+191:1:142
+192:1:143
+193:1:147
+194:1:148
+195:1:156
+196:1:161
+197:1:165
+198:1:166
+199:1:174
+200:1:175
+201:1:179
+202:1:180
+203:1:174
+204:1:175
+205:1:179
+206:1:180
+207:1:188
+208:1:193
+209:1:194
+210:1:205
+211:1:206
+212:1:207
+213:1:218
+214:1:223
+215:1:224
+216:1:235
+217:1:236
+218:1:237
+219:1:235
+220:1:236
+221:1:237
+222:1:248
+223:0:4649
+224:1:15
+225:0:4649
+226:1:23
+227:0:4649
+228:1:24
+229:0:4649
+230:2:3864
+231:0:4649
+232:2:3865
+233:0:4649
+234:1:257
+235:1:258
+236:0:4649
+237:1:15
+238:0:4649
+239:1:23
+240:0:4649
+241:1:24
+242:0:4649
+243:2:3864
+244:0:4649
+245:2:3865
+246:0:4649
+247:1:264
+248:1:265
+249:1:269
+250:1:270
+251:1:278
+252:1:279
+253:1:283
+254:1:284
+255:1:292
+256:1:297
+257:1:301
+258:1:302
+259:1:310
+260:1:311
+261:1:315
+262:1:316
+263:1:310
+264:1:311
+265:1:315
+266:1:316
+267:1:324
+268:1:329
+269:1:330
+270:1:341
+271:1:342
+272:1:343
+273:1:354
+274:1:359
+275:1:360
+276:1:371
+277:1:372
+278:1:373
+279:1:371
+280:1:372
+281:1:373
+282:1:384
+283:0:4649
+284:1:15
+285:0:4649
+286:1:23
+287:0:4649
+288:1:24
+289:0:4649
+290:2:3864
+291:0:4649
+292:2:3865
+293:0:4649
+294:1:393
+295:1:394
+296:1:398
+297:1:399
+298:1:407
+299:1:408
+300:1:412
+301:1:413
+302:1:421
+303:1:426
+304:1:430
+305:1:431
+306:1:439
+307:1:440
+308:1:444
+309:1:445
+310:1:439
+311:1:440
+312:1:444
+313:1:445
+314:1:453
+315:1:458
+316:1:459
+317:1:470
+318:1:471
+319:1:472
+320:1:483
+321:1:488
+322:1:489
+323:1:500
+324:1:501
+325:1:502
+326:1:500
+327:1:501
+328:1:502
+329:1:513
+330:1:520
+331:0:4649
+332:1:15
+333:0:4649
+334:1:16
+335:0:4649
+336:2:3864
+337:0:4649
+338:2:3865
+339:0:4649
+340:1:17
+341:0:4649
+342:2:3864
+343:0:4649
+344:2:3865
+345:0:4649
+346:1:28
+347:0:4649
+348:2:3864
+349:0:4649
+350:2:3865
+351:0:4649
+352:1:32
+353:1:33
+354:1:37
+355:1:38
+356:1:46
+357:1:54
+358:1:55
+359:1:59
+360:1:63
+361:1:64
+362:1:59
+363:1:63
+364:1:64
+365:1:68
+366:1:75
+367:1:82
+368:1:83
+369:1:90
+370:1:95
+371:1:102
+372:1:103
+373:1:102
+374:1:103
+375:1:110
+376:1:114
+377:0:4649
+378:2:3864
+379:0:4649
+380:2:3865
+381:0:4649
+382:1:119
+383:0:4649
+384:2:3866
+385:0:4649
+386:2:3871
+387:0:4649
+388:2:3872
+389:0:4649
+390:2:3880
+391:2:3881
+392:2:3885
+393:2:3889
+394:2:3890
+395:2:3894
+396:2:3902
+397:2:3903
+398:2:3907
+399:2:3911
+400:2:3912
+401:2:3907
+402:2:3911
+403:2:3912
+404:2:3916
+405:2:3923
+406:2:3930
+407:2:3931
+408:2:3938
+409:2:3943
+410:2:3950
+411:2:3951
+412:2:3950
+413:2:3951
+414:2:3958
+415:2:3962
+416:0:4649
+417:2:3073
+418:2:3755
+419:0:4649
+420:2:2883
+421:0:4649
+422:2:3074
+423:0:4649
+424:2:2883
+425:0:4649
+426:2:3077
+427:2:3078
+428:2:3082
+429:2:3083
+430:2:3091
+431:2:3092
+432:2:3096
+433:2:3097
+434:2:3105
+435:2:3110
+436:2:3114
+437:2:3115
+438:2:3123
+439:2:3124
+440:2:3128
+441:2:3129
+442:2:3123
+443:2:3124
+444:2:3128
+445:2:3129
+446:2:3137
+447:2:3142
+448:2:3143
+449:2:3154
+450:2:3155
+451:2:3156
+452:2:3167
+453:2:3172
+454:2:3173
+455:2:3184
+456:2:3185
+457:2:3186
+458:2:3184
+459:2:3185
+460:2:3186
+461:2:3197
+462:2:3204
+463:0:4649
+464:2:2883
+465:0:4649
+466:2:3208
+467:2:3209
+468:2:3210
+469:2:3222
+470:2:3223
+471:2:3227
+472:2:3228
+473:2:3236
+474:2:3241
+475:2:3245
+476:2:3246
+477:2:3254
+478:2:3255
+479:2:3259
+480:2:3260
+481:2:3254
+482:2:3255
+483:2:3259
+484:2:3260
+485:2:3268
+486:2:3273
+487:2:3274
+488:2:3285
+489:2:3286
+490:2:3287
+491:2:3298
+492:2:3303
+493:2:3304
+494:2:3315
+495:2:3316
+496:2:3317
+497:2:3315
+498:2:3316
+499:2:3317
+500:2:3328
+501:2:3337
+502:0:4649
+503:2:2883
+504:0:4649
+505:2:3343
+506:0:4649
+507:2:3972
+508:2:3973
+509:2:3977
+510:2:3981
+511:2:3982
+512:2:3986
+513:2:3994
+514:2:3995
+515:2:3999
+516:2:4003
+517:2:4004
+518:2:3999
+519:2:4003
+520:2:4004
+521:2:4008
+522:2:4015
+523:2:4022
+524:2:4023
+525:2:4030
+526:2:4035
+527:2:4042
+528:2:4043
+529:2:4042
+530:2:4043
+531:2:4050
+532:2:4054
+533:0:4649
+534:2:4059
+535:0:4649
+536:2:4060
+537:0:4649
+538:2:4061
+539:0:4649
+540:2:4062
+541:0:4649
+542:1:28
+543:0:4649
+544:2:4063
+545:0:4649
+546:2:4062
+547:0:4649
+548:1:32
+549:1:33
+550:1:37
+551:1:41
+552:1:42
+553:1:46
+554:1:54
+555:1:55
+556:1:59
+557:1:63
+558:1:64
+559:1:59
+560:1:63
+561:1:64
+562:1:68
+563:1:75
+564:1:82
+565:1:83
+566:1:90
+567:1:95
+568:1:102
+569:1:103
+570:1:102
+571:1:103
+572:1:110
+573:1:114
+-1:-1:-1
+574:0:4649
+575:2:4063
+576:0:4649
+577:2:4062
+578:0:4649
+579:1:119
+580:0:4649
+581:2:4063
+582:0:4649
+583:2:4064
+584:0:4649
+585:2:4069
+586:0:4649
+587:2:4070
+588:0:4649
+589:2:4078
+590:2:4079
+591:2:4083
+592:2:4087
+593:2:4088
+594:2:4092
+595:2:4100
+596:2:4101
+597:2:4105
+598:2:4109
+599:2:4110
+600:2:4105
+601:2:4109
+602:2:4110
+603:2:4114
+604:2:4121
+605:2:4128
+606:2:4129
+607:2:4136
+608:2:4141
+609:2:4148
+610:2:4149
+611:2:4148
+612:2:4149
+613:2:4156
+614:2:4160
+615:0:4649
+616:2:3345
+617:2:3755
+618:0:4649
+619:2:2883
+620:0:4649
+621:2:3208
+622:2:3209
+623:2:3213
+624:2:3214
+625:2:3222
+626:2:3223
+627:2:3227
+628:2:3228
+629:2:3236
+630:2:3241
+631:2:3245
+632:2:3246
+633:2:3254
+634:2:3255
+635:2:3259
+636:2:3260
+637:2:3254
+638:2:3255
+639:2:3259
+640:2:3260
+641:2:3268
+642:2:3273
+643:2:3274
+644:2:3285
+645:2:3286
+646:2:3287
+647:2:3298
+648:2:3303
+649:2:3304
+650:2:3315
+651:2:3316
+652:2:3317
+653:2:3315
+654:2:3316
+655:2:3317
+656:2:3328
+657:2:3337
+658:0:4649
+659:2:2883
+660:0:4649
+661:2:3343
+662:0:4649
+663:2:3972
+664:2:3973
+665:2:3977
+666:2:3981
+667:2:3982
+668:2:3986
+669:2:3994
+670:2:3995
+671:2:3999
+672:2:4003
+673:2:4004
+674:2:3999
+675:2:4003
+676:2:4004
+677:2:4008
+678:2:4015
+679:2:4022
+680:2:4023
+681:2:4030
+682:2:4035
+683:2:4042
+684:2:4043
+685:2:4042
+686:2:4043
+687:2:4050
+688:2:4054
+689:0:4649
+690:2:4059
+691:0:4649
+692:2:4060
+693:0:4649
+694:2:4061
+695:0:4649
+696:2:4062
+697:0:4649
+698:1:28
+699:0:4649
+700:2:4063
+701:0:4649
+702:1:32
+703:1:33
+704:1:37
+705:1:41
+706:1:42
+707:1:46
+708:1:54
+709:1:55
+710:1:59
+711:1:63
+712:1:64
+713:1:59
+714:1:63
+715:1:64
+716:1:68
+717:1:75
+718:1:82
+719:1:83
+720:1:90
+721:1:95
+722:1:102
+723:1:103
+724:1:102
+725:1:103
+726:1:110
+727:1:114
+728:0:4649
+729:2:4062
+730:0:4649
+731:2:4063
+732:0:4649
+733:1:119
+734:0:4649
+735:2:4064
+736:0:4649
+737:2:4069
+738:0:4649
+739:2:4070
+740:0:4649
+741:2:4078
+742:2:4079
+743:2:4083
+744:2:4087
+745:2:4088
+746:2:4092
+747:2:4100
+748:2:4101
+749:2:4105
+750:2:4109
+751:2:4110
+752:2:4105
+753:2:4109
+754:2:4110
+755:2:4114
+756:2:4121
+757:2:4128
+758:2:4129
+759:2:4136
+760:2:4141
+761:2:4148
+762:2:4149
+763:2:4148
+764:2:4149
+765:2:4156
+766:2:4160
+767:0:4649
+768:2:3345
+769:2:3755
+770:0:4649
+771:2:2883
+772:0:4649
+773:2:3208
+774:2:3209
+775:2:3213
+776:2:3214
+777:2:3222
+778:2:3223
+779:2:3227
+780:2:3228
+781:2:3236
+782:2:3241
+783:2:3245
+784:2:3246
+785:2:3254
+786:2:3255
+787:2:3259
+788:2:3260
+789:2:3254
+790:2:3255
+791:2:3259
+792:2:3260
+793:2:3268
+794:2:3273
+795:2:3274
+796:2:3285
+797:2:3286
+798:2:3287
+799:2:3298
+800:2:3303
+801:2:3304
+802:2:3315
+803:2:3316
+804:2:3317
+805:2:3315
+806:2:3316
+807:2:3317
+808:2:3328
+809:2:3337
+810:0:4649
+811:2:2883
+812:0:4649
+813:2:3343
+814:0:4649
+815:2:3972
+816:2:3973
+817:2:3977
+818:2:3981
+819:2:3982
+820:2:3986
+821:2:3994
+822:2:3995
+823:2:3999
+824:2:4003
+825:2:4004
+826:2:3999
+827:2:4003
+828:2:4004
+829:2:4008
+830:2:4015
+831:2:4022
+832:2:4023
+833:2:4030
+834:2:4035
+835:2:4042
+836:2:4043
+837:2:4042
+838:2:4043
+839:2:4050
+840:2:4054
+841:0:4649
+842:2:4059
+843:0:4649
+844:2:4060
+845:0:4649
+846:2:4061
+847:0:4649
+848:2:4062
+849:0:4649
+850:1:28
+851:0:4649
+852:2:4063
+853:0:4649
+854:2:4062
+855:0:4649
+856:1:32
+857:1:33
+858:1:37
+859:1:41
+860:1:42
+861:1:46
+862:1:54
+863:1:55
+864:1:59
+865:1:63
+866:1:64
+867:1:59
+868:1:63
+869:1:64
+870:1:68
+871:1:75
+872:1:82
+873:1:83
+874:1:90
+875:1:95
+876:1:102
+877:1:103
+878:1:102
+879:1:103
+880:1:110
+881:1:114
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_progress_writer_error.define b/formal-model/results/urcu-controldataflow-ipi/urcu_progress_writer_error.define
new file mode 100644 (file)
index 0000000..8d304f5
--- /dev/null
@@ -0,0 +1,2 @@
+#define WRITER_PROGRESS
+#define GEN_ERROR_WRITER_PROGRESS
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_progress_writer_error.log b/formal-model/results/urcu-controldataflow-ipi/urcu_progress_writer_error.log
new file mode 100644 (file)
index 0000000..499062a
--- /dev/null
@@ -0,0 +1,556 @@
+rm -f pan* trail.out .input.spin* *.spin.trail .input.define
+touch .input.define
+cat .input.define > pan.ltl
+cat DEFINES >> pan.ltl
+spin -f "!(`cat urcu_progress.ltl | grep -v ^//`)" >> pan.ltl
+cp urcu_progress_writer_error.define .input.define
+cat .input.define > .input.spin
+cat DEFINES >> .input.spin
+cat urcu.spin >> .input.spin
+rm -f .input.spin.trail
+spin -a -X -N pan.ltl .input.spin
+Exit-Status 0
+gcc -O2 -w -DHASH64 -o pan pan.c
+./pan -a -f -v -c1 -X -m10000000 -w20
+warning: for p.o. reduction to be valid the never claim must be stutter-invariant
+(never claims generated from LTL formulae are stutter-invariant)
+depth 0: Claim reached state 5 (line 1259)
+depth 23: Claim reached state 9 (line 1264)
+depth 51: Claim reached state 9 (line 1263)
+pan: acceptance cycle (at depth 1669)
+pan: wrote .input.spin.trail
+
+(Spin Version 5.1.7 -- 23 December 2008)
+Warning: Search not completed
+       + Partial Order Reduction
+
+Full statespace search for:
+       never claim             +
+       assertion violations    + (if within scope of claim)
+       acceptance   cycles     + (fairness enabled)
+       invalid end states      - (disabled by never claim)
+
+State-vector 88 byte, depth reached 4939, errors: 1
+   565131 states, stored (936882 visited)
+1.8676179e+08 states, matched
+1.8769867e+08 transitions (= visited+matched)
+1.0114449e+09 atomic steps
+hash conflicts:  18464180 (resolved)
+
+Stats on memory usage (in Megabytes):
+   62.518      equivalent memory usage for states (stored*(State-vector + overhead))
+   48.226      actual memory usage for states (compression: 77.14%)
+               state-vector as stored = 61 byte + 28 byte overhead
+    8.000      memory used for hash table (-w20)
+  457.764      memory used for DFS stack (-m10000000)
+  513.908      total actual memory usage
+
+unreached in proctype urcu_reader
+       line 251, "pan.___", state 30, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 259, "pan.___", state 52, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 263, "pan.___", state 61, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 228, "pan.___", state 77, "(1)"
+       line 232, "pan.___", state 85, "(1)"
+       line 236, "pan.___", state 97, "(1)"
+       line 240, "pan.___", state 105, "(1)"
+       line 396, "pan.___", state 131, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 163, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 177, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 196, "(1)"
+       line 422, "pan.___", state 226, "(1)"
+       line 426, "pan.___", state 239, "(1)"
+       line 671, "pan.___", state 260, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<1))"
+       line 396, "pan.___", state 267, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 299, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 313, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 332, "(1)"
+       line 422, "pan.___", state 362, "(1)"
+       line 426, "pan.___", state 375, "(1)"
+       line 396, "pan.___", state 396, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 428, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 442, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 461, "(1)"
+       line 422, "pan.___", state 491, "(1)"
+       line 426, "pan.___", state 504, "(1)"
+       line 396, "pan.___", state 527, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 529, "(1)"
+       line 396, "pan.___", state 530, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 530, "else"
+       line 396, "pan.___", state 533, "(1)"
+       line 400, "pan.___", state 541, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 543, "(1)"
+       line 400, "pan.___", state 544, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 544, "else"
+       line 400, "pan.___", state 547, "(1)"
+       line 400, "pan.___", state 548, "(1)"
+       line 400, "pan.___", state 548, "(1)"
+       line 398, "pan.___", state 553, "((i<1))"
+       line 398, "pan.___", state 553, "((i>=1))"
+       line 405, "pan.___", state 559, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 561, "(1)"
+       line 405, "pan.___", state 562, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 405, "pan.___", state 562, "else"
+       line 405, "pan.___", state 565, "(1)"
+       line 405, "pan.___", state 566, "(1)"
+       line 405, "pan.___", state 566, "(1)"
+       line 409, "pan.___", state 573, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 575, "(1)"
+       line 409, "pan.___", state 576, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 409, "pan.___", state 576, "else"
+       line 409, "pan.___", state 579, "(1)"
+       line 409, "pan.___", state 580, "(1)"
+       line 409, "pan.___", state 580, "(1)"
+       line 407, "pan.___", state 585, "((i<2))"
+       line 407, "pan.___", state 585, "((i>=2))"
+       line 413, "pan.___", state 592, "(1)"
+       line 413, "pan.___", state 593, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 593, "else"
+       line 413, "pan.___", state 596, "(1)"
+       line 413, "pan.___", state 597, "(1)"
+       line 413, "pan.___", state 597, "(1)"
+       line 417, "pan.___", state 605, "(1)"
+       line 417, "pan.___", state 606, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 606, "else"
+       line 417, "pan.___", state 609, "(1)"
+       line 417, "pan.___", state 610, "(1)"
+       line 417, "pan.___", state 610, "(1)"
+       line 415, "pan.___", state 615, "((i<1))"
+       line 415, "pan.___", state 615, "((i>=1))"
+       line 422, "pan.___", state 622, "(1)"
+       line 422, "pan.___", state 623, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 422, "pan.___", state 623, "else"
+       line 422, "pan.___", state 626, "(1)"
+       line 422, "pan.___", state 627, "(1)"
+       line 422, "pan.___", state 627, "(1)"
+       line 426, "pan.___", state 635, "(1)"
+       line 426, "pan.___", state 636, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 426, "pan.___", state 636, "else"
+       line 426, "pan.___", state 639, "(1)"
+       line 426, "pan.___", state 640, "(1)"
+       line 426, "pan.___", state 640, "(1)"
+       line 424, "pan.___", state 645, "((i<2))"
+       line 424, "pan.___", state 645, "((i>=2))"
+       line 431, "pan.___", state 649, "(1)"
+       line 431, "pan.___", state 649, "(1)"
+       line 671, "pan.___", state 652, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 671, "pan.___", state 653, "_proc_urcu_reader = (_proc_urcu_reader|(1<<5))"
+       line 671, "pan.___", state 654, "(1)"
+       line 396, "pan.___", state 661, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 693, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 707, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 726, "(1)"
+       line 422, "pan.___", state 756, "(1)"
+       line 426, "pan.___", state 769, "(1)"
+       line 396, "pan.___", state 797, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 799, "(1)"
+       line 396, "pan.___", state 800, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 800, "else"
+       line 396, "pan.___", state 803, "(1)"
+       line 400, "pan.___", state 811, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 813, "(1)"
+       line 400, "pan.___", state 814, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 814, "else"
+       line 400, "pan.___", state 817, "(1)"
+       line 400, "pan.___", state 818, "(1)"
+       line 400, "pan.___", state 818, "(1)"
+       line 398, "pan.___", state 823, "((i<1))"
+       line 398, "pan.___", state 823, "((i>=1))"
+       line 405, "pan.___", state 829, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 831, "(1)"
+       line 405, "pan.___", state 832, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 405, "pan.___", state 832, "else"
+       line 405, "pan.___", state 835, "(1)"
+       line 405, "pan.___", state 836, "(1)"
+       line 405, "pan.___", state 836, "(1)"
+       line 409, "pan.___", state 843, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 845, "(1)"
+       line 409, "pan.___", state 846, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 409, "pan.___", state 846, "else"
+       line 409, "pan.___", state 849, "(1)"
+       line 409, "pan.___", state 850, "(1)"
+       line 409, "pan.___", state 850, "(1)"
+       line 407, "pan.___", state 855, "((i<2))"
+       line 407, "pan.___", state 855, "((i>=2))"
+       line 413, "pan.___", state 862, "(1)"
+       line 413, "pan.___", state 863, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 863, "else"
+       line 413, "pan.___", state 866, "(1)"
+       line 413, "pan.___", state 867, "(1)"
+       line 413, "pan.___", state 867, "(1)"
+       line 417, "pan.___", state 875, "(1)"
+       line 417, "pan.___", state 876, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 876, "else"
+       line 417, "pan.___", state 879, "(1)"
+       line 417, "pan.___", state 880, "(1)"
+       line 417, "pan.___", state 880, "(1)"
+       line 415, "pan.___", state 885, "((i<1))"
+       line 415, "pan.___", state 885, "((i>=1))"
+       line 422, "pan.___", state 892, "(1)"
+       line 422, "pan.___", state 893, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 422, "pan.___", state 893, "else"
+       line 422, "pan.___", state 896, "(1)"
+       line 422, "pan.___", state 897, "(1)"
+       line 422, "pan.___", state 897, "(1)"
+       line 426, "pan.___", state 905, "(1)"
+       line 426, "pan.___", state 906, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 426, "pan.___", state 906, "else"
+       line 426, "pan.___", state 909, "(1)"
+       line 426, "pan.___", state 910, "(1)"
+       line 426, "pan.___", state 910, "(1)"
+       line 431, "pan.___", state 919, "(1)"
+       line 431, "pan.___", state 919, "(1)"
+       line 396, "pan.___", state 926, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 928, "(1)"
+       line 396, "pan.___", state 929, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 929, "else"
+       line 396, "pan.___", state 932, "(1)"
+       line 400, "pan.___", state 940, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 942, "(1)"
+       line 400, "pan.___", state 943, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 943, "else"
+       line 400, "pan.___", state 946, "(1)"
+       line 400, "pan.___", state 947, "(1)"
+       line 400, "pan.___", state 947, "(1)"
+       line 398, "pan.___", state 952, "((i<1))"
+       line 398, "pan.___", state 952, "((i>=1))"
+       line 405, "pan.___", state 958, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 960, "(1)"
+       line 405, "pan.___", state 961, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 405, "pan.___", state 961, "else"
+       line 405, "pan.___", state 964, "(1)"
+       line 405, "pan.___", state 965, "(1)"
+       line 405, "pan.___", state 965, "(1)"
+       line 409, "pan.___", state 972, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 974, "(1)"
+       line 409, "pan.___", state 975, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 409, "pan.___", state 975, "else"
+       line 409, "pan.___", state 978, "(1)"
+       line 409, "pan.___", state 979, "(1)"
+       line 409, "pan.___", state 979, "(1)"
+       line 407, "pan.___", state 984, "((i<2))"
+       line 407, "pan.___", state 984, "((i>=2))"
+       line 413, "pan.___", state 991, "(1)"
+       line 413, "pan.___", state 992, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 992, "else"
+       line 413, "pan.___", state 995, "(1)"
+       line 413, "pan.___", state 996, "(1)"
+       line 413, "pan.___", state 996, "(1)"
+       line 417, "pan.___", state 1004, "(1)"
+       line 417, "pan.___", state 1005, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 1005, "else"
+       line 417, "pan.___", state 1008, "(1)"
+       line 417, "pan.___", state 1009, "(1)"
+       line 417, "pan.___", state 1009, "(1)"
+       line 415, "pan.___", state 1014, "((i<1))"
+       line 415, "pan.___", state 1014, "((i>=1))"
+       line 422, "pan.___", state 1021, "(1)"
+       line 422, "pan.___", state 1022, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 422, "pan.___", state 1022, "else"
+       line 422, "pan.___", state 1025, "(1)"
+       line 422, "pan.___", state 1026, "(1)"
+       line 422, "pan.___", state 1026, "(1)"
+       line 426, "pan.___", state 1034, "(1)"
+       line 426, "pan.___", state 1035, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 426, "pan.___", state 1035, "else"
+       line 426, "pan.___", state 1038, "(1)"
+       line 426, "pan.___", state 1039, "(1)"
+       line 426, "pan.___", state 1039, "(1)"
+       line 424, "pan.___", state 1044, "((i<2))"
+       line 424, "pan.___", state 1044, "((i>=2))"
+       line 431, "pan.___", state 1048, "(1)"
+       line 431, "pan.___", state 1048, "(1)"
+       line 679, "pan.___", state 1052, "_proc_urcu_reader = (_proc_urcu_reader|(1<<11))"
+       line 396, "pan.___", state 1057, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 1089, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 1103, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 1122, "(1)"
+       line 422, "pan.___", state 1152, "(1)"
+       line 426, "pan.___", state 1165, "(1)"
+       line 396, "pan.___", state 1189, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 1221, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 1235, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 1254, "(1)"
+       line 422, "pan.___", state 1284, "(1)"
+       line 426, "pan.___", state 1297, "(1)"
+       line 396, "pan.___", state 1322, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 1354, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 1368, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 1387, "(1)"
+       line 422, "pan.___", state 1417, "(1)"
+       line 426, "pan.___", state 1430, "(1)"
+       line 396, "pan.___", state 1451, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 1483, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 1497, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 1516, "(1)"
+       line 422, "pan.___", state 1546, "(1)"
+       line 426, "pan.___", state 1559, "(1)"
+       line 396, "pan.___", state 1585, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 1617, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 1631, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 1650, "(1)"
+       line 422, "pan.___", state 1680, "(1)"
+       line 426, "pan.___", state 1693, "(1)"
+       line 396, "pan.___", state 1714, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 1746, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 1760, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 1779, "(1)"
+       line 422, "pan.___", state 1809, "(1)"
+       line 426, "pan.___", state 1822, "(1)"
+       line 396, "pan.___", state 1846, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 1878, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 1892, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 1911, "(1)"
+       line 422, "pan.___", state 1941, "(1)"
+       line 426, "pan.___", state 1954, "(1)"
+       line 718, "pan.___", state 1975, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<19))"
+       line 396, "pan.___", state 1982, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 2014, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 2028, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 2047, "(1)"
+       line 422, "pan.___", state 2077, "(1)"
+       line 426, "pan.___", state 2090, "(1)"
+       line 396, "pan.___", state 2111, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 2143, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 2157, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 2176, "(1)"
+       line 422, "pan.___", state 2206, "(1)"
+       line 426, "pan.___", state 2219, "(1)"
+       line 396, "pan.___", state 2242, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2244, "(1)"
+       line 396, "pan.___", state 2245, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 2245, "else"
+       line 396, "pan.___", state 2248, "(1)"
+       line 400, "pan.___", state 2256, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2258, "(1)"
+       line 400, "pan.___", state 2259, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 2259, "else"
+       line 400, "pan.___", state 2262, "(1)"
+       line 400, "pan.___", state 2263, "(1)"
+       line 400, "pan.___", state 2263, "(1)"
+       line 398, "pan.___", state 2268, "((i<1))"
+       line 398, "pan.___", state 2268, "((i>=1))"
+       line 405, "pan.___", state 2274, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 2276, "(1)"
+       line 405, "pan.___", state 2277, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 405, "pan.___", state 2277, "else"
+       line 405, "pan.___", state 2280, "(1)"
+       line 405, "pan.___", state 2281, "(1)"
+       line 405, "pan.___", state 2281, "(1)"
+       line 409, "pan.___", state 2288, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 2290, "(1)"
+       line 409, "pan.___", state 2291, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 409, "pan.___", state 2291, "else"
+       line 409, "pan.___", state 2294, "(1)"
+       line 409, "pan.___", state 2295, "(1)"
+       line 409, "pan.___", state 2295, "(1)"
+       line 407, "pan.___", state 2300, "((i<2))"
+       line 407, "pan.___", state 2300, "((i>=2))"
+       line 413, "pan.___", state 2307, "(1)"
+       line 413, "pan.___", state 2308, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 2308, "else"
+       line 413, "pan.___", state 2311, "(1)"
+       line 413, "pan.___", state 2312, "(1)"
+       line 413, "pan.___", state 2312, "(1)"
+       line 417, "pan.___", state 2320, "(1)"
+       line 417, "pan.___", state 2321, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 2321, "else"
+       line 417, "pan.___", state 2324, "(1)"
+       line 417, "pan.___", state 2325, "(1)"
+       line 417, "pan.___", state 2325, "(1)"
+       line 415, "pan.___", state 2330, "((i<1))"
+       line 415, "pan.___", state 2330, "((i>=1))"
+       line 422, "pan.___", state 2337, "(1)"
+       line 422, "pan.___", state 2338, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 422, "pan.___", state 2338, "else"
+       line 422, "pan.___", state 2341, "(1)"
+       line 422, "pan.___", state 2342, "(1)"
+       line 422, "pan.___", state 2342, "(1)"
+       line 426, "pan.___", state 2350, "(1)"
+       line 426, "pan.___", state 2351, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 426, "pan.___", state 2351, "else"
+       line 426, "pan.___", state 2354, "(1)"
+       line 426, "pan.___", state 2355, "(1)"
+       line 426, "pan.___", state 2355, "(1)"
+       line 424, "pan.___", state 2360, "((i<2))"
+       line 424, "pan.___", state 2360, "((i>=2))"
+       line 431, "pan.___", state 2364, "(1)"
+       line 431, "pan.___", state 2364, "(1)"
+       line 718, "pan.___", state 2367, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 718, "pan.___", state 2368, "_proc_urcu_reader = (_proc_urcu_reader|(1<<23))"
+       line 718, "pan.___", state 2369, "(1)"
+       line 396, "pan.___", state 2376, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 2408, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 2422, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 2441, "(1)"
+       line 422, "pan.___", state 2471, "(1)"
+       line 426, "pan.___", state 2484, "(1)"
+       line 396, "pan.___", state 2511, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 2543, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 2557, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 2576, "(1)"
+       line 422, "pan.___", state 2606, "(1)"
+       line 426, "pan.___", state 2619, "(1)"
+       line 396, "pan.___", state 2640, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 2672, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 2686, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 2705, "(1)"
+       line 422, "pan.___", state 2735, "(1)"
+       line 426, "pan.___", state 2748, "(1)"
+       line 228, "pan.___", state 2781, "(1)"
+       line 236, "pan.___", state 2801, "(1)"
+       line 240, "pan.___", state 2809, "(1)"
+       line 228, "pan.___", state 2824, "(1)"
+       line 236, "pan.___", state 2844, "(1)"
+       line 240, "pan.___", state 2852, "(1)"
+       line 878, "pan.___", state 2869, "-end-"
+       (278 of 2869 states)
+unreached in proctype urcu_writer
+       line 396, "pan.___", state 18, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 32, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 50, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 83, "(1)"
+       line 417, "pan.___", state 96, "(1)"
+       line 422, "pan.___", state 113, "(1)"
+       line 251, "pan.___", state 149, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 255, "pan.___", state 158, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 259, "pan.___", state 171, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 211, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 225, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 243, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 257, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 276, "(1)"
+       line 417, "pan.___", state 289, "(1)"
+       line 422, "pan.___", state 306, "(1)"
+       line 426, "pan.___", state 319, "(1)"
+       line 400, "pan.___", state 356, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 374, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 388, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 417, "pan.___", state 420, "(1)"
+       line 422, "pan.___", state 437, "(1)"
+       line 426, "pan.___", state 450, "(1)"
+       line 396, "pan.___", state 477, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 479, "(1)"
+       line 396, "pan.___", state 480, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 480, "else"
+       line 396, "pan.___", state 483, "(1)"
+       line 400, "pan.___", state 491, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 493, "(1)"
+       line 400, "pan.___", state 494, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 494, "else"
+       line 400, "pan.___", state 497, "(1)"
+       line 400, "pan.___", state 498, "(1)"
+       line 400, "pan.___", state 498, "(1)"
+       line 398, "pan.___", state 503, "((i<1))"
+       line 398, "pan.___", state 503, "((i>=1))"
+       line 405, "pan.___", state 509, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 511, "(1)"
+       line 405, "pan.___", state 512, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 405, "pan.___", state 512, "else"
+       line 405, "pan.___", state 515, "(1)"
+       line 405, "pan.___", state 516, "(1)"
+       line 405, "pan.___", state 516, "(1)"
+       line 409, "pan.___", state 523, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 525, "(1)"
+       line 409, "pan.___", state 526, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 409, "pan.___", state 526, "else"
+       line 409, "pan.___", state 529, "(1)"
+       line 409, "pan.___", state 530, "(1)"
+       line 409, "pan.___", state 530, "(1)"
+       line 407, "pan.___", state 535, "((i<2))"
+       line 407, "pan.___", state 535, "((i>=2))"
+       line 413, "pan.___", state 542, "(1)"
+       line 413, "pan.___", state 543, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 543, "else"
+       line 413, "pan.___", state 546, "(1)"
+       line 413, "pan.___", state 547, "(1)"
+       line 413, "pan.___", state 547, "(1)"
+       line 417, "pan.___", state 555, "(1)"
+       line 417, "pan.___", state 556, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 556, "else"
+       line 417, "pan.___", state 559, "(1)"
+       line 417, "pan.___", state 560, "(1)"
+       line 417, "pan.___", state 560, "(1)"
+       line 415, "pan.___", state 565, "((i<1))"
+       line 415, "pan.___", state 565, "((i>=1))"
+       line 422, "pan.___", state 572, "(1)"
+       line 422, "pan.___", state 573, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 422, "pan.___", state 573, "else"
+       line 422, "pan.___", state 576, "(1)"
+       line 422, "pan.___", state 577, "(1)"
+       line 422, "pan.___", state 577, "(1)"
+       line 426, "pan.___", state 585, "(1)"
+       line 426, "pan.___", state 586, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 426, "pan.___", state 586, "else"
+       line 426, "pan.___", state 589, "(1)"
+       line 426, "pan.___", state 590, "(1)"
+       line 426, "pan.___", state 590, "(1)"
+       line 431, "pan.___", state 599, "(1)"
+       line 431, "pan.___", state 599, "(1)"
+       line 400, "pan.___", state 619, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 637, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 651, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 417, "pan.___", state 683, "(1)"
+       line 422, "pan.___", state 700, "(1)"
+       line 426, "pan.___", state 713, "(1)"
+       line 400, "pan.___", state 748, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 766, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 780, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 417, "pan.___", state 812, "(1)"
+       line 422, "pan.___", state 829, "(1)"
+       line 426, "pan.___", state 842, "(1)"
+       line 400, "pan.___", state 879, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 897, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 911, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 417, "pan.___", state 943, "(1)"
+       line 422, "pan.___", state 960, "(1)"
+       line 426, "pan.___", state 973, "(1)"
+       line 400, "pan.___", state 1013, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 1031, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 1045, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 417, "pan.___", state 1077, "(1)"
+       line 422, "pan.___", state 1094, "(1)"
+       line 426, "pan.___", state 1107, "(1)"
+       line 251, "pan.___", state 1153, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 255, "pan.___", state 1162, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 259, "pan.___", state 1177, "(1)"
+       line 263, "pan.___", state 1184, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 228, "pan.___", state 1200, "(1)"
+       line 232, "pan.___", state 1208, "(1)"
+       line 236, "pan.___", state 1220, "(1)"
+       line 240, "pan.___", state 1228, "(1)"
+       line 251, "pan.___", state 1259, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 255, "pan.___", state 1268, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 259, "pan.___", state 1281, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 263, "pan.___", state 1290, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 228, "pan.___", state 1306, "(1)"
+       line 232, "pan.___", state 1314, "(1)"
+       line 236, "pan.___", state 1326, "(1)"
+       line 240, "pan.___", state 1334, "(1)"
+       line 255, "pan.___", state 1360, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 259, "pan.___", state 1373, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 263, "pan.___", state 1382, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 228, "pan.___", state 1398, "(1)"
+       line 232, "pan.___", state 1406, "(1)"
+       line 236, "pan.___", state 1418, "(1)"
+       line 240, "pan.___", state 1426, "(1)"
+       line 251, "pan.___", state 1457, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 255, "pan.___", state 1466, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 259, "pan.___", state 1479, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 263, "pan.___", state 1488, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 228, "pan.___", state 1504, "(1)"
+       line 232, "pan.___", state 1512, "(1)"
+       line 236, "pan.___", state 1524, "(1)"
+       line 240, "pan.___", state 1532, "(1)"
+       line 1205, "pan.___", state 1548, "-end-"
+       (118 of 1548 states)
+unreached in proctype :init:
+       (0 of 78 states)
+unreached in proctype :never:
+       line 1266, "pan.___", state 11, "-end-"
+       (1 of 11 states)
+
+pan: elapsed time 237 seconds
+pan: rate 3946.2617 states/second
+pan: avg transition delay 1.2648e-06 usec
+cp .input.spin urcu_progress_writer_error.spin.input
+cp .input.spin.trail urcu_progress_writer_error.spin.input.trail
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_progress_writer_error.spin.input b/formal-model/results/urcu-controldataflow-ipi/urcu_progress_writer_error.spin.input
new file mode 100644 (file)
index 0000000..d01c814
--- /dev/null
@@ -0,0 +1,1241 @@
+#define WRITER_PROGRESS
+#define GEN_ERROR_WRITER_PROGRESS
+
+// Poison value for freed memory
+#define POISON 1
+// Memory with correct data
+#define WINE 0
+#define SLAB_SIZE 2
+
+#define read_poison    (data_read_first[0] == POISON || data_read_second[0] == POISON)
+
+#define RCU_GP_CTR_BIT (1 << 7)
+#define RCU_GP_CTR_NEST_MASK (RCU_GP_CTR_BIT - 1)
+
+//disabled
+#define REMOTE_BARRIERS
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+typedef per_proc_bit {
+       bit val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bitfield {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bitfield cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               /*
+                * 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, j);
+               reader_barrier[get_readerid()] = 0;
+       :: 1 ->
+               /*
+                * 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)
+//#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);                                                           \
+       i = 0;                                                                  \
+       do                                                                      \
+       :: i < NR_READERS ->                                                    \
+               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.                                            \
+                */                                                             \
+               do                                                              \
+               :: (reader_barrier[i] == 1) ->                                  \
+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(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, smp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only one reader */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* RCU data */
+DECLARE_CACHED_VAR(bit, rcu_data[SLAB_SIZE]);
+
+/* RCU pointer */
+#if (SLAB_SIZE == 2)
+DECLARE_CACHED_VAR(bit, rcu_ptr);
+bit ptr_read_first[NR_READERS];
+bit ptr_read_second[NR_READERS];
+#else
+DECLARE_CACHED_VAR(byte, rcu_ptr);
+byte ptr_read_first[NR_READERS];
+byte ptr_read_second[NR_READERS];
+#endif
+
+bit data_read_first[NR_READERS];
+bit data_read_second[NR_READERS];
+
+bit init_done = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               ptr_read_first[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb1;
+rmb1_end:
+                               data_read_first[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_first[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               ptr_read_second[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb2;
+rmb2_end:
+                               data_read_second[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_second[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+rmb1:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb1_end;
+rmb2:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_DATA                     (1 << 1)
+#define WRITE_PROC_WMB                 (1 << 2)
+#define WRITE_XCHG_PTR                 (1 << 3)
+
+#define WRITE_PROC_FIRST_MB            (1 << 4)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 5)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 6)
+#define WRITE_PROC_FIRST_WAIT          (1 << 7)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 8)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 9)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 10)
+#define WRITE_PROC_SECOND_WAIT         (1 << 11)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 12)
+
+#define WRITE_PROC_SECOND_MB           (1 << 13)
+
+#define WRITE_FREE                     (1 << 14)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_DATA                    \
+                                       | WRITE_PROC_WMB                \
+                                       | WRITE_XCHG_PTR                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB          \
+                                       | WRITE_FREE)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 15) - 1)
+
+/*
+ * Mutexes are implied around writer execution. A single writer at a time.
+ */
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte cur_data = 0, old_data, loop_nr = 0;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (loop_nr < 3) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               loop_nr = loop_nr + 1;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_WMB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+#endif
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_DATA) ->
+                       ooo_mem(i);
+                       cur_data = (cur_data + 1) % SLAB_SIZE;
+                       WRITE_CACHED_VAR(rcu_data[cur_data], WINE);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_DATA);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA,
+                                 WRITE_PROC_WMB) ->
+                       smp_wmb(i, j);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_WMB,
+                                 WRITE_XCHG_PTR) ->
+                       /* rcu_xchg_pointer() */
+                       atomic {
+                               old_data = READ_CACHED_VAR(rcu_ptr);
+                               WRITE_CACHED_VAR(rcu_ptr, cur_data);
+                       }
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_XCHG_PTR);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_WMB      /* No dependency on
+                                                        * WRITE_DATA because we
+                                                        * write to a
+                                                        * different location. */
+                                 | WRITE_PROC_SECOND_MB
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_FREE) ->
+                       WRITE_CACHED_VAR(rcu_data[old_data], POISON);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_FREE);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+               /*
+                * Note : Promela model adds implicit serialization of the
+                * WRITE_FREE instruction. Normally, it would be permitted to
+                * spill on the next loop execution. Given the validation we do
+                * checks for the data entry read to be poisoned, it's ok if
+                * we do not check "late arriving" memory poisoning.
+                */
+       :: 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
+#ifdef READER_PROGRESS
+               /*
+                * Make sure we don't block the reader's progress.
+                */
+               smp_mb_send(i, j, 5);
+#endif
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(rcu_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       ptr_read_first[i] = 1;
+                       ptr_read_second[i] = 1;
+                       data_read_first[i] = WINE;
+                       data_read_second[i] = WINE;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               INIT_CACHED_VAR(rcu_data[0], WINE, j);
+               i = 1;
+               do
+               :: i < SLAB_SIZE ->
+                       INIT_CACHED_VAR(rcu_data[i], POISON, j);
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-ipi/urcu_progress_writer_error.spin.input.trail b/formal-model/results/urcu-controldataflow-ipi/urcu_progress_writer_error.spin.input.trail
new file mode 100644 (file)
index 0000000..64285b2
--- /dev/null
@@ -0,0 +1,1830 @@
+-2:3:-2
+-4:-4:-4
+1:0:4497
+2:3:4417
+3:3:4420
+4:3:4420
+5:3:4423
+6:3:4431
+7:3:4431
+8:3:4434
+9:3:4440
+10:3:4444
+11:3:4444
+12:3:4447
+13:3:4457
+14:3:4465
+15:3:4465
+16:3:4468
+17:3:4474
+18:3:4478
+19:3:4478
+20:3:4481
+21:3:4487
+22:3:4491
+23:3:4492
+24:0:4497
+25:3:4494
+26:0:4497
+27:2:2871
+28:0:4497
+29:2:2877
+30:0:4497
+31:2:2878
+32:0:4497
+33:2:2879
+34:0:4497
+35:2:2880
+36:0:4497
+37:2:2881
+38:0:4497
+39:2:2882
+40:2:2883
+41:2:2887
+42:2:2888
+43:2:2896
+44:2:2897
+45:2:2901
+46:2:2902
+47:2:2910
+48:2:2915
+49:2:2919
+50:2:2920
+51:2:2928
+52:2:2929
+53:2:2933
+54:2:2934
+55:2:2928
+56:2:2929
+57:2:2933
+58:2:2934
+59:2:2942
+60:2:2947
+61:2:2948
+62:2:2959
+63:2:2960
+64:2:2961
+65:2:2972
+66:2:2977
+67:2:2978
+68:2:2989
+69:2:2990
+70:2:2991
+71:2:2989
+72:2:2990
+73:2:2991
+74:2:3002
+75:2:3010
+76:0:4497
+77:2:2881
+78:0:4497
+79:2:3014
+80:2:3018
+81:2:3019
+82:2:3023
+83:2:3027
+84:2:3028
+85:2:3032
+86:2:3040
+87:2:3041
+88:2:3045
+89:2:3049
+90:2:3050
+91:2:3045
+92:2:3046
+93:2:3054
+94:0:4497
+95:2:2881
+96:0:4497
+97:2:3062
+98:2:3063
+99:2:3064
+100:0:4497
+101:2:2881
+102:0:4497
+103:2:3069
+104:0:4497
+105:2:4022
+106:2:4023
+107:2:4027
+108:2:4031
+109:2:4032
+110:2:4036
+111:2:4041
+112:2:4049
+113:2:4053
+114:2:4054
+115:2:4049
+116:2:4053
+117:2:4054
+118:2:4058
+119:2:4065
+120:2:4072
+121:2:4073
+122:2:4080
+123:2:4085
+124:2:4092
+125:2:4093
+126:2:4092
+127:2:4093
+128:2:4100
+129:2:4104
+130:0:4497
+131:2:4109
+132:0:4497
+133:2:4110
+134:0:4497
+135:2:4111
+136:0:4497
+137:2:4112
+138:0:4497
+139:1:2
+140:0:4497
+141:1:8
+142:0:4497
+143:1:9
+144:0:4497
+145:2:4113
+146:0:4497
+147:1:10
+148:0:4497
+149:2:4112
+150:0:4497
+151:1:11
+152:0:4497
+153:2:4113
+154:0:4497
+155:1:12
+156:0:4497
+157:2:4112
+158:0:4497
+159:1:13
+160:0:4497
+161:2:4113
+162:0:4497
+163:1:14
+164:0:4497
+165:1:15
+166:0:4497
+167:1:16
+168:0:4497
+169:2:4112
+170:0:4497
+171:1:17
+172:0:4497
+173:2:4113
+174:0:4497
+175:1:26
+176:0:4497
+177:2:4112
+178:0:4497
+179:1:30
+180:1:31
+181:1:35
+182:1:39
+183:1:40
+184:1:44
+185:1:52
+186:1:53
+187:1:57
+188:1:61
+189:1:62
+190:1:57
+191:1:61
+192:1:62
+193:1:66
+194:1:73
+195:1:80
+196:1:81
+197:1:88
+198:1:93
+199:1:100
+200:1:101
+201:1:100
+202:1:101
+203:1:108
+204:1:112
+205:0:4497
+206:2:4113
+207:0:4497
+208:1:117
+209:0:4497
+210:2:4114
+211:0:4497
+212:2:4119
+213:0:4497
+214:2:4120
+215:0:4497
+216:2:4128
+217:2:4129
+218:2:4133
+219:2:4137
+220:2:4138
+221:2:4142
+222:2:4150
+223:2:4151
+224:2:4155
+225:2:4159
+226:2:4160
+227:2:4155
+228:2:4159
+229:2:4160
+230:2:4164
+231:2:4171
+232:2:4178
+233:2:4179
+234:2:4186
+235:2:4191
+236:2:4198
+237:2:4199
+238:2:4198
+239:2:4199
+240:2:4206
+241:2:4210
+242:0:4497
+243:2:3071
+244:2:4003
+245:0:4497
+246:2:2881
+247:0:4497
+248:2:3072
+249:0:4497
+250:2:2881
+251:0:4497
+252:2:3075
+253:2:3076
+254:2:3080
+255:2:3081
+256:2:3089
+257:2:3090
+258:2:3094
+259:2:3095
+260:2:3103
+261:2:3108
+262:2:3112
+263:2:3113
+264:2:3121
+265:2:3122
+266:2:3126
+267:2:3127
+268:2:3121
+269:2:3122
+270:2:3126
+271:2:3127
+272:2:3135
+273:2:3140
+274:2:3141
+275:2:3152
+276:2:3153
+277:2:3154
+278:2:3165
+279:2:3170
+280:2:3171
+281:2:3182
+282:2:3183
+283:2:3184
+284:2:3182
+285:2:3183
+286:2:3184
+287:2:3195
+288:2:3202
+289:0:4497
+290:2:2881
+291:0:4497
+292:2:3206
+293:2:3207
+294:2:3208
+295:2:3220
+296:2:3221
+297:2:3225
+298:2:3226
+299:2:3234
+300:2:3239
+301:2:3243
+302:2:3244
+303:2:3252
+304:2:3253
+305:2:3257
+306:2:3258
+307:2:3252
+308:2:3253
+309:2:3257
+310:2:3258
+311:2:3266
+312:2:3271
+313:2:3272
+314:2:3283
+315:2:3284
+316:2:3285
+317:2:3296
+318:2:3301
+319:2:3302
+320:2:3313
+321:2:3314
+322:2:3315
+323:2:3313
+324:2:3314
+325:2:3315
+326:2:3326
+327:2:3337
+328:2:3338
+329:0:4497
+330:2:2881
+331:0:4497
+332:2:3469
+333:2:3470
+334:2:3474
+335:2:3475
+336:2:3483
+337:2:3484
+338:2:3488
+339:2:3489
+340:2:3497
+341:2:3502
+342:2:3506
+343:2:3507
+344:2:3515
+345:2:3516
+346:2:3520
+347:2:3521
+348:2:3515
+349:2:3516
+350:2:3520
+351:2:3521
+352:2:3529
+353:2:3534
+354:2:3535
+355:2:3546
+356:2:3547
+357:2:3548
+358:2:3559
+359:2:3564
+360:2:3565
+361:2:3576
+362:2:3577
+363:2:3578
+364:2:3576
+365:2:3577
+366:2:3578
+367:2:3589
+368:0:4497
+369:2:2881
+370:0:4497
+371:2:3598
+372:2:3599
+373:2:3603
+374:2:3604
+375:2:3612
+376:2:3613
+377:2:3617
+378:2:3618
+379:2:3626
+380:2:3631
+381:2:3635
+382:2:3636
+383:2:3644
+384:2:3645
+385:2:3649
+386:2:3650
+387:2:3644
+388:2:3645
+389:2:3649
+390:2:3650
+391:2:3658
+392:2:3663
+393:2:3664
+394:2:3675
+395:2:3676
+396:2:3677
+397:2:3688
+398:2:3693
+399:2:3694
+400:2:3705
+401:2:3706
+402:2:3707
+403:2:3705
+404:2:3706
+405:2:3707
+406:2:3718
+407:2:3725
+408:0:4497
+409:2:2881
+410:0:4497
+411:2:3729
+412:2:3730
+413:2:3731
+414:2:3743
+415:2:3744
+416:2:3748
+417:2:3749
+418:2:3757
+419:2:3762
+420:2:3766
+421:2:3767
+422:2:3775
+423:2:3776
+424:2:3780
+425:2:3781
+426:2:3775
+427:2:3776
+428:2:3780
+429:2:3781
+430:2:3789
+431:2:3794
+432:2:3795
+433:2:3806
+434:2:3807
+435:2:3808
+436:2:3819
+437:2:3824
+438:2:3825
+439:2:3836
+440:2:3837
+441:2:3838
+442:2:3836
+443:2:3837
+444:2:3838
+445:2:3849
+446:2:3859
+447:2:3860
+448:0:4497
+449:2:2881
+450:0:4497
+451:2:3991
+452:0:4497
+453:2:4220
+454:2:4221
+455:2:4225
+456:2:4229
+457:2:4230
+458:2:4234
+459:2:4242
+460:2:4243
+461:2:4247
+462:2:4251
+463:2:4252
+464:2:4247
+465:2:4251
+466:2:4252
+467:2:4256
+468:2:4263
+469:2:4270
+470:2:4271
+471:2:4278
+472:2:4283
+473:2:4290
+474:2:4291
+475:2:4290
+476:2:4291
+477:2:4298
+478:2:4302
+479:0:4497
+480:2:4307
+481:0:4497
+482:2:4308
+483:0:4497
+484:2:4309
+485:0:4497
+486:2:4310
+487:0:4497
+488:1:26
+489:0:4497
+490:2:4311
+491:0:4497
+492:1:30
+493:1:31
+494:1:35
+495:1:39
+496:1:40
+497:1:44
+498:1:52
+499:1:53
+500:1:57
+501:1:61
+502:1:62
+503:1:57
+504:1:61
+505:1:62
+506:1:66
+507:1:73
+508:1:80
+509:1:81
+510:1:88
+511:1:93
+512:1:100
+513:1:101
+514:1:100
+515:1:101
+516:1:108
+517:1:112
+518:0:4497
+519:2:4310
+520:0:4497
+521:1:117
+522:0:4497
+523:2:4311
+524:0:4497
+525:2:4312
+526:0:4497
+527:2:4317
+528:0:4497
+529:2:4318
+530:0:4497
+531:2:4326
+532:2:4327
+533:2:4331
+534:2:4335
+535:2:4336
+536:2:4340
+537:2:4348
+538:2:4349
+539:2:4353
+540:2:4357
+541:2:4358
+542:2:4353
+543:2:4357
+544:2:4358
+545:2:4362
+546:2:4369
+547:2:4376
+548:2:4377
+549:2:4384
+550:2:4389
+551:2:4396
+552:2:4397
+553:2:4396
+554:2:4397
+555:2:4404
+556:2:4408
+557:0:4497
+558:2:3993
+559:2:4003
+560:0:4497
+561:2:2881
+562:0:4497
+563:2:3994
+564:2:3995
+565:0:4497
+566:2:2881
+567:0:4497
+568:2:3999
+569:0:4497
+570:2:4007
+571:0:4497
+572:2:2878
+573:0:4497
+574:2:2879
+575:0:4497
+576:2:2880
+577:0:4497
+578:2:2881
+579:0:4497
+580:2:2882
+581:2:2883
+582:2:2887
+583:2:2888
+584:2:2896
+585:2:2897
+586:2:2901
+587:2:2902
+588:2:2910
+589:2:2915
+590:2:2919
+591:2:2920
+592:2:2928
+593:2:2929
+594:2:2930
+595:2:2928
+596:2:2929
+597:2:2933
+598:2:2934
+599:2:2942
+600:2:2947
+601:2:2948
+602:2:2959
+603:2:2960
+604:2:2961
+605:2:2972
+606:2:2977
+607:2:2978
+608:2:2989
+609:2:2990
+610:2:2991
+611:2:2989
+612:2:2990
+613:2:2991
+614:2:3002
+615:2:3010
+616:0:4497
+617:2:2881
+618:0:4497
+619:2:3014
+620:2:3018
+621:2:3019
+622:2:3023
+623:2:3027
+624:2:3028
+625:2:3032
+626:2:3040
+627:2:3041
+628:2:3045
+629:2:3046
+630:2:3045
+631:2:3049
+632:2:3050
+633:2:3054
+634:0:4497
+635:2:2881
+636:0:4497
+637:2:3062
+638:2:3063
+639:2:3064
+640:0:4497
+641:2:2881
+642:0:4497
+643:2:3069
+644:0:4497
+645:2:4022
+646:2:4023
+647:2:4027
+648:2:4031
+649:2:4032
+650:2:4036
+651:2:4041
+652:2:4049
+653:2:4053
+654:2:4054
+655:2:4049
+656:2:4053
+657:2:4054
+658:2:4058
+659:2:4065
+660:2:4072
+661:2:4073
+662:2:4080
+663:2:4085
+664:2:4092
+665:2:4093
+666:2:4092
+667:2:4093
+668:2:4100
+669:2:4104
+670:0:4497
+671:2:4109
+672:0:4497
+673:2:4110
+674:0:4497
+675:2:4111
+676:0:4497
+677:2:4112
+678:0:4497
+679:1:26
+680:0:4497
+681:2:4113
+682:0:4497
+683:1:30
+684:1:31
+685:1:35
+686:1:39
+687:1:40
+688:1:44
+689:1:52
+690:1:53
+691:1:57
+692:1:61
+693:1:62
+694:1:57
+695:1:61
+696:1:62
+697:1:66
+698:1:73
+699:1:80
+700:1:81
+701:1:88
+702:1:93
+703:1:100
+704:1:101
+705:1:100
+706:1:101
+707:1:108
+708:1:112
+709:0:4497
+710:2:4112
+711:0:4497
+712:1:117
+713:0:4497
+714:2:4113
+715:0:4497
+716:2:4114
+717:0:4497
+718:2:4119
+719:0:4497
+720:2:4120
+721:0:4497
+722:2:4128
+723:2:4129
+724:2:4133
+725:2:4137
+726:2:4138
+727:2:4142
+728:2:4150
+729:2:4151
+730:2:4155
+731:2:4159
+732:2:4160
+733:2:4155
+734:2:4159
+735:2:4160
+736:2:4164
+737:2:4171
+738:2:4178
+739:2:4179
+740:2:4186
+741:2:4191
+742:2:4198
+743:2:4199
+744:2:4198
+745:2:4199
+746:2:4206
+747:2:4210
+748:0:4497
+749:2:3071
+750:2:4003
+751:0:4497
+752:2:2881
+753:0:4497
+754:2:3072
+755:0:4497
+756:2:2881
+757:0:4497
+758:2:3075
+759:2:3076
+760:2:3080
+761:2:3081
+762:2:3089
+763:2:3090
+764:2:3094
+765:2:3095
+766:2:3103
+767:2:3108
+768:2:3112
+769:2:3113
+770:2:3121
+771:2:3122
+772:2:3126
+773:2:3127
+774:2:3121
+775:2:3122
+776:2:3126
+777:2:3127
+778:2:3135
+779:2:3140
+780:2:3141
+781:2:3152
+782:2:3153
+783:2:3154
+784:2:3165
+785:2:3170
+786:2:3171
+787:2:3182
+788:2:3183
+789:2:3184
+790:2:3182
+791:2:3183
+792:2:3184
+793:2:3195
+794:2:3202
+795:0:4497
+796:2:2881
+797:0:4497
+798:2:3206
+799:2:3207
+800:2:3208
+801:2:3220
+802:2:3221
+803:2:3225
+804:2:3226
+805:2:3234
+806:2:3239
+807:2:3243
+808:2:3244
+809:2:3252
+810:2:3253
+811:2:3257
+812:2:3258
+813:2:3252
+814:2:3253
+815:2:3257
+816:2:3258
+817:2:3266
+818:2:3271
+819:2:3272
+820:2:3283
+821:2:3284
+822:2:3285
+823:2:3296
+824:2:3301
+825:2:3302
+826:2:3313
+827:2:3314
+828:2:3315
+829:2:3313
+830:2:3314
+831:2:3315
+832:2:3326
+833:2:3337
+834:2:3338
+835:0:4497
+836:2:2881
+837:0:4497
+838:2:3469
+839:2:3470
+840:2:3474
+841:2:3475
+842:2:3483
+843:2:3484
+844:2:3488
+845:2:3489
+846:2:3497
+847:2:3502
+848:2:3506
+849:2:3507
+850:2:3515
+851:2:3516
+852:2:3520
+853:2:3521
+854:2:3515
+855:2:3516
+856:2:3520
+857:2:3521
+858:2:3529
+859:2:3534
+860:2:3535
+861:2:3546
+862:2:3547
+863:2:3548
+864:2:3559
+865:2:3564
+866:2:3565
+867:2:3576
+868:2:3577
+869:2:3578
+870:2:3576
+871:2:3577
+872:2:3578
+873:2:3589
+874:0:4497
+875:2:2881
+876:0:4497
+877:2:3598
+878:2:3599
+879:2:3603
+880:2:3604
+881:2:3612
+882:2:3613
+883:2:3617
+884:2:3618
+885:2:3626
+886:2:3631
+887:2:3635
+888:2:3636
+889:2:3644
+890:2:3645
+891:2:3649
+892:2:3650
+893:2:3644
+894:2:3645
+895:2:3649
+896:2:3650
+897:2:3658
+898:2:3663
+899:2:3664
+900:2:3675
+901:2:3676
+902:2:3677
+903:2:3688
+904:2:3693
+905:2:3694
+906:2:3705
+907:2:3706
+908:2:3707
+909:2:3705
+910:2:3706
+911:2:3707
+912:2:3718
+913:2:3725
+914:0:4497
+915:2:2881
+916:0:4497
+917:2:3729
+918:2:3730
+919:2:3731
+920:2:3743
+921:2:3744
+922:2:3748
+923:2:3749
+924:2:3757
+925:2:3762
+926:2:3766
+927:2:3767
+928:2:3775
+929:2:3776
+930:2:3780
+931:2:3781
+932:2:3775
+933:2:3776
+934:2:3780
+935:2:3781
+936:2:3789
+937:2:3794
+938:2:3795
+939:2:3806
+940:2:3807
+941:2:3808
+942:2:3819
+943:2:3824
+944:2:3825
+945:2:3836
+946:2:3837
+947:2:3838
+948:2:3836
+949:2:3837
+950:2:3838
+951:2:3849
+952:2:3859
+953:2:3860
+954:0:4497
+955:2:2881
+956:0:4497
+957:2:3991
+958:0:4497
+959:2:4220
+960:2:4221
+961:2:4225
+962:2:4229
+963:2:4230
+964:2:4234
+965:2:4242
+966:2:4243
+967:2:4247
+968:2:4251
+969:2:4252
+970:2:4247
+971:2:4251
+972:2:4252
+973:2:4256
+974:2:4263
+975:2:4270
+976:2:4271
+977:2:4278
+978:2:4283
+979:2:4290
+980:2:4291
+981:2:4290
+982:2:4291
+983:2:4298
+984:2:4302
+985:0:4497
+986:2:4307
+987:0:4497
+988:2:4308
+989:0:4497
+990:2:4309
+991:0:4497
+992:2:4310
+993:0:4497
+994:1:26
+995:0:4497
+996:2:4311
+997:0:4497
+998:1:30
+999:1:31
+1000:1:35
+1001:1:39
+1002:1:40
+1003:1:44
+1004:1:52
+1005:1:53
+1006:1:57
+1007:1:61
+1008:1:62
+1009:1:57
+1010:1:61
+1011:1:62
+1012:1:66
+1013:1:73
+1014:1:80
+1015:1:81
+1016:1:88
+1017:1:93
+1018:1:100
+1019:1:101
+1020:1:100
+1021:1:101
+1022:1:108
+1023:1:112
+1024:0:4497
+1025:2:4310
+1026:0:4497
+1027:1:117
+1028:0:4497
+1029:2:4311
+1030:0:4497
+1031:2:4312
+1032:0:4497
+1033:2:4317
+1034:0:4497
+1035:2:4318
+1036:0:4497
+1037:2:4326
+1038:2:4327
+1039:2:4331
+1040:2:4335
+1041:2:4336
+1042:2:4340
+1043:2:4348
+1044:2:4349
+1045:2:4353
+1046:2:4357
+1047:2:4358
+1048:2:4353
+1049:2:4357
+1050:2:4358
+1051:2:4362
+1052:2:4369
+1053:2:4376
+1054:2:4377
+1055:2:4384
+1056:2:4389
+1057:2:4396
+1058:2:4397
+1059:2:4396
+1060:2:4397
+1061:2:4404
+1062:2:4408
+1063:0:4497
+1064:2:3993
+1065:2:4003
+1066:0:4497
+1067:2:2881
+1068:0:4497
+1069:2:3994
+1070:2:3995
+1071:0:4497
+1072:2:2881
+1073:0:4497
+1074:2:3999
+1075:0:4497
+1076:2:4007
+1077:0:4497
+1078:2:2878
+1079:0:4497
+1080:2:2879
+1081:0:4497
+1082:2:2880
+1083:0:4497
+1084:2:2881
+1085:0:4497
+1086:2:2882
+1087:2:2883
+1088:2:2887
+1089:2:2888
+1090:2:2896
+1091:2:2897
+1092:2:2901
+1093:2:2902
+1094:2:2910
+1095:2:2915
+1096:2:2919
+1097:2:2920
+1098:2:2928
+1099:2:2929
+1100:2:2933
+1101:2:2934
+1102:2:2928
+1103:2:2929
+1104:2:2930
+1105:2:2942
+1106:2:2947
+1107:2:2948
+1108:2:2959
+1109:2:2960
+1110:2:2961
+1111:2:2972
+1112:2:2977
+1113:2:2978
+1114:2:2989
+1115:2:2990
+1116:2:2991
+1117:2:2989
+1118:2:2990
+1119:2:2991
+1120:2:3002
+1121:2:3010
+1122:0:4497
+1123:2:2881
+1124:0:4497
+1125:2:3014
+1126:2:3018
+1127:2:3019
+1128:2:3023
+1129:2:3027
+1130:2:3028
+1131:2:3032
+1132:2:3040
+1133:2:3041
+1134:2:3045
+1135:2:3049
+1136:2:3050
+1137:2:3045
+1138:2:3046
+1139:2:3054
+1140:0:4497
+1141:2:2881
+1142:0:4497
+1143:2:3062
+1144:2:3063
+1145:2:3064
+1146:0:4497
+1147:2:2881
+1148:0:4497
+1149:2:3069
+1150:0:4497
+1151:2:4022
+1152:2:4023
+1153:2:4027
+1154:2:4031
+1155:2:4032
+1156:2:4036
+1157:2:4041
+1158:2:4049
+1159:2:4053
+1160:2:4054
+1161:2:4049
+1162:2:4053
+1163:2:4054
+1164:2:4058
+1165:2:4065
+1166:2:4072
+1167:2:4073
+1168:2:4080
+1169:2:4085
+1170:2:4092
+1171:2:4093
+1172:2:4092
+1173:2:4093
+1174:2:4100
+1175:2:4104
+1176:0:4497
+1177:2:4109
+1178:0:4497
+1179:2:4110
+1180:0:4497
+1181:2:4111
+1182:0:4497
+1183:2:4112
+1184:0:4497
+1185:1:26
+1186:0:4497
+1187:2:4113
+1188:0:4497
+1189:1:30
+1190:1:31
+1191:1:35
+1192:1:39
+1193:1:40
+1194:1:44
+1195:1:52
+1196:1:53
+1197:1:57
+1198:1:61
+1199:1:62
+1200:1:57
+1201:1:61
+1202:1:62
+1203:1:66
+1204:1:73
+1205:1:80
+1206:1:81
+1207:1:88
+1208:1:93
+1209:1:100
+1210:1:101
+1211:1:100
+1212:1:101
+1213:1:108
+1214:1:112
+1215:0:4497
+1216:2:4112
+1217:0:4497
+1218:1:117
+1219:0:4497
+1220:2:4113
+1221:0:4497
+1222:2:4114
+1223:0:4497
+1224:2:4119
+1225:0:4497
+1226:2:4120
+1227:0:4497
+1228:2:4128
+1229:2:4129
+1230:2:4133
+1231:2:4137
+1232:2:4138
+1233:2:4142
+1234:2:4150
+1235:2:4151
+1236:2:4155
+1237:2:4159
+1238:2:4160
+1239:2:4155
+1240:2:4159
+1241:2:4160
+1242:2:4164
+1243:2:4171
+1244:2:4178
+1245:2:4179
+1246:2:4186
+1247:2:4191
+1248:2:4198
+1249:2:4199
+1250:2:4198
+1251:2:4199
+1252:2:4206
+1253:2:4210
+1254:0:4497
+1255:2:3071
+1256:2:4003
+1257:0:4497
+1258:2:2881
+1259:0:4497
+1260:2:3072
+1261:0:4497
+1262:2:2881
+1263:0:4497
+1264:2:3075
+1265:2:3076
+1266:2:3080
+1267:2:3081
+1268:2:3089
+1269:2:3090
+1270:2:3094
+1271:2:3095
+1272:2:3103
+1273:2:3108
+1274:2:3112
+1275:2:3113
+1276:2:3121
+1277:2:3122
+1278:2:3126
+1279:2:3127
+1280:2:3121
+1281:2:3122
+1282:2:3126
+1283:2:3127
+1284:2:3135
+1285:2:3140
+1286:2:3141
+1287:2:3152
+1288:2:3153
+1289:2:3154
+1290:2:3165
+1291:2:3170
+1292:2:3171
+1293:2:3182
+1294:2:3183
+1295:2:3184
+1296:2:3182
+1297:2:3183
+1298:2:3184
+1299:2:3195
+1300:2:3202
+1301:0:4497
+1302:2:2881
+1303:0:4497
+1304:2:3206
+1305:2:3207
+1306:2:3208
+1307:2:3220
+1308:2:3221
+1309:2:3225
+1310:2:3226
+1311:2:3234
+1312:2:3239
+1313:2:3243
+1314:2:3244
+1315:2:3252
+1316:2:3253
+1317:2:3257
+1318:2:3258
+1319:2:3252
+1320:2:3253
+1321:2:3257
+1322:2:3258
+1323:2:3266
+1324:2:3271
+1325:2:3272
+1326:2:3283
+1327:2:3284
+1328:2:3285
+1329:2:3296
+1330:2:3301
+1331:2:3302
+1332:2:3313
+1333:2:3314
+1334:2:3315
+1335:2:3313
+1336:2:3314
+1337:2:3315
+1338:2:3326
+1339:2:3337
+1340:2:3338
+1341:0:4497
+1342:2:2881
+1343:0:4497
+1344:2:3469
+1345:2:3470
+1346:2:3474
+1347:2:3475
+1348:2:3483
+1349:2:3484
+1350:2:3488
+1351:2:3489
+1352:2:3497
+1353:2:3502
+1354:2:3506
+1355:2:3507
+1356:2:3515
+1357:2:3516
+1358:2:3520
+1359:2:3521
+1360:2:3515
+1361:2:3516
+1362:2:3520
+1363:2:3521
+1364:2:3529
+1365:2:3534
+1366:2:3535
+1367:2:3546
+1368:2:3547
+1369:2:3548
+1370:2:3559
+1371:2:3564
+1372:2:3565
+1373:2:3576
+1374:2:3577
+1375:2:3578
+1376:2:3576
+1377:2:3577
+1378:2:3578
+1379:2:3589
+1380:0:4497
+1381:2:2881
+1382:0:4497
+1383:2:3598
+1384:2:3599
+1385:2:3603
+1386:2:3604
+1387:2:3612
+1388:2:3613
+1389:2:3617
+1390:2:3618
+1391:2:3626
+1392:2:3631
+1393:2:3635
+1394:2:3636
+1395:2:3644
+1396:2:3645
+1397:2:3649
+1398:2:3650
+1399:2:3644
+1400:2:3645
+1401:2:3649
+1402:2:3650
+1403:2:3658
+1404:2:3663
+1405:2:3664
+1406:2:3675
+1407:2:3676
+1408:2:3677
+1409:2:3688
+1410:2:3693
+1411:2:3694
+1412:2:3705
+1413:2:3706
+1414:2:3707
+1415:2:3705
+1416:2:3706
+1417:2:3707
+1418:2:3718
+1419:2:3725
+1420:0:4497
+1421:2:2881
+1422:0:4497
+1423:1:118
+1424:0:4497
+1425:1:120
+1426:0:4497
+1427:1:19
+1428:0:4497
+1429:1:126
+1430:1:127
+1431:1:131
+1432:1:132
+1433:1:140
+1434:1:141
+1435:1:145
+1436:1:146
+1437:1:154
+1438:1:159
+1439:1:163
+1440:1:164
+1441:1:172
+1442:1:173
+1443:1:177
+1444:1:178
+1445:1:172
+1446:1:173
+1447:1:177
+1448:1:178
+1449:1:186
+1450:1:191
+1451:1:192
+1452:1:203
+1453:1:204
+1454:1:205
+1455:1:216
+1456:1:221
+1457:1:222
+1458:1:233
+1459:1:234
+1460:1:235
+1461:1:233
+1462:1:234
+1463:1:235
+1464:1:246
+1465:0:4497
+1466:1:15
+1467:0:4497
+1468:1:16
+1469:0:4497
+1470:1:17
+1471:0:4497
+1472:1:118
+1473:0:4497
+1474:1:120
+1475:0:4497
+1476:1:19
+1477:0:4497
+1478:1:255
+1479:1:256
+1480:0:4497
+1481:1:15
+1482:0:4497
+1483:1:16
+1484:0:4497
+1485:1:17
+1486:0:4497
+1487:1:118
+1488:0:4497
+1489:1:120
+1490:0:4497
+1491:1:19
+1492:0:4497
+1493:1:262
+1494:1:263
+1495:1:267
+1496:1:268
+1497:1:276
+1498:1:277
+1499:1:281
+1500:1:282
+1501:1:290
+1502:1:295
+1503:1:299
+1504:1:300
+1505:1:308
+1506:1:309
+1507:1:313
+1508:1:314
+1509:1:308
+1510:1:309
+1511:1:313
+1512:1:314
+1513:1:322
+1514:1:327
+1515:1:328
+1516:1:339
+1517:1:340
+1518:1:341
+1519:1:352
+1520:1:357
+1521:1:358
+1522:1:369
+1523:1:370
+1524:1:371
+1525:1:369
+1526:1:370
+1527:1:371
+1528:1:382
+1529:0:4497
+1530:1:15
+1531:0:4497
+1532:1:16
+1533:0:4497
+1534:1:17
+1535:0:4497
+1536:1:118
+1537:0:4497
+1538:1:120
+1539:0:4497
+1540:1:19
+1541:0:4497
+1542:1:391
+1543:1:392
+1544:1:396
+1545:1:397
+1546:1:405
+1547:1:406
+1548:1:410
+1549:1:411
+1550:1:419
+1551:1:424
+1552:1:428
+1553:1:429
+1554:1:437
+1555:1:438
+1556:1:442
+1557:1:443
+1558:1:437
+1559:1:438
+1560:1:442
+1561:1:443
+1562:1:451
+1563:1:456
+1564:1:457
+1565:1:468
+1566:1:469
+1567:1:470
+1568:1:481
+1569:1:486
+1570:1:487
+1571:1:498
+1572:1:499
+1573:1:500
+1574:1:498
+1575:1:499
+1576:1:500
+1577:1:511
+1578:1:518
+1579:0:4497
+1580:1:15
+1581:0:4497
+1582:1:16
+1583:0:4497
+1584:1:17
+1585:0:4497
+1586:1:118
+1587:0:4497
+1588:1:120
+1589:0:4495
+1590:1:19
+1591:0:4501
+1592:1:1184
+1593:1:1185
+1594:1:1189
+1595:1:1190
+1596:1:1198
+1597:1:1199
+1598:1:1200
+1599:1:1212
+1600:1:1217
+1601:1:1221
+1602:1:1222
+1603:1:1230
+1604:1:1231
+1605:1:1235
+1606:1:1236
+1607:1:1230
+1608:1:1231
+1609:1:1235
+1610:1:1236
+1611:1:1244
+1612:1:1249
+1613:1:1250
+1614:1:1261
+1615:1:1262
+1616:1:1263
+1617:1:1274
+1618:1:1279
+1619:1:1280
+1620:1:1291
+1621:1:1292
+1622:1:1293
+1623:1:1291
+1624:1:1292
+1625:1:1293
+1626:1:1304
+1627:0:4501
+1628:1:15
+1629:0:4501
+1630:1:16
+1631:0:4501
+1632:2:3729
+1633:2:3730
+1634:2:3731
+1635:2:3743
+1636:2:3744
+1637:2:3748
+1638:2:3749
+1639:2:3757
+1640:2:3762
+1641:2:3766
+1642:2:3767
+1643:2:3775
+1644:2:3776
+1645:2:3780
+1646:2:3781
+1647:2:3775
+1648:2:3776
+1649:2:3780
+1650:2:3781
+1651:2:3789
+1652:2:3794
+1653:2:3795
+1654:2:3806
+1655:2:3807
+1656:2:3808
+1657:2:3819
+1658:2:3824
+1659:2:3825
+1660:2:3836
+1661:2:3837
+1662:2:3838
+1663:2:3836
+1664:2:3837
+1665:2:3838
+1666:2:3849
+1667:2:3857
+1668:0:4501
+1669:2:2881
+-1:-1:-1
+1670:0:4501
+1671:2:3863
+1672:2:3864
+1673:2:3868
+1674:2:3869
+1675:2:3877
+1676:2:3878
+1677:2:3882
+1678:2:3883
+1679:2:3891
+1680:2:3896
+1681:2:3900
+1682:2:3901
+1683:2:3909
+1684:2:3910
+1685:2:3914
+1686:2:3915
+1687:2:3909
+1688:2:3910
+1689:2:3914
+1690:2:3915
+1691:2:3923
+1692:2:3928
+1693:2:3929
+1694:2:3940
+1695:2:3941
+1696:2:3942
+1697:2:3953
+1698:2:3958
+1699:2:3959
+1700:2:3970
+1701:2:3971
+1702:2:3972
+1703:2:3970
+1704:2:3971
+1705:2:3972
+1706:2:3983
+1707:0:4501
+1708:2:2881
+1709:0:4501
+1710:2:3729
+1711:2:3730
+1712:2:3734
+1713:2:3735
+1714:2:3743
+1715:2:3744
+1716:2:3748
+1717:2:3749
+1718:2:3757
+1719:2:3762
+1720:2:3766
+1721:2:3767
+1722:2:3775
+1723:2:3776
+1724:2:3780
+1725:2:3781
+1726:2:3775
+1727:2:3776
+1728:2:3780
+1729:2:3781
+1730:2:3789
+1731:2:3794
+1732:2:3795
+1733:2:3806
+1734:2:3807
+1735:2:3808
+1736:2:3819
+1737:2:3824
+1738:2:3825
+1739:2:3836
+1740:2:3837
+1741:2:3838
+1742:2:3836
+1743:2:3837
+1744:2:3838
+1745:2:3849
+1746:2:3857
+1747:0:4501
+1748:2:2881
+1749:0:4501
+1750:2:3863
+1751:2:3864
+1752:2:3868
+1753:2:3869
+1754:2:3877
+1755:2:3878
+1756:2:3882
+1757:2:3883
+1758:2:3891
+1759:2:3896
+1760:2:3900
+1761:2:3901
+1762:2:3909
+1763:2:3910
+1764:2:3914
+1765:2:3915
+1766:2:3909
+1767:2:3910
+1768:2:3914
+1769:2:3915
+1770:2:3923
+1771:2:3928
+1772:2:3929
+1773:2:3940
+1774:2:3941
+1775:2:3942
+1776:2:3953
+1777:2:3958
+1778:2:3959
+1779:2:3970
+1780:2:3971
+1781:2:3972
+1782:2:3970
+1783:2:3971
+1784:2:3972
+1785:2:3983
+1786:0:4501
+1787:2:2881
+1788:0:4501
+1789:2:3729
+1790:2:3730
+1791:2:3734
+1792:2:3735
+1793:2:3743
+1794:2:3744
+1795:2:3748
+1796:2:3749
+1797:2:3757
+1798:2:3762
+1799:2:3766
+1800:2:3767
+1801:2:3775
+1802:2:3776
+1803:2:3780
+1804:2:3781
+1805:2:3775
+1806:2:3776
+1807:2:3780
+1808:2:3781
+1809:2:3789
+1810:2:3794
+1811:2:3795
+1812:2:3806
+1813:2:3807
+1814:2:3808
+1815:2:3819
+1816:2:3824
+1817:2:3825
+1818:2:3836
+1819:2:3837
+1820:2:3838
+1821:2:3836
+1822:2:3837
+1823:2:3838
+1824:2:3849
+1825:2:3857
+1826:0:4501
+1827:2:2881
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/.input.spin b/formal-model/results/urcu-controldataflow-no-ipi/.input.spin
new file mode 100644 (file)
index 0000000..542625d
--- /dev/null
@@ -0,0 +1,1239 @@
+
+// Poison value for freed memory
+#define POISON 1
+// Memory with correct data
+#define WINE 0
+#define SLAB_SIZE 2
+
+#define read_poison    (data_read_first[0] == POISON || data_read_second[0] == POISON)
+
+#define RCU_GP_CTR_BIT (1 << 7)
+#define RCU_GP_CTR_NEST_MASK (RCU_GP_CTR_BIT - 1)
+
+//disabled
+//#define REMOTE_BARRIERS
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+typedef per_proc_bit {
+       bit val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bitfield {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bitfield cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               /*
+                * 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, j);
+               reader_barrier[get_readerid()] = 0;
+       :: 1 ->
+               /*
+                * 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)
+//#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);                                                           \
+       i = 0;                                                                  \
+       do                                                                      \
+       :: i < NR_READERS ->                                                    \
+               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.                                            \
+                */                                                             \
+               do                                                              \
+               :: (reader_barrier[i] == 1) ->                                  \
+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(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, smp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only one reader */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* RCU data */
+DECLARE_CACHED_VAR(bit, rcu_data[SLAB_SIZE]);
+
+/* RCU pointer */
+#if (SLAB_SIZE == 2)
+DECLARE_CACHED_VAR(bit, rcu_ptr);
+bit ptr_read_first[NR_READERS];
+bit ptr_read_second[NR_READERS];
+#else
+DECLARE_CACHED_VAR(byte, rcu_ptr);
+byte ptr_read_first[NR_READERS];
+byte ptr_read_second[NR_READERS];
+#endif
+
+bit data_read_first[NR_READERS];
+bit data_read_second[NR_READERS];
+
+bit init_done = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               ptr_read_first[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb1;
+rmb1_end:
+                               data_read_first[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_first[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               ptr_read_second[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb2;
+rmb2_end:
+                               data_read_second[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_second[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+rmb1:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb1_end;
+rmb2:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_DATA                     (1 << 1)
+#define WRITE_PROC_WMB                 (1 << 2)
+#define WRITE_XCHG_PTR                 (1 << 3)
+
+#define WRITE_PROC_FIRST_MB            (1 << 4)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 5)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 6)
+#define WRITE_PROC_FIRST_WAIT          (1 << 7)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 8)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 9)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 10)
+#define WRITE_PROC_SECOND_WAIT         (1 << 11)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 12)
+
+#define WRITE_PROC_SECOND_MB           (1 << 13)
+
+#define WRITE_FREE                     (1 << 14)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_DATA                    \
+                                       | WRITE_PROC_WMB                \
+                                       | WRITE_XCHG_PTR                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB          \
+                                       | WRITE_FREE)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 15) - 1)
+
+/*
+ * Mutexes are implied around writer execution. A single writer at a time.
+ */
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte cur_data = 0, old_data, loop_nr = 0;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (loop_nr < 3) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               loop_nr = loop_nr + 1;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_WMB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+#endif
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_DATA) ->
+                       ooo_mem(i);
+                       cur_data = (cur_data + 1) % SLAB_SIZE;
+                       WRITE_CACHED_VAR(rcu_data[cur_data], WINE);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_DATA);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA,
+                                 WRITE_PROC_WMB) ->
+                       smp_wmb(i, j);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_WMB,
+                                 WRITE_XCHG_PTR) ->
+                       /* rcu_xchg_pointer() */
+                       atomic {
+                               old_data = READ_CACHED_VAR(rcu_ptr);
+                               WRITE_CACHED_VAR(rcu_ptr, cur_data);
+                       }
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_XCHG_PTR);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_WMB      /* No dependency on
+                                                        * WRITE_DATA because we
+                                                        * write to a
+                                                        * different location. */
+                                 | WRITE_PROC_SECOND_MB
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_FREE) ->
+                       WRITE_CACHED_VAR(rcu_data[old_data], POISON);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_FREE);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+               /*
+                * Note : Promela model adds implicit serialization of the
+                * WRITE_FREE instruction. Normally, it would be permitted to
+                * spill on the next loop execution. Given the validation we do
+                * checks for the data entry read to be poisoned, it's ok if
+                * we do not check "late arriving" memory poisoning.
+                */
+       :: 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
+#ifdef READER_PROGRESS
+               /*
+                * Make sure we don't block the reader's progress.
+                */
+               smp_mb_send(i, j, 5);
+#endif
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(rcu_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       ptr_read_first[i] = 1;
+                       ptr_read_second[i] = 1;
+                       data_read_first[i] = WINE;
+                       data_read_second[i] = WINE;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               INIT_CACHED_VAR(rcu_data[0], WINE, j);
+               i = 1;
+               do
+               :: i < SLAB_SIZE ->
+                       INIT_CACHED_VAR(rcu_data[i], POISON, j);
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/DEFINES b/formal-model/results/urcu-controldataflow-no-ipi/DEFINES
new file mode 100644 (file)
index 0000000..929f5a1
--- /dev/null
@@ -0,0 +1,14 @@
+
+// Poison value for freed memory
+#define POISON 1
+// Memory with correct data
+#define WINE 0
+#define SLAB_SIZE 2
+
+#define read_poison    (data_read_first[0] == POISON || data_read_second[0] == POISON)
+
+#define RCU_GP_CTR_BIT (1 << 7)
+#define RCU_GP_CTR_NEST_MASK (RCU_GP_CTR_BIT - 1)
+
+//disabled
+//#define REMOTE_BARRIERS
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/Makefile b/formal-model/results/urcu-controldataflow-no-ipi/Makefile
new file mode 100644 (file)
index 0000000..de47dff
--- /dev/null
@@ -0,0 +1,170 @@
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Copyright (C) Mathieu Desnoyers, 2009
+#
+# Authors: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+
+#CFLAGS=-DSAFETY
+#for multi-core verif, 15.5GB shared mem, use files if full
+#CFLAGS=-DHASH64 -DMEMLIM=15500 -DNCORE=2
+#CFLAGS=-DHASH64 -DCOLLAPSE -DMA=88 -DMEMLIM=15500 -DNCORE=8
+
+#liveness
+#CFLAGS=-DHASH64 -DCOLLAPSE -DMA=88
+CFLAGS=-DHASH64
+
+SPINFILE=urcu.spin
+
+default:
+       make urcu_free | tee urcu_free.log
+       make urcu_free_no_mb | tee urcu_free_no_mb.log
+       make urcu_free_no_rmb | tee urcu_free_no_rmb.log
+       make urcu_free_no_wmb | tee urcu_free_no_wmb.log
+       make urcu_free_single_flip | tee urcu_free_single_flip.log
+       make urcu_progress_writer | tee urcu_progress_writer.log
+       make urcu_progress_reader | tee urcu_progress_reader.log
+       make urcu_progress_writer_error | tee urcu_progress_writer_error.log
+       make asserts | tee asserts.log
+       make summary
+
+#show trail : spin -v -t -N pan.ltl input.spin
+# after each individual make.
+
+summary:
+       @echo
+       @echo "Verification summary"
+       @grep errors: *.log
+
+asserts: clean
+       cat DEFINES > .input.spin
+       cat ${SPINFILE} >> .input.spin
+       rm -f .input.spin.trail
+       spin -a -X .input.spin
+       gcc -O2 -w ${CFLAGS} -DSAFETY -o pan pan.c
+       ./pan -v -c1 -X -m10000000 -w20
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_free: clean urcu_free_ltl run
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_free_nested: clean urcu_free_ltl urcu_free_nested_define run
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_free_nested_define:
+       cp urcu_free_nested.define .input.define
+
+urcu_free_no_rmb: clean urcu_free_ltl urcu_free_no_rmb_define run
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_free_no_rmb_define:
+       cp urcu_free_no_rmb.define .input.define
+
+urcu_free_no_wmb: clean urcu_free_ltl urcu_free_no_wmb_define run
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_free_no_wmb_define:
+       cp urcu_free_no_wmb.define .input.define
+
+urcu_free_no_mb: clean urcu_free_ltl urcu_free_no_mb_define run
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_free_no_mb_define:
+       cp urcu_free_no_mb.define .input.define
+
+urcu_free_single_flip: clean urcu_free_ltl urcu_free_single_flip_define run
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_free_single_flip_define:
+       cp urcu_free_single_flip.define .input.define
+
+urcu_free_ltl:
+       touch .input.define
+       cat .input.define >> pan.ltl
+       cat DEFINES >> pan.ltl
+       spin -f "!(`cat urcu_free.ltl | grep -v ^//`)" >> pan.ltl
+
+# Progress checks
+
+urcu_progress_writer: clean urcu_progress_writer_ltl \
+               urcu_progress_writer_define run_weak_fair
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_progress_writer_define:
+       cp urcu_progress_writer.define .input.define
+
+urcu_progress_writer_ltl:
+       touch .input.define
+       cat .input.define > pan.ltl
+       cat DEFINES >> pan.ltl
+       spin -f "!(`cat urcu_progress.ltl | grep -v ^//`)" >> pan.ltl
+
+urcu_progress_reader: clean urcu_progress_reader_ltl \
+               urcu_progress_reader_define run_weak_fair
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_progress_reader_define:
+       cp urcu_progress_reader.define .input.define
+
+urcu_progress_reader_ltl:
+       touch .input.define
+       cat .input.define > pan.ltl
+       cat DEFINES >> pan.ltl
+       spin -f "!(`cat urcu_progress.ltl | grep -v ^//`)" >> pan.ltl
+
+urcu_progress_writer_error: clean urcu_progress_writer_error_ltl \
+               urcu_progress_writer_error_define run_weak_fair
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_progress_writer_error_define:
+       cp urcu_progress_writer_error.define .input.define
+
+urcu_progress_writer_error_ltl:
+       touch .input.define
+       cat .input.define > pan.ltl
+       cat DEFINES >> pan.ltl
+       spin -f "!(`cat urcu_progress.ltl | grep -v ^//`)" >> pan.ltl
+
+
+run_weak_fair: pan
+       ./pan -a -f -v -c1 -X -m10000000 -w20
+
+run: pan
+       ./pan -a -v -c1 -X -m10000000 -w20
+
+pan: pan.c
+       gcc -O2 -w ${CFLAGS} -o pan pan.c
+
+pan.c: pan.ltl ${SPINFILE}
+       cat .input.define > .input.spin
+       cat DEFINES >> .input.spin
+       cat ${SPINFILE} >> .input.spin
+       rm -f .input.spin.trail
+       spin -a -X -N pan.ltl .input.spin
+
+.PHONY: clean default distclean summary
+clean:
+       rm -f pan* trail.out .input.spin* *.spin.trail .input.define
+distclean:
+       rm -f *.trail *.input *.log
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/asserts.log b/formal-model/results/urcu-controldataflow-no-ipi/asserts.log
new file mode 100644 (file)
index 0000000..a732917
--- /dev/null
@@ -0,0 +1,514 @@
+rm -f pan* trail.out .input.spin* *.spin.trail .input.define
+cat DEFINES > .input.spin
+cat urcu.spin >> .input.spin
+rm -f .input.spin.trail
+spin -a -X .input.spin
+Exit-Status 0
+gcc -O2 -w -DHASH64 -DSAFETY -o pan pan.c
+./pan -v -c1 -X -m10000000 -w20
+Depth=    4311 States=    1e+06 Transitions= 4.65e+08 Memory=   542.717        t=    480 R=   2e+03
+
+(Spin Version 5.1.7 -- 23 December 2008)
+       + Partial Order Reduction
+
+Full statespace search for:
+       never claim             - (none specified)
+       assertion violations    +
+       cycle checks            - (disabled by -DSAFETY)
+       invalid end states      +
+
+State-vector 72 byte, depth reached 4311, errors: 0
+  1884295 states, stored
+9.0500014e+08 states, matched
+9.0688444e+08 transitions (= stored+matched)
+5.3819272e+09 atomic steps
+hash conflicts: 4.4436974e+08 (resolved)
+
+Stats on memory usage (in Megabytes):
+  179.700      equivalent memory usage for states (stored*(State-vector + overhead))
+  144.496      actual memory usage for states (compression: 80.41%)
+               state-vector as stored = 52 byte + 28 byte overhead
+    8.000      memory used for hash table (-w20)
+  457.764      memory used for DFS stack (-m10000000)
+  610.197      total actual memory usage
+
+unreached in proctype urcu_reader
+       line 394, ".input.spin", state 17, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 49, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 63, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 82, "(1)"
+       line 420, ".input.spin", state 112, "(1)"
+       line 424, ".input.spin", state 125, "(1)"
+       line 575, ".input.spin", state 146, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<1))"
+       line 394, ".input.spin", state 153, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 185, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 199, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 218, "(1)"
+       line 420, ".input.spin", state 248, "(1)"
+       line 424, ".input.spin", state 261, "(1)"
+       line 394, ".input.spin", state 282, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 314, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 328, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 347, "(1)"
+       line 420, ".input.spin", state 377, "(1)"
+       line 424, ".input.spin", state 390, "(1)"
+       line 394, ".input.spin", state 413, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 394, ".input.spin", state 415, "(1)"
+       line 394, ".input.spin", state 416, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 394, ".input.spin", state 416, "else"
+       line 394, ".input.spin", state 419, "(1)"
+       line 398, ".input.spin", state 427, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 398, ".input.spin", state 429, "(1)"
+       line 398, ".input.spin", state 430, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 398, ".input.spin", state 430, "else"
+       line 398, ".input.spin", state 433, "(1)"
+       line 398, ".input.spin", state 434, "(1)"
+       line 398, ".input.spin", state 434, "(1)"
+       line 396, ".input.spin", state 439, "((i<1))"
+       line 396, ".input.spin", state 439, "((i>=1))"
+       line 403, ".input.spin", state 445, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 447, "(1)"
+       line 403, ".input.spin", state 448, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 403, ".input.spin", state 448, "else"
+       line 403, ".input.spin", state 451, "(1)"
+       line 403, ".input.spin", state 452, "(1)"
+       line 403, ".input.spin", state 452, "(1)"
+       line 407, ".input.spin", state 459, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 461, "(1)"
+       line 407, ".input.spin", state 462, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 407, ".input.spin", state 462, "else"
+       line 407, ".input.spin", state 465, "(1)"
+       line 407, ".input.spin", state 466, "(1)"
+       line 407, ".input.spin", state 466, "(1)"
+       line 405, ".input.spin", state 471, "((i<2))"
+       line 405, ".input.spin", state 471, "((i>=2))"
+       line 411, ".input.spin", state 478, "(1)"
+       line 411, ".input.spin", state 479, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 411, ".input.spin", state 479, "else"
+       line 411, ".input.spin", state 482, "(1)"
+       line 411, ".input.spin", state 483, "(1)"
+       line 411, ".input.spin", state 483, "(1)"
+       line 415, ".input.spin", state 491, "(1)"
+       line 415, ".input.spin", state 492, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 415, ".input.spin", state 492, "else"
+       line 415, ".input.spin", state 495, "(1)"
+       line 415, ".input.spin", state 496, "(1)"
+       line 415, ".input.spin", state 496, "(1)"
+       line 413, ".input.spin", state 501, "((i<1))"
+       line 413, ".input.spin", state 501, "((i>=1))"
+       line 420, ".input.spin", state 508, "(1)"
+       line 420, ".input.spin", state 509, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 420, ".input.spin", state 509, "else"
+       line 420, ".input.spin", state 512, "(1)"
+       line 420, ".input.spin", state 513, "(1)"
+       line 420, ".input.spin", state 513, "(1)"
+       line 424, ".input.spin", state 521, "(1)"
+       line 424, ".input.spin", state 522, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 424, ".input.spin", state 522, "else"
+       line 424, ".input.spin", state 525, "(1)"
+       line 424, ".input.spin", state 526, "(1)"
+       line 424, ".input.spin", state 526, "(1)"
+       line 422, ".input.spin", state 531, "((i<2))"
+       line 422, ".input.spin", state 531, "((i>=2))"
+       line 429, ".input.spin", state 535, "(1)"
+       line 429, ".input.spin", state 535, "(1)"
+       line 575, ".input.spin", state 538, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 575, ".input.spin", state 539, "_proc_urcu_reader = (_proc_urcu_reader|(1<<5))"
+       line 575, ".input.spin", state 540, "(1)"
+       line 249, ".input.spin", state 544, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 253, ".input.spin", state 555, "(1)"
+       line 257, ".input.spin", state 566, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, ".input.spin", state 575, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, ".input.spin", state 591, "(1)"
+       line 230, ".input.spin", state 599, "(1)"
+       line 234, ".input.spin", state 611, "(1)"
+       line 238, ".input.spin", state 619, "(1)"
+       line 394, ".input.spin", state 637, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 398, ".input.spin", state 651, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 669, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 683, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 702, "(1)"
+       line 415, ".input.spin", state 715, "(1)"
+       line 420, ".input.spin", state 732, "(1)"
+       line 424, ".input.spin", state 745, "(1)"
+       line 394, ".input.spin", state 773, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 394, ".input.spin", state 775, "(1)"
+       line 394, ".input.spin", state 776, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 394, ".input.spin", state 776, "else"
+       line 394, ".input.spin", state 779, "(1)"
+       line 398, ".input.spin", state 787, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 398, ".input.spin", state 789, "(1)"
+       line 398, ".input.spin", state 790, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 398, ".input.spin", state 790, "else"
+       line 398, ".input.spin", state 793, "(1)"
+       line 398, ".input.spin", state 794, "(1)"
+       line 398, ".input.spin", state 794, "(1)"
+       line 396, ".input.spin", state 799, "((i<1))"
+       line 396, ".input.spin", state 799, "((i>=1))"
+       line 403, ".input.spin", state 805, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 807, "(1)"
+       line 403, ".input.spin", state 808, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 403, ".input.spin", state 808, "else"
+       line 403, ".input.spin", state 811, "(1)"
+       line 403, ".input.spin", state 812, "(1)"
+       line 403, ".input.spin", state 812, "(1)"
+       line 407, ".input.spin", state 819, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 821, "(1)"
+       line 407, ".input.spin", state 822, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 407, ".input.spin", state 822, "else"
+       line 407, ".input.spin", state 825, "(1)"
+       line 407, ".input.spin", state 826, "(1)"
+       line 407, ".input.spin", state 826, "(1)"
+       line 405, ".input.spin", state 831, "((i<2))"
+       line 405, ".input.spin", state 831, "((i>=2))"
+       line 411, ".input.spin", state 838, "(1)"
+       line 411, ".input.spin", state 839, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 411, ".input.spin", state 839, "else"
+       line 411, ".input.spin", state 842, "(1)"
+       line 411, ".input.spin", state 843, "(1)"
+       line 411, ".input.spin", state 843, "(1)"
+       line 415, ".input.spin", state 851, "(1)"
+       line 415, ".input.spin", state 852, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 415, ".input.spin", state 852, "else"
+       line 415, ".input.spin", state 855, "(1)"
+       line 415, ".input.spin", state 856, "(1)"
+       line 415, ".input.spin", state 856, "(1)"
+       line 413, ".input.spin", state 861, "((i<1))"
+       line 413, ".input.spin", state 861, "((i>=1))"
+       line 420, ".input.spin", state 868, "(1)"
+       line 420, ".input.spin", state 869, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 420, ".input.spin", state 869, "else"
+       line 420, ".input.spin", state 872, "(1)"
+       line 420, ".input.spin", state 873, "(1)"
+       line 420, ".input.spin", state 873, "(1)"
+       line 424, ".input.spin", state 881, "(1)"
+       line 424, ".input.spin", state 882, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 424, ".input.spin", state 882, "else"
+       line 424, ".input.spin", state 885, "(1)"
+       line 424, ".input.spin", state 886, "(1)"
+       line 424, ".input.spin", state 886, "(1)"
+       line 429, ".input.spin", state 895, "(1)"
+       line 429, ".input.spin", state 895, "(1)"
+       line 394, ".input.spin", state 902, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 394, ".input.spin", state 904, "(1)"
+       line 394, ".input.spin", state 905, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 394, ".input.spin", state 905, "else"
+       line 394, ".input.spin", state 908, "(1)"
+       line 398, ".input.spin", state 916, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 398, ".input.spin", state 918, "(1)"
+       line 398, ".input.spin", state 919, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 398, ".input.spin", state 919, "else"
+       line 398, ".input.spin", state 922, "(1)"
+       line 398, ".input.spin", state 923, "(1)"
+       line 398, ".input.spin", state 923, "(1)"
+       line 396, ".input.spin", state 928, "((i<1))"
+       line 396, ".input.spin", state 928, "((i>=1))"
+       line 403, ".input.spin", state 934, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 936, "(1)"
+       line 403, ".input.spin", state 937, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 403, ".input.spin", state 937, "else"
+       line 403, ".input.spin", state 940, "(1)"
+       line 403, ".input.spin", state 941, "(1)"
+       line 403, ".input.spin", state 941, "(1)"
+       line 407, ".input.spin", state 948, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 950, "(1)"
+       line 407, ".input.spin", state 951, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 407, ".input.spin", state 951, "else"
+       line 407, ".input.spin", state 954, "(1)"
+       line 407, ".input.spin", state 955, "(1)"
+       line 407, ".input.spin", state 955, "(1)"
+       line 405, ".input.spin", state 960, "((i<2))"
+       line 405, ".input.spin", state 960, "((i>=2))"
+       line 411, ".input.spin", state 967, "(1)"
+       line 411, ".input.spin", state 968, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 411, ".input.spin", state 968, "else"
+       line 411, ".input.spin", state 971, "(1)"
+       line 411, ".input.spin", state 972, "(1)"
+       line 411, ".input.spin", state 972, "(1)"
+       line 415, ".input.spin", state 980, "(1)"
+       line 415, ".input.spin", state 981, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 415, ".input.spin", state 981, "else"
+       line 415, ".input.spin", state 984, "(1)"
+       line 415, ".input.spin", state 985, "(1)"
+       line 415, ".input.spin", state 985, "(1)"
+       line 413, ".input.spin", state 990, "((i<1))"
+       line 413, ".input.spin", state 990, "((i>=1))"
+       line 420, ".input.spin", state 997, "(1)"
+       line 420, ".input.spin", state 998, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 420, ".input.spin", state 998, "else"
+       line 420, ".input.spin", state 1001, "(1)"
+       line 420, ".input.spin", state 1002, "(1)"
+       line 420, ".input.spin", state 1002, "(1)"
+       line 424, ".input.spin", state 1010, "(1)"
+       line 424, ".input.spin", state 1011, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 424, ".input.spin", state 1011, "else"
+       line 424, ".input.spin", state 1014, "(1)"
+       line 424, ".input.spin", state 1015, "(1)"
+       line 424, ".input.spin", state 1015, "(1)"
+       line 422, ".input.spin", state 1020, "((i<2))"
+       line 422, ".input.spin", state 1020, "((i>=2))"
+       line 429, ".input.spin", state 1024, "(1)"
+       line 429, ".input.spin", state 1024, "(1)"
+       line 583, ".input.spin", state 1028, "_proc_urcu_reader = (_proc_urcu_reader|(1<<11))"
+       line 394, ".input.spin", state 1033, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 398, ".input.spin", state 1047, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 1065, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 1079, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 1098, "(1)"
+       line 415, ".input.spin", state 1111, "(1)"
+       line 420, ".input.spin", state 1128, "(1)"
+       line 424, ".input.spin", state 1141, "(1)"
+       line 394, ".input.spin", state 1165, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 1197, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 1211, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 1230, "(1)"
+       line 420, ".input.spin", state 1260, "(1)"
+       line 424, ".input.spin", state 1273, "(1)"
+       line 394, ".input.spin", state 1298, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 1330, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 1344, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 1363, "(1)"
+       line 420, ".input.spin", state 1393, "(1)"
+       line 424, ".input.spin", state 1406, "(1)"
+       line 394, ".input.spin", state 1427, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 1459, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 1473, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 1492, "(1)"
+       line 420, ".input.spin", state 1522, "(1)"
+       line 424, ".input.spin", state 1535, "(1)"
+       line 249, ".input.spin", state 1558, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 257, ".input.spin", state 1580, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, ".input.spin", state 1589, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, ".input.spin", state 1605, "(1)"
+       line 230, ".input.spin", state 1613, "(1)"
+       line 234, ".input.spin", state 1625, "(1)"
+       line 238, ".input.spin", state 1633, "(1)"
+       line 394, ".input.spin", state 1651, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 398, ".input.spin", state 1665, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 1683, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 1697, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 1716, "(1)"
+       line 415, ".input.spin", state 1729, "(1)"
+       line 420, ".input.spin", state 1746, "(1)"
+       line 424, ".input.spin", state 1759, "(1)"
+       line 394, ".input.spin", state 1780, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 398, ".input.spin", state 1794, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 1812, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 1826, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 1845, "(1)"
+       line 415, ".input.spin", state 1858, "(1)"
+       line 420, ".input.spin", state 1875, "(1)"
+       line 424, ".input.spin", state 1888, "(1)"
+       line 394, ".input.spin", state 1912, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 398, ".input.spin", state 1928, "(1)"
+       line 403, ".input.spin", state 1944, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 1958, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 1977, "(1)"
+       line 420, ".input.spin", state 2007, "(1)"
+       line 424, ".input.spin", state 2020, "(1)"
+       line 622, ".input.spin", state 2041, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<19))"
+       line 394, ".input.spin", state 2048, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 2080, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 2094, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 2113, "(1)"
+       line 420, ".input.spin", state 2143, "(1)"
+       line 424, ".input.spin", state 2156, "(1)"
+       line 394, ".input.spin", state 2177, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 2209, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 2223, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 2242, "(1)"
+       line 420, ".input.spin", state 2272, "(1)"
+       line 424, ".input.spin", state 2285, "(1)"
+       line 394, ".input.spin", state 2308, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 394, ".input.spin", state 2310, "(1)"
+       line 394, ".input.spin", state 2311, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 394, ".input.spin", state 2311, "else"
+       line 394, ".input.spin", state 2314, "(1)"
+       line 398, ".input.spin", state 2322, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 398, ".input.spin", state 2324, "(1)"
+       line 398, ".input.spin", state 2325, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 398, ".input.spin", state 2325, "else"
+       line 398, ".input.spin", state 2328, "(1)"
+       line 398, ".input.spin", state 2329, "(1)"
+       line 398, ".input.spin", state 2329, "(1)"
+       line 396, ".input.spin", state 2334, "((i<1))"
+       line 396, ".input.spin", state 2334, "((i>=1))"
+       line 403, ".input.spin", state 2340, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 2342, "(1)"
+       line 403, ".input.spin", state 2343, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 403, ".input.spin", state 2343, "else"
+       line 403, ".input.spin", state 2346, "(1)"
+       line 403, ".input.spin", state 2347, "(1)"
+       line 403, ".input.spin", state 2347, "(1)"
+       line 407, ".input.spin", state 2354, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 2356, "(1)"
+       line 407, ".input.spin", state 2357, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 407, ".input.spin", state 2357, "else"
+       line 407, ".input.spin", state 2360, "(1)"
+       line 407, ".input.spin", state 2361, "(1)"
+       line 407, ".input.spin", state 2361, "(1)"
+       line 405, ".input.spin", state 2366, "((i<2))"
+       line 405, ".input.spin", state 2366, "((i>=2))"
+       line 411, ".input.spin", state 2373, "(1)"
+       line 411, ".input.spin", state 2374, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 411, ".input.spin", state 2374, "else"
+       line 411, ".input.spin", state 2377, "(1)"
+       line 411, ".input.spin", state 2378, "(1)"
+       line 411, ".input.spin", state 2378, "(1)"
+       line 415, ".input.spin", state 2386, "(1)"
+       line 415, ".input.spin", state 2387, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 415, ".input.spin", state 2387, "else"
+       line 415, ".input.spin", state 2390, "(1)"
+       line 415, ".input.spin", state 2391, "(1)"
+       line 415, ".input.spin", state 2391, "(1)"
+       line 413, ".input.spin", state 2396, "((i<1))"
+       line 413, ".input.spin", state 2396, "((i>=1))"
+       line 420, ".input.spin", state 2403, "(1)"
+       line 420, ".input.spin", state 2404, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 420, ".input.spin", state 2404, "else"
+       line 420, ".input.spin", state 2407, "(1)"
+       line 420, ".input.spin", state 2408, "(1)"
+       line 420, ".input.spin", state 2408, "(1)"
+       line 424, ".input.spin", state 2416, "(1)"
+       line 424, ".input.spin", state 2417, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 424, ".input.spin", state 2417, "else"
+       line 424, ".input.spin", state 2420, "(1)"
+       line 424, ".input.spin", state 2421, "(1)"
+       line 424, ".input.spin", state 2421, "(1)"
+       line 422, ".input.spin", state 2426, "((i<2))"
+       line 422, ".input.spin", state 2426, "((i>=2))"
+       line 429, ".input.spin", state 2430, "(1)"
+       line 429, ".input.spin", state 2430, "(1)"
+       line 622, ".input.spin", state 2433, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 622, ".input.spin", state 2434, "_proc_urcu_reader = (_proc_urcu_reader|(1<<23))"
+       line 622, ".input.spin", state 2435, "(1)"
+       line 249, ".input.spin", state 2439, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 253, ".input.spin", state 2450, "(1)"
+       line 257, ".input.spin", state 2461, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, ".input.spin", state 2470, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, ".input.spin", state 2486, "(1)"
+       line 230, ".input.spin", state 2494, "(1)"
+       line 234, ".input.spin", state 2506, "(1)"
+       line 238, ".input.spin", state 2514, "(1)"
+       line 394, ".input.spin", state 2532, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 398, ".input.spin", state 2546, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 2564, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 2578, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 2597, "(1)"
+       line 415, ".input.spin", state 2610, "(1)"
+       line 420, ".input.spin", state 2627, "(1)"
+       line 424, ".input.spin", state 2640, "(1)"
+       line 249, ".input.spin", state 2664, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 253, ".input.spin", state 2673, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, ".input.spin", state 2686, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, ".input.spin", state 2695, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, ".input.spin", state 2711, "(1)"
+       line 230, ".input.spin", state 2719, "(1)"
+       line 234, ".input.spin", state 2731, "(1)"
+       line 238, ".input.spin", state 2739, "(1)"
+       line 394, ".input.spin", state 2757, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 398, ".input.spin", state 2771, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 2789, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 2803, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 2822, "(1)"
+       line 415, ".input.spin", state 2835, "(1)"
+       line 420, ".input.spin", state 2852, "(1)"
+       line 424, ".input.spin", state 2865, "(1)"
+       line 394, ".input.spin", state 2886, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 398, ".input.spin", state 2900, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 2918, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 2932, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 2951, "(1)"
+       line 415, ".input.spin", state 2964, "(1)"
+       line 420, ".input.spin", state 2981, "(1)"
+       line 424, ".input.spin", state 2994, "(1)"
+       line 226, ".input.spin", state 3027, "(1)"
+       line 234, ".input.spin", state 3047, "(1)"
+       line 238, ".input.spin", state 3055, "(1)"
+       line 226, ".input.spin", state 3070, "(1)"
+       line 230, ".input.spin", state 3078, "(1)"
+       line 234, ".input.spin", state 3090, "(1)"
+       line 238, ".input.spin", state 3098, "(1)"
+       line 876, ".input.spin", state 3115, "-end-"
+       (318 of 3115 states)
+unreached in proctype urcu_writer
+       line 394, ".input.spin", state 18, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 398, ".input.spin", state 32, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 50, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 83, "(1)"
+       line 415, ".input.spin", state 96, "(1)"
+       line 420, ".input.spin", state 113, "(1)"
+       line 249, ".input.spin", state 149, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 253, ".input.spin", state 158, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, ".input.spin", state 171, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 394, ".input.spin", state 211, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 398, ".input.spin", state 225, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 243, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 257, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, ".input.spin", state 276, "(1)"
+       line 415, ".input.spin", state 289, "(1)"
+       line 420, ".input.spin", state 306, "(1)"
+       line 424, ".input.spin", state 319, "(1)"
+       line 398, ".input.spin", state 356, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 374, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 388, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 415, ".input.spin", state 420, "(1)"
+       line 420, ".input.spin", state 437, "(1)"
+       line 424, ".input.spin", state 450, "(1)"
+       line 398, ".input.spin", state 494, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 512, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 526, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 415, ".input.spin", state 558, "(1)"
+       line 420, ".input.spin", state 575, "(1)"
+       line 424, ".input.spin", state 588, "(1)"
+       line 398, ".input.spin", state 623, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 641, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 655, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 415, ".input.spin", state 687, "(1)"
+       line 420, ".input.spin", state 704, "(1)"
+       line 424, ".input.spin", state 717, "(1)"
+       line 398, ".input.spin", state 754, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, ".input.spin", state 772, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, ".input.spin", state 786, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 415, ".input.spin", state 818, "(1)"
+       line 420, ".input.spin", state 835, "(1)"
+       line 424, ".input.spin", state 848, "(1)"
+       line 249, ".input.spin", state 903, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 253, ".input.spin", state 912, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, ".input.spin", state 927, "(1)"
+       line 261, ".input.spin", state 934, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, ".input.spin", state 950, "(1)"
+       line 230, ".input.spin", state 958, "(1)"
+       line 234, ".input.spin", state 970, "(1)"
+       line 238, ".input.spin", state 978, "(1)"
+       line 253, ".input.spin", state 1003, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, ".input.spin", state 1016, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, ".input.spin", state 1025, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, ".input.spin", state 1041, "(1)"
+       line 230, ".input.spin", state 1049, "(1)"
+       line 234, ".input.spin", state 1061, "(1)"
+       line 238, ".input.spin", state 1069, "(1)"
+       line 253, ".input.spin", state 1094, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, ".input.spin", state 1107, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, ".input.spin", state 1116, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, ".input.spin", state 1132, "(1)"
+       line 230, ".input.spin", state 1140, "(1)"
+       line 234, ".input.spin", state 1152, "(1)"
+       line 238, ".input.spin", state 1160, "(1)"
+       line 253, ".input.spin", state 1185, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, ".input.spin", state 1198, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, ".input.spin", state 1207, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, ".input.spin", state 1223, "(1)"
+       line 230, ".input.spin", state 1231, "(1)"
+       line 234, ".input.spin", state 1243, "(1)"
+       line 238, ".input.spin", state 1251, "(1)"
+       line 1203, ".input.spin", state 1266, "-end-"
+       (71 of 1266 states)
+unreached in proctype :init:
+       (0 of 78 states)
+
+pan: elapsed time 944 seconds
+pan: rate 1995.0819 states/second
+pan: avg transition delay 1.0414e-06 usec
+cp .input.spin asserts.spin.input
+cp .input.spin.trail asserts.spin.input.trail
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/asserts.spin.input b/formal-model/results/urcu-controldataflow-no-ipi/asserts.spin.input
new file mode 100644 (file)
index 0000000..542625d
--- /dev/null
@@ -0,0 +1,1239 @@
+
+// Poison value for freed memory
+#define POISON 1
+// Memory with correct data
+#define WINE 0
+#define SLAB_SIZE 2
+
+#define read_poison    (data_read_first[0] == POISON || data_read_second[0] == POISON)
+
+#define RCU_GP_CTR_BIT (1 << 7)
+#define RCU_GP_CTR_NEST_MASK (RCU_GP_CTR_BIT - 1)
+
+//disabled
+//#define REMOTE_BARRIERS
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+typedef per_proc_bit {
+       bit val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bitfield {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bitfield cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               /*
+                * 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, j);
+               reader_barrier[get_readerid()] = 0;
+       :: 1 ->
+               /*
+                * 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)
+//#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);                                                           \
+       i = 0;                                                                  \
+       do                                                                      \
+       :: i < NR_READERS ->                                                    \
+               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.                                            \
+                */                                                             \
+               do                                                              \
+               :: (reader_barrier[i] == 1) ->                                  \
+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(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, smp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only one reader */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* RCU data */
+DECLARE_CACHED_VAR(bit, rcu_data[SLAB_SIZE]);
+
+/* RCU pointer */
+#if (SLAB_SIZE == 2)
+DECLARE_CACHED_VAR(bit, rcu_ptr);
+bit ptr_read_first[NR_READERS];
+bit ptr_read_second[NR_READERS];
+#else
+DECLARE_CACHED_VAR(byte, rcu_ptr);
+byte ptr_read_first[NR_READERS];
+byte ptr_read_second[NR_READERS];
+#endif
+
+bit data_read_first[NR_READERS];
+bit data_read_second[NR_READERS];
+
+bit init_done = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               ptr_read_first[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb1;
+rmb1_end:
+                               data_read_first[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_first[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               ptr_read_second[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb2;
+rmb2_end:
+                               data_read_second[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_second[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+rmb1:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb1_end;
+rmb2:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_DATA                     (1 << 1)
+#define WRITE_PROC_WMB                 (1 << 2)
+#define WRITE_XCHG_PTR                 (1 << 3)
+
+#define WRITE_PROC_FIRST_MB            (1 << 4)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 5)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 6)
+#define WRITE_PROC_FIRST_WAIT          (1 << 7)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 8)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 9)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 10)
+#define WRITE_PROC_SECOND_WAIT         (1 << 11)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 12)
+
+#define WRITE_PROC_SECOND_MB           (1 << 13)
+
+#define WRITE_FREE                     (1 << 14)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_DATA                    \
+                                       | WRITE_PROC_WMB                \
+                                       | WRITE_XCHG_PTR                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB          \
+                                       | WRITE_FREE)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 15) - 1)
+
+/*
+ * Mutexes are implied around writer execution. A single writer at a time.
+ */
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte cur_data = 0, old_data, loop_nr = 0;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (loop_nr < 3) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               loop_nr = loop_nr + 1;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_WMB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+#endif
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_DATA) ->
+                       ooo_mem(i);
+                       cur_data = (cur_data + 1) % SLAB_SIZE;
+                       WRITE_CACHED_VAR(rcu_data[cur_data], WINE);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_DATA);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA,
+                                 WRITE_PROC_WMB) ->
+                       smp_wmb(i, j);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_WMB,
+                                 WRITE_XCHG_PTR) ->
+                       /* rcu_xchg_pointer() */
+                       atomic {
+                               old_data = READ_CACHED_VAR(rcu_ptr);
+                               WRITE_CACHED_VAR(rcu_ptr, cur_data);
+                       }
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_XCHG_PTR);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_WMB      /* No dependency on
+                                                        * WRITE_DATA because we
+                                                        * write to a
+                                                        * different location. */
+                                 | WRITE_PROC_SECOND_MB
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_FREE) ->
+                       WRITE_CACHED_VAR(rcu_data[old_data], POISON);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_FREE);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+               /*
+                * Note : Promela model adds implicit serialization of the
+                * WRITE_FREE instruction. Normally, it would be permitted to
+                * spill on the next loop execution. Given the validation we do
+                * checks for the data entry read to be poisoned, it's ok if
+                * we do not check "late arriving" memory poisoning.
+                */
+       :: 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
+#ifdef READER_PROGRESS
+               /*
+                * Make sure we don't block the reader's progress.
+                */
+               smp_mb_send(i, j, 5);
+#endif
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(rcu_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       ptr_read_first[i] = 1;
+                       ptr_read_second[i] = 1;
+                       data_read_first[i] = WINE;
+                       data_read_second[i] = WINE;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               INIT_CACHED_VAR(rcu_data[0], WINE, j);
+               i = 1;
+               do
+               :: i < SLAB_SIZE ->
+                       INIT_CACHED_VAR(rcu_data[i], POISON, j);
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/references.txt b/formal-model/results/urcu-controldataflow-no-ipi/references.txt
new file mode 100644 (file)
index 0000000..72c67a2
--- /dev/null
@@ -0,0 +1,13 @@
+http://spinroot.com/spin/Man/ltl.html
+http://en.wikipedia.org/wiki/Linear_temporal_logic
+http://www.dcs.gla.ac.uk/~muffy/MRS4-2002/lect11.ppt
+
+http://www.lsv.ens-cachan.fr/~gastin/ltl2ba/index.php
+http://spinroot.com/spin/Man/index.html
+http://spinroot.com/spin/Man/promela.html
+
+LTL vs CTL :
+
+http://spinroot.com/spin/Doc/course/lecture12.pdf p. 9, p. 15, p. 18
+http://www-i2.informatik.rwth-aachen.de/i2/fileadmin/user_upload/documents/Introduction_to_Model_Checking/mc_lec18.pdf
+  (downloaded)
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/DEFINES b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/DEFINES
new file mode 100644 (file)
index 0000000..980fad6
--- /dev/null
@@ -0,0 +1,14 @@
+
+// Poison value for freed memory
+#define POISON 1
+// Memory with correct data
+#define WINE 0
+#define SLAB_SIZE 2
+
+#define read_poison    (data_read_first[0] == POISON || data_read_second[0] == POISON)
+
+#define RCU_GP_CTR_BIT (1 << 7)
+#define RCU_GP_CTR_NEST_MASK (RCU_GP_CTR_BIT - 1)
+
+//disabled
+#define REMOTE_BARRIERS
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/Makefile b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/Makefile
new file mode 100644 (file)
index 0000000..de47dff
--- /dev/null
@@ -0,0 +1,170 @@
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Copyright (C) Mathieu Desnoyers, 2009
+#
+# Authors: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+
+#CFLAGS=-DSAFETY
+#for multi-core verif, 15.5GB shared mem, use files if full
+#CFLAGS=-DHASH64 -DMEMLIM=15500 -DNCORE=2
+#CFLAGS=-DHASH64 -DCOLLAPSE -DMA=88 -DMEMLIM=15500 -DNCORE=8
+
+#liveness
+#CFLAGS=-DHASH64 -DCOLLAPSE -DMA=88
+CFLAGS=-DHASH64
+
+SPINFILE=urcu.spin
+
+default:
+       make urcu_free | tee urcu_free.log
+       make urcu_free_no_mb | tee urcu_free_no_mb.log
+       make urcu_free_no_rmb | tee urcu_free_no_rmb.log
+       make urcu_free_no_wmb | tee urcu_free_no_wmb.log
+       make urcu_free_single_flip | tee urcu_free_single_flip.log
+       make urcu_progress_writer | tee urcu_progress_writer.log
+       make urcu_progress_reader | tee urcu_progress_reader.log
+       make urcu_progress_writer_error | tee urcu_progress_writer_error.log
+       make asserts | tee asserts.log
+       make summary
+
+#show trail : spin -v -t -N pan.ltl input.spin
+# after each individual make.
+
+summary:
+       @echo
+       @echo "Verification summary"
+       @grep errors: *.log
+
+asserts: clean
+       cat DEFINES > .input.spin
+       cat ${SPINFILE} >> .input.spin
+       rm -f .input.spin.trail
+       spin -a -X .input.spin
+       gcc -O2 -w ${CFLAGS} -DSAFETY -o pan pan.c
+       ./pan -v -c1 -X -m10000000 -w20
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_free: clean urcu_free_ltl run
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_free_nested: clean urcu_free_ltl urcu_free_nested_define run
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_free_nested_define:
+       cp urcu_free_nested.define .input.define
+
+urcu_free_no_rmb: clean urcu_free_ltl urcu_free_no_rmb_define run
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_free_no_rmb_define:
+       cp urcu_free_no_rmb.define .input.define
+
+urcu_free_no_wmb: clean urcu_free_ltl urcu_free_no_wmb_define run
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_free_no_wmb_define:
+       cp urcu_free_no_wmb.define .input.define
+
+urcu_free_no_mb: clean urcu_free_ltl urcu_free_no_mb_define run
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_free_no_mb_define:
+       cp urcu_free_no_mb.define .input.define
+
+urcu_free_single_flip: clean urcu_free_ltl urcu_free_single_flip_define run
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_free_single_flip_define:
+       cp urcu_free_single_flip.define .input.define
+
+urcu_free_ltl:
+       touch .input.define
+       cat .input.define >> pan.ltl
+       cat DEFINES >> pan.ltl
+       spin -f "!(`cat urcu_free.ltl | grep -v ^//`)" >> pan.ltl
+
+# Progress checks
+
+urcu_progress_writer: clean urcu_progress_writer_ltl \
+               urcu_progress_writer_define run_weak_fair
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_progress_writer_define:
+       cp urcu_progress_writer.define .input.define
+
+urcu_progress_writer_ltl:
+       touch .input.define
+       cat .input.define > pan.ltl
+       cat DEFINES >> pan.ltl
+       spin -f "!(`cat urcu_progress.ltl | grep -v ^//`)" >> pan.ltl
+
+urcu_progress_reader: clean urcu_progress_reader_ltl \
+               urcu_progress_reader_define run_weak_fair
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_progress_reader_define:
+       cp urcu_progress_reader.define .input.define
+
+urcu_progress_reader_ltl:
+       touch .input.define
+       cat .input.define > pan.ltl
+       cat DEFINES >> pan.ltl
+       spin -f "!(`cat urcu_progress.ltl | grep -v ^//`)" >> pan.ltl
+
+urcu_progress_writer_error: clean urcu_progress_writer_error_ltl \
+               urcu_progress_writer_error_define run_weak_fair
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_progress_writer_error_define:
+       cp urcu_progress_writer_error.define .input.define
+
+urcu_progress_writer_error_ltl:
+       touch .input.define
+       cat .input.define > pan.ltl
+       cat DEFINES >> pan.ltl
+       spin -f "!(`cat urcu_progress.ltl | grep -v ^//`)" >> pan.ltl
+
+
+run_weak_fair: pan
+       ./pan -a -f -v -c1 -X -m10000000 -w20
+
+run: pan
+       ./pan -a -v -c1 -X -m10000000 -w20
+
+pan: pan.c
+       gcc -O2 -w ${CFLAGS} -o pan pan.c
+
+pan.c: pan.ltl ${SPINFILE}
+       cat .input.define > .input.spin
+       cat DEFINES >> .input.spin
+       cat ${SPINFILE} >> .input.spin
+       rm -f .input.spin.trail
+       spin -a -X -N pan.ltl .input.spin
+
+.PHONY: clean default distclean summary
+clean:
+       rm -f pan* trail.out .input.spin* *.spin.trail .input.define
+distclean:
+       rm -f *.trail *.input *.log
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/references.txt b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/references.txt
new file mode 100644 (file)
index 0000000..72c67a2
--- /dev/null
@@ -0,0 +1,13 @@
+http://spinroot.com/spin/Man/ltl.html
+http://en.wikipedia.org/wiki/Linear_temporal_logic
+http://www.dcs.gla.ac.uk/~muffy/MRS4-2002/lect11.ppt
+
+http://www.lsv.ens-cachan.fr/~gastin/ltl2ba/index.php
+http://spinroot.com/spin/Man/index.html
+http://spinroot.com/spin/Man/promela.html
+
+LTL vs CTL :
+
+http://spinroot.com/spin/Doc/course/lecture12.pdf p. 9, p. 15, p. 18
+http://www-i2.informatik.rwth-aachen.de/i2/fileadmin/user_upload/documents/Introduction_to_Model_Checking/mc_lec18.pdf
+  (downloaded)
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/result-ipi-urcu_free/DEFINES b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/result-ipi-urcu_free/DEFINES
new file mode 100644 (file)
index 0000000..980fad6
--- /dev/null
@@ -0,0 +1,14 @@
+
+// Poison value for freed memory
+#define POISON 1
+// Memory with correct data
+#define WINE 0
+#define SLAB_SIZE 2
+
+#define read_poison    (data_read_first[0] == POISON || data_read_second[0] == POISON)
+
+#define RCU_GP_CTR_BIT (1 << 7)
+#define RCU_GP_CTR_NEST_MASK (RCU_GP_CTR_BIT - 1)
+
+//disabled
+#define REMOTE_BARRIERS
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/result-ipi-urcu_free/Makefile b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/result-ipi-urcu_free/Makefile
new file mode 100644 (file)
index 0000000..de47dff
--- /dev/null
@@ -0,0 +1,170 @@
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Copyright (C) Mathieu Desnoyers, 2009
+#
+# Authors: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+
+#CFLAGS=-DSAFETY
+#for multi-core verif, 15.5GB shared mem, use files if full
+#CFLAGS=-DHASH64 -DMEMLIM=15500 -DNCORE=2
+#CFLAGS=-DHASH64 -DCOLLAPSE -DMA=88 -DMEMLIM=15500 -DNCORE=8
+
+#liveness
+#CFLAGS=-DHASH64 -DCOLLAPSE -DMA=88
+CFLAGS=-DHASH64
+
+SPINFILE=urcu.spin
+
+default:
+       make urcu_free | tee urcu_free.log
+       make urcu_free_no_mb | tee urcu_free_no_mb.log
+       make urcu_free_no_rmb | tee urcu_free_no_rmb.log
+       make urcu_free_no_wmb | tee urcu_free_no_wmb.log
+       make urcu_free_single_flip | tee urcu_free_single_flip.log
+       make urcu_progress_writer | tee urcu_progress_writer.log
+       make urcu_progress_reader | tee urcu_progress_reader.log
+       make urcu_progress_writer_error | tee urcu_progress_writer_error.log
+       make asserts | tee asserts.log
+       make summary
+
+#show trail : spin -v -t -N pan.ltl input.spin
+# after each individual make.
+
+summary:
+       @echo
+       @echo "Verification summary"
+       @grep errors: *.log
+
+asserts: clean
+       cat DEFINES > .input.spin
+       cat ${SPINFILE} >> .input.spin
+       rm -f .input.spin.trail
+       spin -a -X .input.spin
+       gcc -O2 -w ${CFLAGS} -DSAFETY -o pan pan.c
+       ./pan -v -c1 -X -m10000000 -w20
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_free: clean urcu_free_ltl run
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_free_nested: clean urcu_free_ltl urcu_free_nested_define run
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_free_nested_define:
+       cp urcu_free_nested.define .input.define
+
+urcu_free_no_rmb: clean urcu_free_ltl urcu_free_no_rmb_define run
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_free_no_rmb_define:
+       cp urcu_free_no_rmb.define .input.define
+
+urcu_free_no_wmb: clean urcu_free_ltl urcu_free_no_wmb_define run
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_free_no_wmb_define:
+       cp urcu_free_no_wmb.define .input.define
+
+urcu_free_no_mb: clean urcu_free_ltl urcu_free_no_mb_define run
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_free_no_mb_define:
+       cp urcu_free_no_mb.define .input.define
+
+urcu_free_single_flip: clean urcu_free_ltl urcu_free_single_flip_define run
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_free_single_flip_define:
+       cp urcu_free_single_flip.define .input.define
+
+urcu_free_ltl:
+       touch .input.define
+       cat .input.define >> pan.ltl
+       cat DEFINES >> pan.ltl
+       spin -f "!(`cat urcu_free.ltl | grep -v ^//`)" >> pan.ltl
+
+# Progress checks
+
+urcu_progress_writer: clean urcu_progress_writer_ltl \
+               urcu_progress_writer_define run_weak_fair
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_progress_writer_define:
+       cp urcu_progress_writer.define .input.define
+
+urcu_progress_writer_ltl:
+       touch .input.define
+       cat .input.define > pan.ltl
+       cat DEFINES >> pan.ltl
+       spin -f "!(`cat urcu_progress.ltl | grep -v ^//`)" >> pan.ltl
+
+urcu_progress_reader: clean urcu_progress_reader_ltl \
+               urcu_progress_reader_define run_weak_fair
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_progress_reader_define:
+       cp urcu_progress_reader.define .input.define
+
+urcu_progress_reader_ltl:
+       touch .input.define
+       cat .input.define > pan.ltl
+       cat DEFINES >> pan.ltl
+       spin -f "!(`cat urcu_progress.ltl | grep -v ^//`)" >> pan.ltl
+
+urcu_progress_writer_error: clean urcu_progress_writer_error_ltl \
+               urcu_progress_writer_error_define run_weak_fair
+       cp .input.spin $@.spin.input
+       -cp .input.spin.trail $@.spin.input.trail
+
+urcu_progress_writer_error_define:
+       cp urcu_progress_writer_error.define .input.define
+
+urcu_progress_writer_error_ltl:
+       touch .input.define
+       cat .input.define > pan.ltl
+       cat DEFINES >> pan.ltl
+       spin -f "!(`cat urcu_progress.ltl | grep -v ^//`)" >> pan.ltl
+
+
+run_weak_fair: pan
+       ./pan -a -f -v -c1 -X -m10000000 -w20
+
+run: pan
+       ./pan -a -v -c1 -X -m10000000 -w20
+
+pan: pan.c
+       gcc -O2 -w ${CFLAGS} -o pan pan.c
+
+pan.c: pan.ltl ${SPINFILE}
+       cat .input.define > .input.spin
+       cat DEFINES >> .input.spin
+       cat ${SPINFILE} >> .input.spin
+       rm -f .input.spin.trail
+       spin -a -X -N pan.ltl .input.spin
+
+.PHONY: clean default distclean summary
+clean:
+       rm -f pan* trail.out .input.spin* *.spin.trail .input.define
+distclean:
+       rm -f *.trail *.input *.log
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/result-ipi-urcu_free/asserts.log b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/result-ipi-urcu_free/asserts.log
new file mode 100644 (file)
index 0000000..60a124e
--- /dev/null
@@ -0,0 +1,41 @@
+make[1]: Entering directory `/home/compudj/doc/userspace-rcu/formal-model/urcu-controldataflow'
+rm -f pan* trail.out .input.spin* *.spin.trail .input.define
+cat DEFINES > .input.spin
+cat urcu.spin >> .input.spin
+rm -f .input.spin.trail
+spin -a -X .input.spin
+Exit-Status 0
+gcc -O2 -w -DHASH64 -DSAFETY -o pan pan.c
+./pan -v -c1 -X -m10000000 -w20
+Depth=    6408 States=    1e+06 Transitions= 1.63e+08 Memory=   542.717        t=    163 R=   6e+03
+Depth=    7831 States=    2e+06 Transitions= 3.34e+08 Memory=   618.986        t=    343 R=   6e+03
+Depth=    7831 States=    3e+06 Transitions= 5.11e+08 Memory=   695.354        t=    530 R=   6e+03
+pan: resizing hashtable to -w22..  done
+Depth=    7831 States=    4e+06 Transitions= 6.76e+08 Memory=   802.744        t=    697 R=   6e+03
+Depth=    7831 States=    5e+06 Transitions=    9e+08 Memory=   879.014        t=    928 R=   5e+03
+Depth=    7831 States=    6e+06 Transitions= 1.34e+09 Memory=   955.283        t= 1.39e+03 R=   4e+03
+Depth=    7831 States=    7e+06 Transitions= 1.71e+09 Memory=  1031.553        t= 1.79e+03 R=   4e+03
+Depth=    7831 States=    8e+06 Transitions= 2.07e+09 Memory=  1107.920        t= 2.18e+03 R=   4e+03
+Depth=    7831 States=    9e+06 Transitions= 2.39e+09 Memory=  1184.190        t= 2.53e+03 R=   4e+03
+pan: resizing hashtable to -w24..  done
+Depth=    7831 States=    1e+07 Transitions= 2.59e+09 Memory=  1384.553        t= 2.74e+03 R=   4e+03
+Depth=    7831 States=  1.1e+07 Transitions= 2.89e+09 Memory=  1460.822        t= 3.04e+03 R=   4e+03
+Depth=    7831 States=  1.2e+07 Transitions= 3.23e+09 Memory=  1537.092        t= 3.4e+03 R=   4e+03
+Depth=    7831 States=  1.3e+07 Transitions= 3.94e+09 Memory=  1613.459        t= 4.17e+03 R=   3e+03
+Depth=    7831 States=  1.4e+07 Transitions= 4.65e+09 Memory=  1689.729        t= 4.93e+03 R=   3e+03
+Depth=    7831 States=  1.5e+07 Transitions= 5.08e+09 Memory=  1765.998        t= 5.39e+03 R=   3e+03
+Depth=    7831 States=  1.6e+07 Transitions=  5.5e+09 Memory=  1842.268        t= 5.84e+03 R=   3e+03
+Depth=    7831 States=  1.7e+07 Transitions=  5.7e+09 Memory=  1918.635        t= 6.04e+03 R=   3e+03
+Depth=    7831 States=  1.8e+07 Transitions= 6.11e+09 Memory=  1994.904        t= 6.49e+03 R=   3e+03
+Depth=    7831 States=  1.9e+07 Transitions= 6.54e+09 Memory=  2071.174        t= 6.95e+03 R=   3e+03
+Depth=    7831 States=    2e+07 Transitions= 6.89e+09 Memory=  2147.443        t= 7.32e+03 R=   3e+03
+Depth=    7991 States=  2.1e+07 Transitions= 7.11e+09 Memory=  2223.811        t= 7.55e+03 R=   3e+03
+Depth=    7991 States=  2.2e+07 Transitions= 7.39e+09 Memory=  2300.080        t= 7.85e+03 R=   3e+03
+Depth=    7991 States=  2.3e+07 Transitions= 7.59e+09 Memory=  2376.350        t= 8.06e+03 R=   3e+03
+Depth=    7991 States=  2.4e+07 Transitions= 7.86e+09 Memory=  2452.619        t= 8.35e+03 R=   3e+03
+Depth=    7991 States=  2.5e+07 Transitions= 8.07e+09 Memory=  2528.986        t= 8.58e+03 R=   3e+03
+Depth=    7991 States=  2.6e+07 Transitions= 8.31e+09 Memory=  2605.256        t= 8.83e+03 R=   3e+03
+Depth=    7991 States=  2.7e+07 Transitions= 8.55e+09 Memory=  2681.526        t= 9.09e+03 R=   3e+03
+Depth=    7991 States=  2.8e+07 Transitions= 8.79e+09 Memory=  2757.795        t= 9.35e+03 R=   3e+03
+Depth=    7991 States=  2.9e+07 Transitions= 9.03e+09 Memory=  2834.162        t= 9.61e+03 R=   3e+03
+Depth=    7991 States=    3e+07 Transitions= 9.24e+09 Memory=  2910.432        t= 9.83e+03 R=   3e+03
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/result-ipi-urcu_free/asserts.spin.input b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/result-ipi-urcu_free/asserts.spin.input
new file mode 100644 (file)
index 0000000..a3e31d3
--- /dev/null
@@ -0,0 +1,1191 @@
+
+// Poison value for freed memory
+#define POISON 1
+// Memory with correct data
+#define WINE 0
+#define SLAB_SIZE 2
+
+#define read_poison    (data_read_first[0] == POISON || data_read_second[0] == POISON)
+
+#define RCU_GP_CTR_BIT (1 << 7)
+#define RCU_GP_CTR_NEST_MASK (RCU_GP_CTR_BIT - 1)
+
+//disabled
+//#define REMOTE_BARRIERS
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+typedef per_proc_bit {
+       bit val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bitfield {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bitfield cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               smp_mb(i, j);
+               reader_barrier[get_readerid()] = 0;
+       :: 1 ->
+       /*
+        * Busy-looping waiting for other barrier requests is not considered as
+        * non-progress.
+        */
+#ifdef READER_PROGRESS
+progress_reader2:
+#endif
+#ifdef WRITER_PROGRESS
+//progress_writer_from_reader1:
+#endif
+               skip;
+       :: 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_reader2:
+#endif
+               break;
+       od;
+}
+
+#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;                                          \
+               /*                                                              \
+                * 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)                                                     \
+               do                                                              \
+               :: (reader_barrier[i] == 1) -> skip;                            \
+               :: (reader_barrier[i] == 0) -> break;                           \
+               od;                                                             \
+               i++;                                                            \
+       :: i >= NR_READERS ->                                                   \
+               break                                                           \
+       od;                                                                     \
+       smp_mb(i, j);                                                           \
+}
+
+#else
+
+#define smp_mb_send(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, smp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only one reader */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* RCU data */
+DECLARE_CACHED_VAR(bit, rcu_data[SLAB_SIZE]);
+
+/* RCU pointer */
+#if (SLAB_SIZE == 2)
+DECLARE_CACHED_VAR(bit, rcu_ptr);
+bit ptr_read_first[NR_READERS];
+bit ptr_read_second[NR_READERS];
+#else
+DECLARE_CACHED_VAR(byte, rcu_ptr);
+byte ptr_read_first[NR_READERS];
+byte ptr_read_second[NR_READERS];
+#endif
+
+bit data_read_first[NR_READERS];
+bit data_read_second[NR_READERS];
+
+bit init_done = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               :: 1 -> skip;
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               ptr_read_first[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb1;
+rmb1_end:
+                               data_read_first[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_first[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               ptr_read_second[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb2;
+rmb2_end:
+                               data_read_second[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_second[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+rmb1:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb1_end;
+rmb2:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_PROC_FIRST_MB            (1 << 1)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 2)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 3)
+#define WRITE_PROC_FIRST_WAIT          (1 << 4)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 5)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 6)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 7)
+#define WRITE_PROC_SECOND_WAIT         (1 << 8)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 9)
+
+#define WRITE_PROC_SECOND_MB           (1 << 10)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 11) - 1)
+
+/*
+ * Mutexes are implied around writer execution. A single writer at a time.
+ */
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte cur_data = 0, old_data, loop_nr = 0;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (loop_nr < 4) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               loop_nr = loop_nr + 1;
+
+               /* TODO : add instruction scheduling to this code path to test
+                * missing wmb effect. */
+               /* smp_wmb() ensures order of the following instructions */
+               /* malloc */
+               cur_data = (cur_data + 1) % SLAB_SIZE;
+               ooo_mem(i);
+               WRITE_CACHED_VAR(rcu_data[cur_data], WINE);
+#ifndef NO_WMB
+               smp_wmb(i, j);
+#else
+               ooo_mem(i);
+#endif
+               /* rcu_xchg_pointer() */
+               atomic {
+                       old_data = READ_CACHED_VAR(rcu_ptr);
+                       WRITE_CACHED_VAR(rcu_ptr, cur_data);
+               }
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+
+               WRITE_CACHED_VAR(rcu_data[old_data], POISON);
+
+       :: 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
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(rcu_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       ptr_read_first[i] = 1;
+                       ptr_read_second[i] = 1;
+                       data_read_first[i] = WINE;
+                       data_read_second[i] = WINE;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               INIT_CACHED_VAR(rcu_data[0], WINE, j);
+               i = 1;
+               do
+               :: i < SLAB_SIZE ->
+                       INIT_CACHED_VAR(rcu_data[i], POISON, j);
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/result-ipi-urcu_free/references.txt b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/result-ipi-urcu_free/references.txt
new file mode 100644 (file)
index 0000000..72c67a2
--- /dev/null
@@ -0,0 +1,13 @@
+http://spinroot.com/spin/Man/ltl.html
+http://en.wikipedia.org/wiki/Linear_temporal_logic
+http://www.dcs.gla.ac.uk/~muffy/MRS4-2002/lect11.ppt
+
+http://www.lsv.ens-cachan.fr/~gastin/ltl2ba/index.php
+http://spinroot.com/spin/Man/index.html
+http://spinroot.com/spin/Man/promela.html
+
+LTL vs CTL :
+
+http://spinroot.com/spin/Doc/course/lecture12.pdf p. 9, p. 15, p. 18
+http://www-i2.informatik.rwth-aachen.de/i2/fileadmin/user_upload/documents/Introduction_to_Model_Checking/mc_lec18.pdf
+  (downloaded)
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu.sh b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu.sh
new file mode 100644 (file)
index 0000000..65ff517
--- /dev/null
@@ -0,0 +1,29 @@
+#!/bin/sh
+#
+# Compiles and runs the urcu.spin Promela model.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Copyright (C) IBM Corporation, 2009
+#               Mathieu Desnoyers, 2009
+#
+# Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+#          Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+
+# Basic execution, without LTL clauses. See Makefile.
+
+spin -a urcu.spin
+cc -DSAFETY -o pan pan.c
+./pan -v -c1 -X -m10000000 -w21
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu.spin b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu.spin
new file mode 100644 (file)
index 0000000..3751868
--- /dev/null
@@ -0,0 +1,1212 @@
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+typedef per_proc_bit {
+       bit val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bitfield {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bitfield cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               smp_mb(i, j);
+               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
+               break;
+       od;
+}
+
+#ifdef WRITER_PROGRESS
+//#define PROGRESS_LABEL(progressid)   progress_writer_progid_##progressid:
+#define PROGRESS_LABEL(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;                                          \
+               /*                                                              \
+                * 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)                                                     \
+               do                                                              \
+               :: (reader_barrier[i] == 1) -> skip;                            \
+               :: (reader_barrier[i] == 0) -> break;                           \
+               od;                                                             \
+               i++;                                                            \
+       :: i >= NR_READERS ->                                                   \
+               break                                                           \
+       od;                                                                     \
+       smp_mb(i, j);                                                           \
+}
+
+#else
+
+#define smp_mb_send(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, smp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only one reader */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* RCU data */
+DECLARE_CACHED_VAR(bit, rcu_data[SLAB_SIZE]);
+
+/* RCU pointer */
+#if (SLAB_SIZE == 2)
+DECLARE_CACHED_VAR(bit, rcu_ptr);
+bit ptr_read_first[NR_READERS];
+bit ptr_read_second[NR_READERS];
+#else
+DECLARE_CACHED_VAR(byte, rcu_ptr);
+byte ptr_read_first[NR_READERS];
+byte ptr_read_second[NR_READERS];
+#endif
+
+bit data_read_first[NR_READERS];
+bit data_read_second[NR_READERS];
+
+bit init_done = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               :: 1 -> skip;
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               ptr_read_first[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb1;
+rmb1_end:
+                               data_read_first[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_first[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               ptr_read_second[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb2;
+rmb2_end:
+                               data_read_second[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_second[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+rmb1:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb1_end;
+rmb2:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_DATA                     (1 << 1)
+#define WRITE_PROC_WMB                 (1 << 2)
+#define WRITE_XCHG_PTR                 (1 << 3)
+
+#define WRITE_PROC_FIRST_MB            (1 << 4)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 5)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 6)
+#define WRITE_PROC_FIRST_WAIT          (1 << 7)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 8)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 9)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 10)
+#define WRITE_PROC_SECOND_WAIT         (1 << 11)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 12)
+
+#define WRITE_PROC_SECOND_MB           (1 << 13)
+
+#define WRITE_FREE                     (1 << 14)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_DATA                    \
+                                       | WRITE_PROC_WMB                \
+                                       | WRITE_XCHG_PTR                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB          \
+                                       | WRITE_FREE)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 15) - 1)
+
+/*
+ * Mutexes are implied around writer execution. A single writer at a time.
+ */
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte cur_data = 0, old_data, loop_nr = 0;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (loop_nr < 3) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               loop_nr = loop_nr + 1;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_WMB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+#endif
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_DATA) ->
+                       ooo_mem(i);
+                       cur_data = (cur_data + 1) % SLAB_SIZE;
+                       WRITE_CACHED_VAR(rcu_data[cur_data], WINE);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_DATA);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA,
+                                 WRITE_PROC_WMB) ->
+                       smp_wmb(i, j);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_WMB,
+                                 WRITE_XCHG_PTR) ->
+                       /* rcu_xchg_pointer() */
+                       atomic {
+                               old_data = READ_CACHED_VAR(rcu_ptr);
+                               WRITE_CACHED_VAR(rcu_ptr, cur_data);
+                       }
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_XCHG_PTR);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_WMB      /* No dependency on
+                                                        * WRITE_DATA because we
+                                                        * write to a
+                                                        * different location. */
+                                 | WRITE_PROC_SECOND_MB
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_FREE) ->
+                       WRITE_CACHED_VAR(rcu_data[old_data], POISON);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_FREE);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+               /*
+                * Note : Promela model adds implicit serialization of the
+                * WRITE_FREE instruction. Normally, it would be permitted to
+                * spill on the next loop execution. Given the validation we do
+                * checks for the data entry read to be poisoned, it's ok if
+                * we do not check "late arriving" memory poisoning.
+                */
+       :: 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
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(rcu_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       ptr_read_first[i] = 1;
+                       ptr_read_second[i] = 1;
+                       data_read_first[i] = WINE;
+                       data_read_second[i] = WINE;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               INIT_CACHED_VAR(rcu_data[0], WINE, j);
+               i = 1;
+               do
+               :: i < SLAB_SIZE ->
+                       INIT_CACHED_VAR(rcu_data[i], POISON, j);
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu.spin.bkp.b4ptr b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu.spin.bkp.b4ptr
new file mode 100644 (file)
index 0000000..6670f3e
--- /dev/null
@@ -0,0 +1,1123 @@
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bit {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bit cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(generation_ptr, get_pid());
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(generation_ptr, get_pid());
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               smp_mb(i, j);
+               reader_barrier[get_readerid()] = 0;
+       :: 1 ->
+       /*
+        * Busy-looping waiting for other barrier requests is not considered as
+        * non-progress.
+        */
+#ifdef READER_PROGRESS
+progress_reader2:
+#endif
+#ifdef WRITER_PROGRESS
+//progress_writer_from_reader1:
+#endif
+               skip;
+       :: 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_reader2:
+#endif
+               break;
+       od;
+}
+
+#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;                                          \
+               /*                                                              \
+                * 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)                                                     \
+               do                                                              \
+               :: (reader_barrier[i] == 1) -> skip;                            \
+               :: (reader_barrier[i] == 0) -> break;                           \
+               od;                                                             \
+               i++;                                                            \
+       :: i >= NR_READERS ->                                                   \
+               break                                                           \
+       od;                                                                     \
+       smp_mb(i, j);                                                           \
+}
+
+#else
+
+#define smp_mb_send(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, wmp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only two readers */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* pointer generation */
+DECLARE_CACHED_VAR(byte, generation_ptr);
+
+byte last_free_gen = 0;
+bit free_done = 0;
+byte read_generation[NR_READERS];
+bit data_access[NR_READERS];
+
+bit write_lock = 0;
+
+bit init_done = 0;
+
+bit sighand_exec = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(generation_ptr, get_pid());
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(generation_ptr, get_pid());
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               :: 1 -> skip;
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               read_generation[get_readerid()] =
+                                       READ_CACHED_VAR(generation_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               ooo_mem(i);
+                               goto non_atomic;
+non_atomic_end:
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               read_generation[get_readerid()] =
+                                       READ_CACHED_VAR(generation_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               goto non_atomic2;
+non_atomic2_end:
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+non_atomic:
+       data_access[get_readerid()] = 1;
+       data_access[get_readerid()] = 0;
+       goto non_atomic_end;
+non_atomic2:
+       data_access[get_readerid()] = 1;
+       data_access[get_readerid()] = 0;
+       goto non_atomic2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_PROC_FIRST_MB            (1 << 1)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 2)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 3)
+#define WRITE_PROC_FIRST_WAIT          (1 << 4)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 5)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 6)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 7)
+#define WRITE_PROC_SECOND_WAIT         (1 << 8)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 9)
+
+#define WRITE_PROC_SECOND_MB           (1 << 10)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 11) - 1)
+
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte old_gen;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (READ_CACHED_VAR(generation_ptr) < 5) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               ooo_mem(i);
+               atomic {
+                       old_gen = READ_CACHED_VAR(generation_ptr);
+                       WRITE_CACHED_VAR(generation_ptr, old_gen + 1);
+               }
+               ooo_mem(i);
+
+               do
+               :: 1 ->
+                       atomic {
+                               if
+                               :: write_lock == 0 ->
+                                       write_lock = 1;
+                                       break;
+                               :: else ->
+                                       skip;
+                               fi;
+                       }
+               od;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+
+               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
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(generation_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       read_generation[i] = 1;
+                       data_access[i] = 0;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free.log b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free.log
new file mode 100644 (file)
index 0000000..886469c
--- /dev/null
@@ -0,0 +1,584 @@
+make[1]: Entering directory `/home/compudj/doc/userspace-rcu/formal-model/urcu-controldataflow'
+rm -f pan* trail.out .input.spin* *.spin.trail .input.define
+touch .input.define
+cat .input.define >> pan.ltl
+cat DEFINES >> pan.ltl
+spin -f "!(`cat urcu_free.ltl | grep -v ^//`)" >> pan.ltl
+cat .input.define > .input.spin
+cat DEFINES >> .input.spin
+cat urcu.spin >> .input.spin
+rm -f .input.spin.trail
+spin -a -X -N pan.ltl .input.spin
+Exit-Status 0
+gcc -O2 -w -DHASH64 -o pan pan.c
+./pan -a -v -c1 -X -m10000000 -w20
+warning: for p.o. reduction to be valid the never claim must be stutter-invariant
+(never claims generated from LTL formulae are stutter-invariant)
+depth 0: Claim reached state 5 (line 1244)
+Depth=    8092 States=    1e+06 Transitions= 1.63e+08 Memory=   550.432        t=    202 R=   5e+03
+Depth=    9706 States=    2e+06 Transitions= 3.34e+08 Memory=   634.318        t=    421 R=   5e+03
+Depth=    9706 States=    3e+06 Transitions= 5.11e+08 Memory=   718.303        t=    649 R=   5e+03
+pan: resizing hashtable to -w22..  done
+Depth=    9706 States=    4e+06 Transitions= 6.76e+08 Memory=   833.311        t=    855 R=   5e+03
+Depth=    9706 States=    5e+06 Transitions=    9e+08 Memory=   917.295        t= 1.14e+03 R=   4e+03
+Depth=    9706 States=    6e+06 Transitions= 1.34e+09 Memory=  1001.279        t= 1.7e+03 R=   4e+03
+Depth=    9706 States=    7e+06 Transitions= 1.71e+09 Memory=  1085.264        t= 2.18e+03 R=   3e+03
+Depth=    9706 States=    8e+06 Transitions= 2.07e+09 Memory=  1169.151        t= 2.65e+03 R=   3e+03
+Depth=    9706 States=    9e+06 Transitions= 2.39e+09 Memory=  1253.135        t= 3.08e+03 R=   3e+03
+pan: resizing hashtable to -w24..  done
+Depth=    9706 States=    1e+07 Transitions= 2.59e+09 Memory=  1461.115        t= 3.33e+03 R=   3e+03
+Depth=    9706 States=  1.1e+07 Transitions= 2.89e+09 Memory=  1545.100        t= 3.7e+03 R=   3e+03
+Depth=    9706 States=  1.2e+07 Transitions= 3.23e+09 Memory=  1629.084        t= 4.14e+03 R=   3e+03
+Depth=    9706 States=  1.3e+07 Transitions= 3.94e+09 Memory=  1713.068        t= 5.07e+03 R=   3e+03
+Depth=    9706 States=  1.4e+07 Transitions= 4.65e+09 Memory=  1797.053        t= 5.99e+03 R=   2e+03
+Depth=    9706 States=  1.5e+07 Transitions= 5.08e+09 Memory=  1881.037        t= 6.56e+03 R=   2e+03
+Depth=    9706 States=  1.6e+07 Transitions=  5.5e+09 Memory=  1964.924        t= 7.11e+03 R=   2e+03
+Depth=    9706 States=  1.7e+07 Transitions=  5.7e+09 Memory=  2048.908        t= 7.35e+03 R=   2e+03
+Depth=    9706 States=  1.8e+07 Transitions= 6.12e+09 Memory=  2132.893        t= 7.9e+03 R=   2e+03
+Depth=    9706 States=  1.9e+07 Transitions= 6.54e+09 Memory=  2216.877        t= 8.45e+03 R=   2e+03
+Depth=    9706 States=    2e+07 Transitions= 6.89e+09 Memory=  2300.861        t= 8.91e+03 R=   2e+03
+Depth=    9744 States=  2.1e+07 Transitions= 7.11e+09 Memory=  2384.846        t= 9.18e+03 R=   2e+03
+Depth=    9744 States=  2.2e+07 Transitions= 7.39e+09 Memory=  2468.830        t= 9.54e+03 R=   2e+03
+Depth=    9744 States=  2.3e+07 Transitions= 7.59e+09 Memory=  2552.717        t= 9.81e+03 R=   2e+03
+Depth=    9744 States=  2.4e+07 Transitions= 7.86e+09 Memory=  2636.701        t= 1.02e+04 R=   2e+03
+Depth=    9744 States=  2.5e+07 Transitions= 8.07e+09 Memory=  2720.686        t= 1.04e+04 R=   2e+03
+Depth=    9744 States=  2.6e+07 Transitions= 8.31e+09 Memory=  2804.670        t= 1.07e+04 R=   2e+03
+Depth=    9744 States=  2.7e+07 Transitions= 8.55e+09 Memory=  2888.654        t= 1.11e+04 R=   2e+03
+Depth=    9744 States=  2.8e+07 Transitions= 8.79e+09 Memory=  2972.639        t= 1.14e+04 R=   2e+03
+Depth=    9744 States=  2.9e+07 Transitions= 9.03e+09 Memory=  3056.526        t= 1.17e+04 R=   2e+03
+Depth=    9744 States=    3e+07 Transitions= 9.24e+09 Memory=  3140.510        t= 1.2e+04 R=   3e+03
+Depth=    9744 States=  3.1e+07 Transitions= 9.55e+09 Memory=  3224.494        t= 1.24e+04 R=   3e+03
+Depth=    9744 States=  3.2e+07 Transitions=    1e+10 Memory=  3308.479        t= 1.3e+04 R=   2e+03
+Depth=    9744 States=  3.3e+07 Transitions= 1.04e+10 Memory=  3392.463        t= 1.35e+04 R=   2e+03
+Depth=    9744 States=  3.4e+07 Transitions= 1.08e+10 Memory=  3476.447        t= 1.4e+04 R=   2e+03
+pan: resizing hashtable to -w26..  done
+Depth=    9744 States=  3.5e+07 Transitions= 1.11e+10 Memory=  4056.416        t= 1.45e+04 R=   2e+03
+Depth=    9744 States=  3.6e+07 Transitions= 1.14e+10 Memory=  4140.401        t= 1.47e+04 R=   2e+03
+Depth=    9744 States=  3.7e+07 Transitions= 1.16e+10 Memory=  4224.385        t= 1.51e+04 R=   2e+03
+Depth=    9744 States=  3.8e+07 Transitions= 1.19e+10 Memory=  4308.369        t= 1.54e+04 R=   2e+03
+Depth=    9744 States=  3.9e+07 Transitions= 1.25e+10 Memory=  4392.354        t= 1.62e+04 R=   2e+03
+Depth=    9744 States=    4e+07 Transitions= 1.33e+10 Memory=  4476.338        t= 1.72e+04 R=   2e+03
+Depth=    9744 States=  4.1e+07 Transitions= 1.38e+10 Memory=  4560.225        t= 1.79e+04 R=   2e+03
+Depth=    9744 States=  4.2e+07 Transitions= 1.43e+10 Memory=  4644.209        t= 1.86e+04 R=   2e+03
+Depth=    9744 States=  4.3e+07 Transitions= 1.45e+10 Memory=  4728.193        t= 1.88e+04 R=   2e+03
+Depth=    9744 States=  4.4e+07 Transitions= 1.48e+10 Memory=  4812.178        t= 1.92e+04 R=   2e+03
+Depth=    9744 States=  4.5e+07 Transitions= 1.52e+10 Memory=  4896.162        t= 1.97e+04 R=   2e+03
+Depth=    9744 States=  4.6e+07 Transitions= 1.55e+10 Memory=  4980.147        t= 2.02e+04 R=   2e+03
+Depth=    9744 States=  4.7e+07 Transitions= 1.58e+10 Memory=  5064.131        t= 2.05e+04 R=   2e+03
+Depth=    9744 States=  4.8e+07 Transitions= 1.61e+10 Memory=  5148.018        t= 2.08e+04 R=   2e+03
+Depth=    9744 States=  4.9e+07 Transitions= 1.63e+10 Memory=  5232.002        t= 2.11e+04 R=   2e+03
+Depth=    9744 States=    5e+07 Transitions= 1.66e+10 Memory=  5315.986        t= 2.15e+04 R=   2e+03
+Depth=    9744 States=  5.1e+07 Transitions= 1.68e+10 Memory=  5399.971        t= 2.17e+04 R=   2e+03
+Depth=    9744 States=  5.2e+07 Transitions=  1.7e+10 Memory=  5483.955        t= 2.2e+04 R=   2e+03
+Depth=    9744 States=  5.3e+07 Transitions= 1.72e+10 Memory=  5567.940        t= 2.23e+04 R=   2e+03
+Depth=    9744 States=  5.4e+07 Transitions= 1.75e+10 Memory=  5651.826        t= 2.26e+04 R=   2e+03
+Depth=    9744 States=  5.5e+07 Transitions= 1.77e+10 Memory=  5735.811        t= 2.29e+04 R=   2e+03
+Depth=    9744 States=  5.6e+07 Transitions= 1.79e+10 Memory=  5819.795        t= 2.32e+04 R=   2e+03
+Depth=    9744 States=  5.7e+07 Transitions= 1.83e+10 Memory=  5903.779        t= 2.36e+04 R=   2e+03
+Depth=    9744 States=  5.8e+07 Transitions= 1.87e+10 Memory=  5987.764        t= 2.42e+04 R=   2e+03
+Depth=    9744 States=  5.9e+07 Transitions= 1.91e+10 Memory=  6071.748        t= 2.46e+04 R=   2e+03
+Depth=    9744 States=    6e+07 Transitions= 1.94e+10 Memory=  6155.733        t= 2.51e+04 R=   2e+03
+Depth=    9744 States=  6.1e+07 Transitions= 1.98e+10 Memory=  6239.619        t= 2.56e+04 R=   2e+03
+Depth=    9744 States=  6.2e+07 Transitions= 2.02e+10 Memory=  6323.604        t= 2.61e+04 R=   2e+03
+
+(Spin Version 5.1.7 -- 23 December 2008)
+       + Partial Order Reduction
+
+Full statespace search for:
+       never claim             +
+       assertion violations    + (if within scope of claim)
+       acceptance   cycles     + (fairness disabled)
+       invalid end states      - (disabled by never claim)
+
+State-vector 88 byte, depth reached 9744, errors: 0
+ 62203844 states, stored
+2.0186786e+10 states, matched
+2.024899e+10 transitions (= stored+matched)
+1.1642436e+11 atomic steps
+hash conflicts: 1.1759978e+10 (resolved)
+
+Stats on memory usage (in Megabytes):
+ 6881.376      equivalent memory usage for states (stored*(State-vector + overhead))
+ 5374.024      actual memory usage for states (compression: 78.10%)
+               state-vector as stored = 63 byte + 28 byte overhead
+  512.000      memory used for hash table (-w26)
+  457.764      memory used for DFS stack (-m10000000)
+    2.996      memory lost to fragmentation
+ 6340.791      total actual memory usage
+
+unreached in proctype urcu_reader
+       line 249, "pan.___", state 32, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 257, "pan.___", state 54, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, "pan.___", state 63, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, "pan.___", state 79, "(1)"
+       line 230, "pan.___", state 87, "(1)"
+       line 234, "pan.___", state 99, "(1)"
+       line 238, "pan.___", state 107, "(1)"
+       line 386, "pan.___", state 132, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 164, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 178, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 197, "(1)"
+       line 412, "pan.___", state 227, "(1)"
+       line 416, "pan.___", state 240, "(1)"
+       line 662, "pan.___", state 261, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<1))"
+       line 386, "pan.___", state 268, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 300, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 314, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 333, "(1)"
+       line 412, "pan.___", state 363, "(1)"
+       line 416, "pan.___", state 376, "(1)"
+       line 386, "pan.___", state 397, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 429, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 443, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 462, "(1)"
+       line 412, "pan.___", state 492, "(1)"
+       line 416, "pan.___", state 505, "(1)"
+       line 386, "pan.___", state 528, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 386, "pan.___", state 530, "(1)"
+       line 386, "pan.___", state 531, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 386, "pan.___", state 531, "else"
+       line 386, "pan.___", state 534, "(1)"
+       line 390, "pan.___", state 542, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 390, "pan.___", state 544, "(1)"
+       line 390, "pan.___", state 545, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 390, "pan.___", state 545, "else"
+       line 390, "pan.___", state 548, "(1)"
+       line 390, "pan.___", state 549, "(1)"
+       line 390, "pan.___", state 549, "(1)"
+       line 388, "pan.___", state 554, "((i<1))"
+       line 388, "pan.___", state 554, "((i>=1))"
+       line 395, "pan.___", state 560, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 562, "(1)"
+       line 395, "pan.___", state 563, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 563, "else"
+       line 395, "pan.___", state 566, "(1)"
+       line 395, "pan.___", state 567, "(1)"
+       line 395, "pan.___", state 567, "(1)"
+       line 399, "pan.___", state 574, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 576, "(1)"
+       line 399, "pan.___", state 577, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 577, "else"
+       line 399, "pan.___", state 580, "(1)"
+       line 399, "pan.___", state 581, "(1)"
+       line 399, "pan.___", state 581, "(1)"
+       line 397, "pan.___", state 586, "((i<2))"
+       line 397, "pan.___", state 586, "((i>=2))"
+       line 403, "pan.___", state 593, "(1)"
+       line 403, "pan.___", state 594, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 403, "pan.___", state 594, "else"
+       line 403, "pan.___", state 597, "(1)"
+       line 403, "pan.___", state 598, "(1)"
+       line 403, "pan.___", state 598, "(1)"
+       line 407, "pan.___", state 606, "(1)"
+       line 407, "pan.___", state 607, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 407, "pan.___", state 607, "else"
+       line 407, "pan.___", state 610, "(1)"
+       line 407, "pan.___", state 611, "(1)"
+       line 407, "pan.___", state 611, "(1)"
+       line 405, "pan.___", state 616, "((i<1))"
+       line 405, "pan.___", state 616, "((i>=1))"
+       line 412, "pan.___", state 623, "(1)"
+       line 412, "pan.___", state 624, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 624, "else"
+       line 412, "pan.___", state 627, "(1)"
+       line 412, "pan.___", state 628, "(1)"
+       line 412, "pan.___", state 628, "(1)"
+       line 416, "pan.___", state 636, "(1)"
+       line 416, "pan.___", state 637, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 637, "else"
+       line 416, "pan.___", state 640, "(1)"
+       line 416, "pan.___", state 641, "(1)"
+       line 416, "pan.___", state 641, "(1)"
+       line 414, "pan.___", state 646, "((i<2))"
+       line 414, "pan.___", state 646, "((i>=2))"
+       line 421, "pan.___", state 650, "(1)"
+       line 421, "pan.___", state 650, "(1)"
+       line 662, "pan.___", state 653, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 662, "pan.___", state 654, "_proc_urcu_reader = (_proc_urcu_reader|(1<<5))"
+       line 662, "pan.___", state 655, "(1)"
+       line 386, "pan.___", state 662, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 694, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 708, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 727, "(1)"
+       line 412, "pan.___", state 757, "(1)"
+       line 416, "pan.___", state 770, "(1)"
+       line 386, "pan.___", state 798, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 386, "pan.___", state 800, "(1)"
+       line 386, "pan.___", state 801, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 386, "pan.___", state 801, "else"
+       line 386, "pan.___", state 804, "(1)"
+       line 390, "pan.___", state 812, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 390, "pan.___", state 814, "(1)"
+       line 390, "pan.___", state 815, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 390, "pan.___", state 815, "else"
+       line 390, "pan.___", state 818, "(1)"
+       line 390, "pan.___", state 819, "(1)"
+       line 390, "pan.___", state 819, "(1)"
+       line 388, "pan.___", state 824, "((i<1))"
+       line 388, "pan.___", state 824, "((i>=1))"
+       line 395, "pan.___", state 830, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 832, "(1)"
+       line 395, "pan.___", state 833, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 833, "else"
+       line 395, "pan.___", state 836, "(1)"
+       line 395, "pan.___", state 837, "(1)"
+       line 395, "pan.___", state 837, "(1)"
+       line 399, "pan.___", state 844, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 846, "(1)"
+       line 399, "pan.___", state 847, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 847, "else"
+       line 399, "pan.___", state 850, "(1)"
+       line 399, "pan.___", state 851, "(1)"
+       line 399, "pan.___", state 851, "(1)"
+       line 397, "pan.___", state 856, "((i<2))"
+       line 397, "pan.___", state 856, "((i>=2))"
+       line 403, "pan.___", state 863, "(1)"
+       line 403, "pan.___", state 864, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 403, "pan.___", state 864, "else"
+       line 403, "pan.___", state 867, "(1)"
+       line 403, "pan.___", state 868, "(1)"
+       line 403, "pan.___", state 868, "(1)"
+       line 407, "pan.___", state 876, "(1)"
+       line 407, "pan.___", state 877, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 407, "pan.___", state 877, "else"
+       line 407, "pan.___", state 880, "(1)"
+       line 407, "pan.___", state 881, "(1)"
+       line 407, "pan.___", state 881, "(1)"
+       line 405, "pan.___", state 886, "((i<1))"
+       line 405, "pan.___", state 886, "((i>=1))"
+       line 412, "pan.___", state 893, "(1)"
+       line 412, "pan.___", state 894, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 894, "else"
+       line 412, "pan.___", state 897, "(1)"
+       line 412, "pan.___", state 898, "(1)"
+       line 412, "pan.___", state 898, "(1)"
+       line 416, "pan.___", state 906, "(1)"
+       line 416, "pan.___", state 907, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 907, "else"
+       line 416, "pan.___", state 910, "(1)"
+       line 416, "pan.___", state 911, "(1)"
+       line 416, "pan.___", state 911, "(1)"
+       line 421, "pan.___", state 920, "(1)"
+       line 421, "pan.___", state 920, "(1)"
+       line 386, "pan.___", state 927, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 386, "pan.___", state 929, "(1)"
+       line 386, "pan.___", state 930, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 386, "pan.___", state 930, "else"
+       line 386, "pan.___", state 933, "(1)"
+       line 390, "pan.___", state 941, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 390, "pan.___", state 943, "(1)"
+       line 390, "pan.___", state 944, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 390, "pan.___", state 944, "else"
+       line 390, "pan.___", state 947, "(1)"
+       line 390, "pan.___", state 948, "(1)"
+       line 390, "pan.___", state 948, "(1)"
+       line 388, "pan.___", state 953, "((i<1))"
+       line 388, "pan.___", state 953, "((i>=1))"
+       line 395, "pan.___", state 959, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 961, "(1)"
+       line 395, "pan.___", state 962, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 962, "else"
+       line 395, "pan.___", state 965, "(1)"
+       line 395, "pan.___", state 966, "(1)"
+       line 395, "pan.___", state 966, "(1)"
+       line 399, "pan.___", state 973, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 975, "(1)"
+       line 399, "pan.___", state 976, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 976, "else"
+       line 399, "pan.___", state 979, "(1)"
+       line 399, "pan.___", state 980, "(1)"
+       line 399, "pan.___", state 980, "(1)"
+       line 397, "pan.___", state 985, "((i<2))"
+       line 397, "pan.___", state 985, "((i>=2))"
+       line 403, "pan.___", state 992, "(1)"
+       line 403, "pan.___", state 993, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 403, "pan.___", state 993, "else"
+       line 403, "pan.___", state 996, "(1)"
+       line 403, "pan.___", state 997, "(1)"
+       line 403, "pan.___", state 997, "(1)"
+       line 407, "pan.___", state 1005, "(1)"
+       line 407, "pan.___", state 1006, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 407, "pan.___", state 1006, "else"
+       line 407, "pan.___", state 1009, "(1)"
+       line 407, "pan.___", state 1010, "(1)"
+       line 407, "pan.___", state 1010, "(1)"
+       line 405, "pan.___", state 1015, "((i<1))"
+       line 405, "pan.___", state 1015, "((i>=1))"
+       line 412, "pan.___", state 1022, "(1)"
+       line 412, "pan.___", state 1023, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 1023, "else"
+       line 412, "pan.___", state 1026, "(1)"
+       line 412, "pan.___", state 1027, "(1)"
+       line 412, "pan.___", state 1027, "(1)"
+       line 416, "pan.___", state 1035, "(1)"
+       line 416, "pan.___", state 1036, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 1036, "else"
+       line 416, "pan.___", state 1039, "(1)"
+       line 416, "pan.___", state 1040, "(1)"
+       line 416, "pan.___", state 1040, "(1)"
+       line 414, "pan.___", state 1045, "((i<2))"
+       line 414, "pan.___", state 1045, "((i>=2))"
+       line 421, "pan.___", state 1049, "(1)"
+       line 421, "pan.___", state 1049, "(1)"
+       line 670, "pan.___", state 1053, "_proc_urcu_reader = (_proc_urcu_reader|(1<<11))"
+       line 386, "pan.___", state 1058, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 1090, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 1104, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 1123, "(1)"
+       line 412, "pan.___", state 1153, "(1)"
+       line 416, "pan.___", state 1166, "(1)"
+       line 386, "pan.___", state 1190, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 1222, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 1236, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 1255, "(1)"
+       line 412, "pan.___", state 1285, "(1)"
+       line 416, "pan.___", state 1298, "(1)"
+       line 386, "pan.___", state 1323, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 1355, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 1369, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 1388, "(1)"
+       line 412, "pan.___", state 1418, "(1)"
+       line 416, "pan.___", state 1431, "(1)"
+       line 386, "pan.___", state 1452, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 1484, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 1498, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 1517, "(1)"
+       line 412, "pan.___", state 1547, "(1)"
+       line 416, "pan.___", state 1560, "(1)"
+       line 386, "pan.___", state 1586, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 1618, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 1632, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 1651, "(1)"
+       line 412, "pan.___", state 1681, "(1)"
+       line 416, "pan.___", state 1694, "(1)"
+       line 386, "pan.___", state 1715, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 1747, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 1761, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 1780, "(1)"
+       line 412, "pan.___", state 1810, "(1)"
+       line 416, "pan.___", state 1823, "(1)"
+       line 386, "pan.___", state 1847, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 1879, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 1893, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 1912, "(1)"
+       line 412, "pan.___", state 1942, "(1)"
+       line 416, "pan.___", state 1955, "(1)"
+       line 709, "pan.___", state 1976, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<19))"
+       line 386, "pan.___", state 1983, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 2015, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 2029, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 2048, "(1)"
+       line 412, "pan.___", state 2078, "(1)"
+       line 416, "pan.___", state 2091, "(1)"
+       line 386, "pan.___", state 2112, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 2144, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 2158, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 2177, "(1)"
+       line 412, "pan.___", state 2207, "(1)"
+       line 416, "pan.___", state 2220, "(1)"
+       line 386, "pan.___", state 2243, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 386, "pan.___", state 2245, "(1)"
+       line 386, "pan.___", state 2246, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 386, "pan.___", state 2246, "else"
+       line 386, "pan.___", state 2249, "(1)"
+       line 390, "pan.___", state 2257, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 390, "pan.___", state 2259, "(1)"
+       line 390, "pan.___", state 2260, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 390, "pan.___", state 2260, "else"
+       line 390, "pan.___", state 2263, "(1)"
+       line 390, "pan.___", state 2264, "(1)"
+       line 390, "pan.___", state 2264, "(1)"
+       line 388, "pan.___", state 2269, "((i<1))"
+       line 388, "pan.___", state 2269, "((i>=1))"
+       line 395, "pan.___", state 2275, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 2277, "(1)"
+       line 395, "pan.___", state 2278, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 2278, "else"
+       line 395, "pan.___", state 2281, "(1)"
+       line 395, "pan.___", state 2282, "(1)"
+       line 395, "pan.___", state 2282, "(1)"
+       line 399, "pan.___", state 2289, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 2291, "(1)"
+       line 399, "pan.___", state 2292, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 2292, "else"
+       line 399, "pan.___", state 2295, "(1)"
+       line 399, "pan.___", state 2296, "(1)"
+       line 399, "pan.___", state 2296, "(1)"
+       line 397, "pan.___", state 2301, "((i<2))"
+       line 397, "pan.___", state 2301, "((i>=2))"
+       line 403, "pan.___", state 2308, "(1)"
+       line 403, "pan.___", state 2309, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 403, "pan.___", state 2309, "else"
+       line 403, "pan.___", state 2312, "(1)"
+       line 403, "pan.___", state 2313, "(1)"
+       line 403, "pan.___", state 2313, "(1)"
+       line 407, "pan.___", state 2321, "(1)"
+       line 407, "pan.___", state 2322, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 407, "pan.___", state 2322, "else"
+       line 407, "pan.___", state 2325, "(1)"
+       line 407, "pan.___", state 2326, "(1)"
+       line 407, "pan.___", state 2326, "(1)"
+       line 405, "pan.___", state 2331, "((i<1))"
+       line 405, "pan.___", state 2331, "((i>=1))"
+       line 412, "pan.___", state 2338, "(1)"
+       line 412, "pan.___", state 2339, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 2339, "else"
+       line 412, "pan.___", state 2342, "(1)"
+       line 412, "pan.___", state 2343, "(1)"
+       line 412, "pan.___", state 2343, "(1)"
+       line 416, "pan.___", state 2351, "(1)"
+       line 416, "pan.___", state 2352, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 2352, "else"
+       line 416, "pan.___", state 2355, "(1)"
+       line 416, "pan.___", state 2356, "(1)"
+       line 416, "pan.___", state 2356, "(1)"
+       line 414, "pan.___", state 2361, "((i<2))"
+       line 414, "pan.___", state 2361, "((i>=2))"
+       line 421, "pan.___", state 2365, "(1)"
+       line 421, "pan.___", state 2365, "(1)"
+       line 709, "pan.___", state 2368, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 709, "pan.___", state 2369, "_proc_urcu_reader = (_proc_urcu_reader|(1<<23))"
+       line 709, "pan.___", state 2370, "(1)"
+       line 386, "pan.___", state 2377, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 2409, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 2423, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 2442, "(1)"
+       line 412, "pan.___", state 2472, "(1)"
+       line 416, "pan.___", state 2485, "(1)"
+       line 386, "pan.___", state 2512, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 2544, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 2558, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 2577, "(1)"
+       line 412, "pan.___", state 2607, "(1)"
+       line 416, "pan.___", state 2620, "(1)"
+       line 386, "pan.___", state 2641, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 2673, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 2687, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 2706, "(1)"
+       line 412, "pan.___", state 2736, "(1)"
+       line 416, "pan.___", state 2749, "(1)"
+       line 226, "pan.___", state 2782, "(1)"
+       line 234, "pan.___", state 2802, "(1)"
+       line 238, "pan.___", state 2810, "(1)"
+       line 226, "pan.___", state 2825, "(1)"
+       line 234, "pan.___", state 2845, "(1)"
+       line 238, "pan.___", state 2853, "(1)"
+       line 869, "pan.___", state 2870, "-end-"
+       (278 of 2870 states)
+unreached in proctype urcu_writer
+       line 386, "pan.___", state 18, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 390, "pan.___", state 32, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 50, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 83, "(1)"
+       line 407, "pan.___", state 96, "(1)"
+       line 412, "pan.___", state 113, "(1)"
+       line 249, "pan.___", state 149, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 253, "pan.___", state 158, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, "pan.___", state 171, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 386, "pan.___", state 211, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 390, "pan.___", state 225, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 243, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 257, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 276, "(1)"
+       line 407, "pan.___", state 289, "(1)"
+       line 412, "pan.___", state 306, "(1)"
+       line 416, "pan.___", state 319, "(1)"
+       line 390, "pan.___", state 356, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 374, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 388, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 420, "(1)"
+       line 412, "pan.___", state 437, "(1)"
+       line 416, "pan.___", state 450, "(1)"
+       line 390, "pan.___", state 494, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 512, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 526, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 558, "(1)"
+       line 412, "pan.___", state 575, "(1)"
+       line 416, "pan.___", state 588, "(1)"
+       line 390, "pan.___", state 623, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 641, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 655, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 687, "(1)"
+       line 412, "pan.___", state 704, "(1)"
+       line 416, "pan.___", state 717, "(1)"
+       line 390, "pan.___", state 754, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 772, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 786, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 818, "(1)"
+       line 412, "pan.___", state 835, "(1)"
+       line 416, "pan.___", state 848, "(1)"
+       line 249, "pan.___", state 903, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 253, "pan.___", state 912, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, "pan.___", state 927, "(1)"
+       line 261, "pan.___", state 934, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, "pan.___", state 950, "(1)"
+       line 230, "pan.___", state 958, "(1)"
+       line 234, "pan.___", state 970, "(1)"
+       line 238, "pan.___", state 978, "(1)"
+       line 249, "pan.___", state 1009, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 253, "pan.___", state 1018, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, "pan.___", state 1031, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, "pan.___", state 1040, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, "pan.___", state 1056, "(1)"
+       line 230, "pan.___", state 1064, "(1)"
+       line 234, "pan.___", state 1076, "(1)"
+       line 238, "pan.___", state 1084, "(1)"
+       line 253, "pan.___", state 1110, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, "pan.___", state 1123, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, "pan.___", state 1132, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, "pan.___", state 1148, "(1)"
+       line 230, "pan.___", state 1156, "(1)"
+       line 234, "pan.___", state 1168, "(1)"
+       line 238, "pan.___", state 1176, "(1)"
+       line 249, "pan.___", state 1207, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 253, "pan.___", state 1216, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, "pan.___", state 1229, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, "pan.___", state 1238, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, "pan.___", state 1254, "(1)"
+       line 230, "pan.___", state 1262, "(1)"
+       line 234, "pan.___", state 1274, "(1)"
+       line 238, "pan.___", state 1282, "(1)"
+       line 253, "pan.___", state 1308, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, "pan.___", state 1321, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, "pan.___", state 1330, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, "pan.___", state 1346, "(1)"
+       line 230, "pan.___", state 1354, "(1)"
+       line 234, "pan.___", state 1366, "(1)"
+       line 238, "pan.___", state 1374, "(1)"
+       line 249, "pan.___", state 1405, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 253, "pan.___", state 1414, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, "pan.___", state 1427, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, "pan.___", state 1436, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, "pan.___", state 1452, "(1)"
+       line 230, "pan.___", state 1460, "(1)"
+       line 234, "pan.___", state 1472, "(1)"
+       line 238, "pan.___", state 1480, "(1)"
+       line 253, "pan.___", state 1506, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, "pan.___", state 1519, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, "pan.___", state 1528, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, "pan.___", state 1544, "(1)"
+       line 230, "pan.___", state 1552, "(1)"
+       line 234, "pan.___", state 1564, "(1)"
+       line 238, "pan.___", state 1572, "(1)"
+       line 249, "pan.___", state 1603, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 253, "pan.___", state 1612, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, "pan.___", state 1625, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, "pan.___", state 1634, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, "pan.___", state 1650, "(1)"
+       line 230, "pan.___", state 1658, "(1)"
+       line 234, "pan.___", state 1670, "(1)"
+       line 238, "pan.___", state 1678, "(1)"
+       line 1190, "pan.___", state 1694, "-end-"
+       (103 of 1694 states)
+unreached in proctype :init:
+       (0 of 78 states)
+unreached in proctype :never:
+       line 1249, "pan.___", state 8, "-end-"
+       (1 of 8 states)
+
+pan: elapsed time 2.62e+04 seconds
+pan: rate 2378.2573 states/second
+pan: avg transition delay 1.2917e-06 usec
+cp .input.spin urcu_free.spin.input
+cp .input.spin.trail urcu_free.spin.input.trail
+make[1]: Leaving directory `/home/compudj/doc/userspace-rcu/formal-model/urcu-controldataflow'
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free.ltl b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free.ltl
new file mode 100644 (file)
index 0000000..6be1be9
--- /dev/null
@@ -0,0 +1 @@
+[] (!read_poison)
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free.spin.input b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free.spin.input
new file mode 100644 (file)
index 0000000..527f16e
--- /dev/null
@@ -0,0 +1,1226 @@
+
+// Poison value for freed memory
+#define POISON 1
+// Memory with correct data
+#define WINE 0
+#define SLAB_SIZE 2
+
+#define read_poison    (data_read_first[0] == POISON || data_read_second[0] == POISON)
+
+#define RCU_GP_CTR_BIT (1 << 7)
+#define RCU_GP_CTR_NEST_MASK (RCU_GP_CTR_BIT - 1)
+
+//disabled
+#define REMOTE_BARRIERS
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+typedef per_proc_bit {
+       bit val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bitfield {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bitfield cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               smp_mb(i, j);
+               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
+               break;
+       od;
+}
+
+#ifdef WRITER_PROGRESS
+//#define PROGRESS_LABEL(progressid)   progress_writer_progid_##progressid:
+#define PROGRESS_LABEL(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;                                          \
+               /*                                                              \
+                * 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)                                                     \
+               do                                                              \
+               :: (reader_barrier[i] == 1) -> skip;                            \
+               :: (reader_barrier[i] == 0) -> break;                           \
+               od;                                                             \
+               i++;                                                            \
+       :: i >= NR_READERS ->                                                   \
+               break                                                           \
+       od;                                                                     \
+       smp_mb(i, j);                                                           \
+}
+
+#else
+
+#define smp_mb_send(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, smp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only one reader */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* RCU data */
+DECLARE_CACHED_VAR(bit, rcu_data[SLAB_SIZE]);
+
+/* RCU pointer */
+#if (SLAB_SIZE == 2)
+DECLARE_CACHED_VAR(bit, rcu_ptr);
+bit ptr_read_first[NR_READERS];
+bit ptr_read_second[NR_READERS];
+#else
+DECLARE_CACHED_VAR(byte, rcu_ptr);
+byte ptr_read_first[NR_READERS];
+byte ptr_read_second[NR_READERS];
+#endif
+
+bit data_read_first[NR_READERS];
+bit data_read_second[NR_READERS];
+
+bit init_done = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               :: 1 -> skip;
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               ptr_read_first[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb1;
+rmb1_end:
+                               data_read_first[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_first[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               ptr_read_second[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb2;
+rmb2_end:
+                               data_read_second[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_second[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+rmb1:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb1_end;
+rmb2:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_DATA                     (1 << 1)
+#define WRITE_PROC_WMB                 (1 << 2)
+#define WRITE_XCHG_PTR                 (1 << 3)
+
+#define WRITE_PROC_FIRST_MB            (1 << 4)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 5)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 6)
+#define WRITE_PROC_FIRST_WAIT          (1 << 7)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 8)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 9)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 10)
+#define WRITE_PROC_SECOND_WAIT         (1 << 11)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 12)
+
+#define WRITE_PROC_SECOND_MB           (1 << 13)
+
+#define WRITE_FREE                     (1 << 14)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_DATA                    \
+                                       | WRITE_PROC_WMB                \
+                                       | WRITE_XCHG_PTR                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB          \
+                                       | WRITE_FREE)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 15) - 1)
+
+/*
+ * Mutexes are implied around writer execution. A single writer at a time.
+ */
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte cur_data = 0, old_data, loop_nr = 0;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (loop_nr < 3) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               loop_nr = loop_nr + 1;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_WMB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+#endif
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_DATA) ->
+                       ooo_mem(i);
+                       cur_data = (cur_data + 1) % SLAB_SIZE;
+                       WRITE_CACHED_VAR(rcu_data[cur_data], WINE);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_DATA);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA,
+                                 WRITE_PROC_WMB) ->
+                       smp_wmb(i, j);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_WMB,
+                                 WRITE_XCHG_PTR) ->
+                       /* rcu_xchg_pointer() */
+                       atomic {
+                               old_data = READ_CACHED_VAR(rcu_ptr);
+                               WRITE_CACHED_VAR(rcu_ptr, cur_data);
+                       }
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_XCHG_PTR);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_WMB      /* No dependency on
+                                                        * WRITE_DATA because we
+                                                        * write to a
+                                                        * different location. */
+                                 | WRITE_PROC_SECOND_MB
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_FREE) ->
+                       WRITE_CACHED_VAR(rcu_data[old_data], POISON);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_FREE);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+               /*
+                * Note : Promela model adds implicit serialization of the
+                * WRITE_FREE instruction. Normally, it would be permitted to
+                * spill on the next loop execution. Given the validation we do
+                * checks for the data entry read to be poisoned, it's ok if
+                * we do not check "late arriving" memory poisoning.
+                */
+       :: 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
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(rcu_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       ptr_read_first[i] = 1;
+                       ptr_read_second[i] = 1;
+                       data_read_first[i] = WINE;
+                       data_read_second[i] = WINE;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               INIT_CACHED_VAR(rcu_data[0], WINE, j);
+               i = 1;
+               do
+               :: i < SLAB_SIZE ->
+                       INIT_CACHED_VAR(rcu_data[i], POISON, j);
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free.spin.input.trail b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free.spin.input.trail
new file mode 100644 (file)
index 0000000..011045f
--- /dev/null
@@ -0,0 +1,2598 @@
+-2:3:-2
+-4:-4:-4
+1:0:4863
+2:3:4786
+3:3:4789
+4:3:4789
+5:3:4792
+6:3:4800
+7:3:4800
+8:3:4803
+9:3:4809
+10:3:4813
+11:3:4813
+12:3:4816
+13:3:4823
+14:3:4831
+15:3:4831
+16:3:4834
+17:3:4840
+18:3:4844
+19:3:4844
+20:3:4847
+21:3:4853
+22:3:4857
+23:3:4858
+24:0:4863
+25:3:4860
+26:0:4863
+27:2:3279
+28:0:4863
+29:2:3285
+30:0:4863
+31:2:3286
+32:0:4863
+33:2:3289
+34:2:3293
+35:2:3294
+36:2:3302
+37:2:3303
+38:2:3307
+39:2:3308
+40:2:3316
+41:2:3321
+42:2:3325
+43:2:3326
+44:2:3334
+45:2:3335
+46:2:3339
+47:2:3340
+48:2:3334
+49:2:3335
+50:2:3339
+51:2:3340
+52:2:3348
+53:2:3353
+54:2:3354
+55:2:3365
+56:2:3366
+57:2:3367
+58:2:3378
+59:2:3383
+60:2:3384
+61:2:3395
+62:2:3396
+63:2:3397
+64:2:3395
+65:2:3396
+66:2:3397
+67:2:3408
+68:2:3412
+69:0:4863
+70:2:3415
+71:0:4863
+72:2:3421
+73:2:3422
+74:2:3426
+75:2:3430
+76:2:3431
+77:2:3435
+78:2:3443
+79:2:3444
+80:2:3448
+81:2:3452
+82:2:3453
+83:2:3448
+84:2:3449
+85:2:3457
+86:2:3461
+87:0:4863
+88:2:3464
+89:0:4863
+90:2:3465
+91:2:3469
+92:2:3470
+93:2:3478
+94:2:3479
+95:2:3483
+96:2:3484
+97:2:3492
+98:2:3497
+99:2:3501
+100:2:3502
+101:2:3510
+102:2:3511
+103:2:3515
+104:2:3516
+105:2:3510
+106:2:3511
+107:2:3515
+108:2:3516
+109:2:3524
+110:2:3529
+111:2:3530
+112:2:3541
+113:2:3542
+114:2:3543
+115:2:3554
+116:2:3559
+117:2:3560
+118:2:3571
+119:2:3572
+120:2:3573
+121:2:3571
+122:2:3572
+123:2:3573
+124:2:3584
+125:2:3588
+126:0:4863
+127:2:3591
+128:0:4863
+129:2:3594
+130:2:3598
+131:2:3599
+132:2:3607
+133:2:3608
+134:2:3612
+135:2:3613
+136:2:3621
+137:2:3626
+138:2:3627
+139:2:3639
+140:2:3640
+141:2:3644
+142:2:3645
+143:2:3639
+144:2:3640
+145:2:3644
+146:2:3645
+147:2:3653
+148:2:3658
+149:2:3659
+150:2:3670
+151:2:3671
+152:2:3672
+153:2:3683
+154:2:3688
+155:2:3689
+156:2:3700
+157:2:3701
+158:2:3702
+159:2:3700
+160:2:3701
+161:2:3702
+162:2:3713
+163:2:3717
+164:0:4863
+165:2:3720
+166:0:4863
+167:2:3721
+168:0:4863
+169:2:3722
+170:0:4863
+171:2:4423
+172:2:4424
+173:2:4428
+174:2:4432
+175:2:4433
+176:2:4437
+177:2:4445
+178:2:4446
+179:2:4450
+180:2:4454
+181:2:4455
+182:2:4450
+183:2:4454
+184:2:4455
+185:2:4459
+186:2:4466
+187:2:4473
+188:2:4474
+189:2:4481
+190:2:4486
+191:2:4493
+192:2:4494
+193:2:4493
+194:2:4494
+195:2:4501
+196:2:4505
+197:0:4863
+198:2:3724
+199:2:4401
+200:0:4863
+201:2:3721
+202:0:4863
+203:2:3725
+204:0:4863
+205:2:3721
+206:0:4863
+207:2:3728
+208:2:3729
+209:2:3733
+210:2:3734
+211:2:3742
+212:2:3743
+213:2:3747
+214:2:3748
+215:2:3756
+216:2:3761
+217:2:3765
+218:2:3766
+219:2:3774
+220:2:3775
+221:2:3779
+222:2:3780
+223:2:3774
+224:2:3775
+225:2:3779
+226:2:3780
+227:2:3788
+228:2:3793
+229:2:3794
+230:2:3805
+231:2:3806
+232:2:3807
+233:2:3818
+234:2:3823
+235:2:3824
+236:2:3835
+237:2:3836
+238:2:3837
+239:2:3835
+240:2:3836
+241:2:3837
+242:2:3848
+243:2:3855
+244:0:4863
+245:2:3721
+246:0:4863
+247:2:3859
+248:2:3860
+249:2:3861
+250:2:3873
+251:2:3874
+252:2:3878
+253:2:3879
+254:2:3887
+255:2:3892
+256:2:3896
+257:2:3897
+258:2:3905
+259:2:3906
+260:2:3910
+261:2:3911
+262:2:3905
+263:2:3906
+264:2:3910
+265:2:3911
+266:2:3919
+267:2:3924
+268:2:3925
+269:2:3936
+270:2:3937
+271:2:3938
+272:2:3949
+273:2:3954
+274:2:3955
+275:2:3966
+276:2:3967
+277:2:3968
+278:2:3966
+279:2:3967
+280:2:3968
+281:2:3979
+282:2:3990
+283:2:3991
+284:0:4863
+285:2:3721
+286:0:4863
+287:2:3997
+288:2:3998
+289:2:4002
+290:2:4003
+291:2:4011
+292:2:4012
+293:2:4016
+294:2:4017
+295:2:4025
+296:2:4030
+297:2:4034
+298:2:4035
+299:2:4043
+300:2:4044
+301:2:4048
+302:2:4049
+303:2:4043
+304:2:4044
+305:2:4048
+306:2:4049
+307:2:4057
+308:2:4062
+309:2:4063
+310:2:4074
+311:2:4075
+312:2:4076
+313:2:4087
+314:2:4092
+315:2:4093
+316:2:4104
+317:2:4105
+318:2:4106
+319:2:4104
+320:2:4105
+321:2:4106
+322:2:4117
+323:0:4863
+324:2:3721
+325:0:4863
+326:2:4126
+327:2:4127
+328:2:4131
+329:2:4132
+330:2:4140
+331:2:4141
+332:2:4145
+333:2:4146
+334:2:4154
+335:2:4159
+336:2:4163
+337:2:4164
+338:2:4172
+339:2:4173
+340:2:4177
+341:2:4178
+342:2:4172
+343:2:4173
+344:2:4177
+345:2:4178
+346:2:4186
+347:2:4191
+348:2:4192
+349:2:4203
+350:2:4204
+351:2:4205
+352:2:4216
+353:2:4221
+354:2:4222
+355:2:4233
+356:2:4234
+357:2:4235
+358:2:4233
+359:2:4234
+360:2:4235
+361:2:4246
+362:2:4253
+363:0:4863
+364:2:3721
+365:0:4863
+366:2:4257
+367:2:4258
+368:2:4259
+369:2:4271
+370:2:4272
+371:2:4276
+372:2:4277
+373:2:4285
+374:2:4290
+375:2:4294
+376:2:4295
+377:2:4303
+378:2:4304
+379:2:4308
+380:2:4309
+381:2:4303
+382:2:4304
+383:2:4308
+384:2:4309
+385:2:4317
+386:2:4322
+387:2:4323
+388:2:4334
+389:2:4335
+390:2:4336
+391:2:4347
+392:2:4352
+393:2:4353
+394:2:4364
+395:2:4365
+396:2:4366
+397:2:4364
+398:2:4365
+399:2:4366
+400:2:4377
+401:2:4387
+402:2:4388
+403:0:4863
+404:2:3721
+405:0:4863
+406:2:4394
+407:0:4863
+408:2:4696
+409:2:4697
+410:2:4701
+411:2:4705
+412:2:4706
+413:2:4710
+414:2:4718
+415:2:4719
+416:2:4723
+417:2:4727
+418:2:4728
+419:2:4723
+420:2:4727
+421:2:4728
+422:2:4732
+423:2:4739
+424:2:4746
+425:2:4747
+426:2:4754
+427:2:4759
+428:2:4766
+429:2:4767
+430:2:4766
+431:2:4767
+432:2:4774
+433:2:4778
+434:0:4863
+435:2:4396
+436:2:4401
+437:0:4863
+438:2:3721
+439:0:4863
+440:2:4397
+441:0:4863
+442:2:4405
+443:0:4863
+444:2:4406
+445:0:4863
+446:2:3286
+447:0:4863
+448:2:3289
+449:2:3293
+450:2:3294
+451:2:3302
+452:2:3303
+453:2:3307
+454:2:3308
+455:2:3316
+456:2:3321
+457:2:3325
+458:2:3326
+459:2:3334
+460:2:3335
+461:2:3336
+462:2:3334
+463:2:3335
+464:2:3339
+465:2:3340
+466:2:3348
+467:2:3353
+468:2:3354
+469:2:3365
+470:2:3366
+471:2:3367
+472:2:3378
+473:2:3383
+474:2:3384
+475:2:3395
+476:2:3396
+477:2:3397
+478:2:3395
+479:2:3396
+480:2:3397
+481:2:3408
+482:2:3412
+483:0:4863
+484:2:3415
+485:0:4863
+486:2:3421
+487:2:3422
+488:2:3426
+489:2:3430
+490:2:3431
+491:2:3435
+492:2:3443
+493:2:3444
+494:2:3448
+495:2:3449
+496:2:3448
+497:2:3452
+498:2:3453
+499:2:3457
+500:2:3461
+501:0:4863
+502:2:3464
+503:0:4863
+504:2:3465
+505:2:3469
+506:2:3470
+507:2:3478
+508:2:3479
+509:2:3483
+510:2:3484
+511:2:3492
+512:2:3497
+513:2:3501
+514:2:3502
+515:2:3510
+516:2:3511
+517:2:3515
+518:2:3516
+519:2:3510
+520:2:3511
+521:2:3515
+522:2:3516
+523:2:3524
+524:2:3529
+525:2:3530
+526:2:3541
+527:2:3542
+528:2:3543
+529:2:3554
+530:2:3559
+531:2:3560
+532:2:3571
+533:2:3572
+534:2:3573
+535:2:3571
+536:2:3572
+537:2:3573
+538:2:3584
+539:2:3588
+540:0:4863
+541:2:3591
+542:0:4863
+543:2:3594
+544:2:3598
+545:2:3599
+546:2:3607
+547:2:3608
+548:2:3612
+549:2:3613
+550:2:3621
+551:2:3626
+552:2:3627
+553:2:3639
+554:2:3640
+555:2:3644
+556:2:3645
+557:2:3639
+558:2:3640
+559:2:3644
+560:2:3645
+561:2:3653
+562:2:3658
+563:2:3659
+564:2:3670
+565:2:3671
+566:2:3672
+567:2:3683
+568:2:3688
+569:2:3689
+570:2:3700
+571:2:3701
+572:2:3702
+573:2:3700
+574:2:3701
+575:2:3702
+576:2:3713
+577:2:3717
+578:0:4863
+579:2:3720
+580:0:4863
+581:2:3721
+582:0:4863
+583:2:3722
+584:0:4863
+585:2:4423
+586:2:4424
+587:2:4428
+588:2:4432
+589:2:4433
+590:2:4437
+591:2:4445
+592:2:4446
+593:2:4450
+594:2:4454
+595:2:4455
+596:2:4450
+597:2:4454
+598:2:4455
+599:2:4459
+600:2:4466
+601:2:4473
+602:2:4474
+603:2:4481
+604:2:4486
+605:2:4493
+606:2:4494
+607:2:4493
+608:2:4494
+609:2:4501
+610:2:4505
+611:0:4863
+612:2:3724
+613:2:4401
+614:0:4863
+615:2:3721
+616:0:4863
+617:2:3725
+618:0:4863
+619:2:3721
+620:0:4863
+621:2:3728
+622:2:3729
+623:2:3733
+624:2:3734
+625:2:3742
+626:2:3743
+627:2:3747
+628:2:3748
+629:2:3756
+630:2:3761
+631:2:3765
+632:2:3766
+633:2:3774
+634:2:3775
+635:2:3779
+636:2:3780
+637:2:3774
+638:2:3775
+639:2:3779
+640:2:3780
+641:2:3788
+642:2:3793
+643:2:3794
+644:2:3805
+645:2:3806
+646:2:3807
+647:2:3818
+648:2:3823
+649:2:3824
+650:2:3835
+651:2:3836
+652:2:3837
+653:2:3835
+654:2:3836
+655:2:3837
+656:2:3848
+657:2:3855
+658:0:4863
+659:2:3721
+660:0:4863
+661:2:3859
+662:2:3860
+663:2:3861
+664:2:3873
+665:2:3874
+666:2:3878
+667:2:3879
+668:2:3887
+669:2:3892
+670:2:3896
+671:2:3897
+672:2:3905
+673:2:3906
+674:2:3910
+675:2:3911
+676:2:3905
+677:2:3906
+678:2:3910
+679:2:3911
+680:2:3919
+681:2:3924
+682:2:3925
+683:2:3936
+684:2:3937
+685:2:3938
+686:2:3949
+687:2:3954
+688:2:3955
+689:2:3966
+690:2:3967
+691:2:3968
+692:2:3966
+693:2:3967
+694:2:3968
+695:2:3979
+696:2:3990
+697:2:3991
+698:0:4863
+699:2:3721
+700:0:4863
+701:2:3997
+702:2:3998
+703:2:4002
+704:2:4003
+705:2:4011
+706:2:4012
+707:2:4016
+708:2:4017
+709:2:4025
+710:2:4030
+711:2:4034
+712:2:4035
+713:2:4043
+714:2:4044
+715:2:4048
+716:2:4049
+717:2:4043
+718:2:4044
+719:2:4048
+720:2:4049
+721:2:4057
+722:2:4062
+723:2:4063
+724:2:4074
+725:2:4075
+726:2:4076
+727:2:4087
+728:2:4092
+729:2:4093
+730:2:4104
+731:2:4105
+732:2:4106
+733:2:4104
+734:2:4105
+735:2:4106
+736:2:4117
+737:0:4863
+738:2:3721
+739:0:4863
+740:2:4126
+741:2:4127
+742:2:4131
+743:2:4132
+744:2:4140
+745:2:4141
+746:2:4145
+747:2:4146
+748:2:4154
+749:2:4159
+750:2:4163
+751:2:4164
+752:2:4172
+753:2:4173
+754:2:4177
+755:2:4178
+756:2:4172
+757:2:4173
+758:2:4177
+759:2:4178
+760:2:4186
+761:2:4191
+762:2:4192
+763:2:4203
+764:2:4204
+765:2:4205
+766:2:4216
+767:2:4221
+768:2:4222
+769:2:4233
+770:2:4234
+771:2:4235
+772:2:4233
+773:2:4234
+774:2:4235
+775:2:4246
+776:2:4253
+777:0:4863
+778:2:3721
+779:0:4863
+780:2:4257
+781:2:4258
+782:2:4259
+783:2:4271
+784:2:4272
+785:2:4276
+786:2:4277
+787:2:4285
+788:2:4290
+789:2:4294
+790:2:4295
+791:2:4303
+792:2:4304
+793:2:4308
+794:2:4309
+795:2:4303
+796:2:4304
+797:2:4308
+798:2:4309
+799:2:4317
+800:2:4322
+801:2:4323
+802:2:4334
+803:2:4335
+804:2:4336
+805:2:4347
+806:2:4352
+807:2:4353
+808:2:4364
+809:2:4365
+810:2:4366
+811:2:4364
+812:2:4365
+813:2:4366
+814:2:4377
+815:2:4387
+816:2:4388
+817:0:4863
+818:2:3721
+819:0:4863
+820:2:4394
+821:0:4863
+822:2:4696
+823:2:4697
+824:2:4701
+825:2:4705
+826:2:4706
+827:2:4710
+828:2:4718
+829:2:4719
+830:2:4723
+831:2:4727
+832:2:4728
+833:2:4723
+834:2:4727
+835:2:4728
+836:2:4732
+837:2:4739
+838:2:4746
+839:2:4747
+840:2:4754
+841:2:4759
+842:2:4766
+843:2:4767
+844:2:4766
+845:2:4767
+846:2:4774
+847:2:4778
+848:0:4863
+849:2:4396
+850:2:4401
+851:0:4863
+852:2:3721
+853:0:4863
+854:2:4397
+855:0:4863
+856:2:4405
+857:0:4863
+858:2:4406
+859:0:4863
+860:2:3286
+861:0:4863
+862:2:3289
+863:2:3293
+864:2:3294
+865:2:3302
+866:2:3303
+867:2:3307
+868:2:3308
+869:2:3316
+870:2:3321
+871:2:3325
+872:2:3326
+873:2:3334
+874:2:3335
+875:2:3339
+876:2:3340
+877:2:3334
+878:2:3335
+879:2:3336
+880:2:3348
+881:2:3353
+882:2:3354
+883:2:3365
+884:2:3366
+885:2:3367
+886:2:3378
+887:2:3383
+888:2:3384
+889:2:3395
+890:2:3396
+891:2:3397
+892:2:3395
+893:2:3396
+894:2:3397
+895:2:3408
+896:2:3412
+897:0:4863
+898:2:3415
+899:0:4863
+900:2:3421
+901:2:3422
+902:2:3426
+903:2:3430
+904:2:3431
+905:2:3435
+906:2:3443
+907:2:3444
+908:2:3448
+909:2:3452
+910:2:3453
+911:2:3448
+912:2:3449
+913:2:3457
+914:2:3461
+915:0:4863
+916:2:3464
+917:0:4863
+918:2:3465
+919:2:3469
+920:2:3470
+921:2:3478
+922:2:3479
+923:2:3483
+924:2:3484
+925:2:3492
+926:2:3497
+927:2:3501
+928:2:3502
+929:2:3510
+930:2:3511
+931:2:3515
+932:2:3516
+933:2:3510
+934:2:3511
+935:2:3515
+936:2:3516
+937:2:3524
+938:2:3529
+939:2:3530
+940:2:3541
+941:2:3542
+942:2:3543
+943:2:3554
+944:2:3559
+945:2:3560
+946:2:3571
+947:2:3572
+948:2:3573
+949:2:3571
+950:2:3572
+951:2:3573
+952:2:3584
+953:2:3588
+954:0:4863
+955:2:3591
+956:0:4863
+957:2:3594
+958:2:3598
+959:2:3599
+960:2:3607
+961:2:3608
+962:2:3612
+963:2:3613
+964:2:3621
+965:2:3626
+966:2:3627
+967:2:3639
+968:2:3640
+969:2:3644
+970:2:3645
+971:2:3639
+972:2:3640
+973:2:3644
+974:2:3645
+975:2:3653
+976:2:3658
+977:2:3659
+978:2:3670
+979:2:3671
+980:2:3672
+981:2:3683
+982:2:3688
+983:2:3689
+984:2:3700
+985:2:3701
+986:2:3702
+987:2:3700
+988:2:3701
+989:2:3702
+990:2:3713
+991:2:3717
+992:0:4863
+993:2:3720
+994:0:4863
+995:2:3721
+996:0:4863
+997:2:3722
+998:0:4863
+999:2:4423
+1000:2:4424
+1001:2:4428
+1002:2:4432
+1003:2:4433
+1004:2:4437
+1005:2:4445
+1006:2:4446
+1007:2:4450
+1008:2:4454
+1009:2:4455
+1010:2:4450
+1011:2:4454
+1012:2:4455
+1013:2:4459
+1014:2:4466
+1015:2:4473
+1016:2:4474
+1017:2:4481
+1018:2:4486
+1019:2:4493
+1020:2:4494
+1021:2:4493
+1022:2:4494
+1023:2:4501
+1024:2:4505
+1025:0:4863
+1026:2:3724
+1027:2:4401
+1028:0:4863
+1029:2:3721
+1030:0:4863
+1031:2:3725
+1032:0:4863
+1033:2:3721
+1034:0:4863
+1035:2:3728
+1036:2:3729
+1037:2:3733
+1038:2:3734
+1039:2:3742
+1040:2:3743
+1041:2:3747
+1042:2:3748
+1043:2:3756
+1044:2:3761
+1045:2:3765
+1046:2:3766
+1047:2:3774
+1048:2:3775
+1049:2:3779
+1050:2:3780
+1051:2:3774
+1052:2:3775
+1053:2:3779
+1054:2:3780
+1055:2:3788
+1056:2:3793
+1057:2:3794
+1058:2:3805
+1059:2:3806
+1060:2:3807
+1061:2:3818
+1062:2:3823
+1063:2:3824
+1064:2:3835
+1065:2:3836
+1066:2:3837
+1067:2:3835
+1068:2:3836
+1069:2:3837
+1070:2:3848
+1071:2:3855
+1072:0:4863
+1073:2:3721
+1074:0:4863
+1075:2:3859
+1076:2:3860
+1077:2:3861
+1078:2:3873
+1079:2:3874
+1080:2:3878
+1081:2:3879
+1082:2:3887
+1083:2:3892
+1084:2:3896
+1085:2:3897
+1086:2:3905
+1087:2:3906
+1088:2:3910
+1089:2:3911
+1090:2:3905
+1091:2:3906
+1092:2:3910
+1093:2:3911
+1094:2:3919
+1095:2:3924
+1096:2:3925
+1097:2:3936
+1098:2:3937
+1099:2:3938
+1100:2:3949
+1101:2:3954
+1102:2:3955
+1103:2:3966
+1104:2:3967
+1105:2:3968
+1106:2:3966
+1107:2:3967
+1108:2:3968
+1109:2:3979
+1110:2:3990
+1111:2:3991
+1112:0:4863
+1113:2:3721
+1114:0:4863
+1115:2:3997
+1116:2:3998
+1117:2:4002
+1118:2:4003
+1119:2:4011
+1120:2:4012
+1121:2:4016
+1122:2:4017
+1123:2:4025
+1124:2:4030
+1125:2:4034
+1126:2:4035
+1127:2:4043
+1128:2:4044
+1129:2:4048
+1130:2:4049
+1131:2:4043
+1132:2:4044
+1133:2:4048
+1134:2:4049
+1135:2:4057
+1136:2:4062
+1137:2:4063
+1138:2:4074
+1139:2:4075
+1140:2:4076
+1141:2:4087
+1142:2:4092
+1143:2:4093
+1144:2:4104
+1145:2:4105
+1146:2:4106
+1147:2:4104
+1148:2:4105
+1149:2:4106
+1150:2:4117
+1151:0:4863
+1152:2:3721
+1153:0:4863
+1154:2:4126
+1155:2:4127
+1156:2:4131
+1157:2:4132
+1158:2:4140
+1159:2:4141
+1160:2:4145
+1161:2:4146
+1162:2:4154
+1163:2:4159
+1164:2:4163
+1165:2:4164
+1166:2:4172
+1167:2:4173
+1168:2:4177
+1169:2:4178
+1170:2:4172
+1171:2:4173
+1172:2:4177
+1173:2:4178
+1174:2:4186
+1175:2:4191
+1176:2:4192
+1177:2:4203
+1178:2:4204
+1179:2:4205
+1180:2:4216
+1181:2:4221
+1182:2:4222
+1183:2:4233
+1184:2:4234
+1185:2:4235
+1186:2:4233
+1187:2:4234
+1188:2:4235
+1189:2:4246
+1190:2:4253
+1191:0:4863
+1192:2:3721
+1193:0:4863
+1194:2:4257
+1195:2:4258
+1196:2:4259
+1197:2:4271
+1198:2:4272
+1199:2:4276
+1200:2:4277
+1201:2:4285
+1202:2:4290
+1203:2:4294
+1204:2:4295
+1205:2:4303
+1206:2:4304
+1207:2:4308
+1208:2:4309
+1209:2:4303
+1210:2:4304
+1211:2:4308
+1212:2:4309
+1213:2:4317
+1214:2:4322
+1215:2:4323
+1216:2:4334
+1217:2:4335
+1218:2:4336
+1219:2:4347
+1220:2:4352
+1221:2:4353
+1222:2:4364
+1223:2:4365
+1224:2:4366
+1225:2:4364
+1226:2:4365
+1227:2:4366
+1228:2:4377
+1229:2:4387
+1230:2:4388
+1231:0:4863
+1232:2:3721
+1233:0:4863
+1234:2:4394
+1235:0:4863
+1236:2:4696
+1237:2:4697
+1238:2:4701
+1239:2:4705
+1240:2:4706
+1241:2:4710
+1242:2:4718
+1243:2:4719
+1244:2:4723
+1245:2:4727
+1246:2:4728
+1247:2:4723
+1248:2:4727
+1249:2:4728
+1250:2:4732
+1251:2:4739
+1252:2:4746
+1253:2:4747
+1254:2:4754
+1255:2:4759
+1256:2:4766
+1257:2:4767
+1258:2:4766
+1259:2:4767
+1260:2:4774
+1261:2:4778
+1262:0:4863
+1263:2:4396
+1264:2:4401
+1265:0:4863
+1266:2:3721
+1267:0:4863
+1268:2:4397
+1269:0:4863
+1270:2:4405
+1271:0:4863
+1272:2:4406
+1273:0:4863
+1274:2:3286
+1275:0:4863
+1276:2:3289
+1277:2:3293
+1278:2:3294
+1279:2:3302
+1280:2:3303
+1281:2:3307
+1282:2:3308
+1283:2:3316
+1284:2:3321
+1285:2:3325
+1286:2:3326
+1287:2:3334
+1288:2:3335
+1289:2:3336
+1290:2:3334
+1291:2:3335
+1292:2:3339
+1293:2:3340
+1294:2:3348
+1295:2:3353
+1296:2:3354
+1297:2:3365
+1298:2:3366
+1299:2:3367
+1300:2:3378
+1301:2:3383
+1302:2:3384
+1303:2:3395
+1304:2:3396
+1305:2:3397
+1306:2:3395
+1307:2:3396
+1308:2:3397
+1309:2:3408
+1310:2:3412
+1311:0:4863
+1312:2:3415
+1313:0:4863
+1314:2:3421
+1315:2:3422
+1316:2:3426
+1317:2:3430
+1318:2:3431
+1319:2:3435
+1320:2:3443
+1321:2:3444
+1322:2:3448
+1323:2:3449
+1324:2:3448
+1325:2:3452
+1326:2:3453
+1327:2:3457
+1328:2:3461
+1329:0:4863
+1330:2:3464
+1331:0:4863
+1332:2:3465
+1333:2:3469
+1334:2:3470
+1335:2:3478
+1336:2:3479
+1337:2:3483
+1338:2:3484
+1339:2:3492
+1340:2:3497
+1341:2:3501
+1342:2:3502
+1343:2:3510
+1344:2:3511
+1345:2:3515
+1346:2:3516
+1347:2:3510
+1348:2:3511
+1349:2:3515
+1350:2:3516
+1351:2:3524
+1352:2:3529
+1353:2:3530
+1354:2:3541
+1355:2:3542
+1356:2:3543
+1357:2:3554
+1358:2:3559
+1359:2:3560
+1360:2:3571
+1361:2:3572
+1362:2:3573
+1363:2:3571
+1364:2:3572
+1365:2:3573
+1366:2:3584
+1367:2:3588
+1368:0:4863
+1369:2:3591
+1370:0:4863
+1371:2:3594
+1372:2:3598
+1373:2:3599
+1374:2:3607
+1375:2:3608
+1376:2:3612
+1377:2:3613
+1378:2:3621
+1379:2:3626
+1380:2:3627
+1381:2:3639
+1382:2:3640
+1383:2:3644
+1384:2:3645
+1385:2:3639
+1386:2:3640
+1387:2:3644
+1388:2:3645
+1389:2:3653
+1390:2:3658
+1391:2:3659
+1392:2:3670
+1393:2:3671
+1394:2:3672
+1395:2:3683
+1396:2:3688
+1397:2:3689
+1398:2:3700
+1399:2:3701
+1400:2:3702
+1401:2:3700
+1402:2:3701
+1403:2:3702
+1404:2:3713
+1405:2:3717
+1406:0:4863
+1407:2:3720
+1408:0:4863
+1409:2:3721
+1410:0:4863
+1411:2:3722
+1412:0:4863
+1413:2:4423
+1414:2:4424
+1415:2:4428
+1416:2:4432
+1417:2:4433
+1418:2:4437
+1419:2:4445
+1420:2:4446
+1421:2:4450
+1422:2:4454
+1423:2:4455
+1424:2:4450
+1425:2:4454
+1426:2:4455
+1427:2:4459
+1428:2:4466
+1429:2:4473
+1430:2:4474
+1431:2:4481
+1432:2:4486
+1433:2:4493
+1434:2:4494
+1435:2:4493
+1436:2:4494
+1437:2:4501
+1438:2:4505
+1439:0:4863
+1440:2:3724
+1441:2:4401
+1442:0:4863
+1443:2:3721
+1444:0:4863
+1445:2:3725
+1446:0:4863
+1447:2:3721
+1448:0:4863
+1449:2:3728
+1450:2:3729
+1451:2:3733
+1452:2:3734
+1453:2:3742
+1454:2:3743
+1455:2:3747
+1456:2:3748
+1457:2:3756
+1458:2:3761
+1459:2:3765
+1460:2:3766
+1461:2:3774
+1462:2:3775
+1463:2:3779
+1464:2:3780
+1465:2:3774
+1466:2:3775
+1467:2:3779
+1468:2:3780
+1469:2:3788
+1470:2:3793
+1471:2:3794
+1472:2:3805
+1473:2:3806
+1474:2:3807
+1475:2:3818
+1476:2:3823
+1477:2:3824
+1478:2:3835
+1479:2:3836
+1480:2:3837
+1481:2:3835
+1482:2:3836
+1483:2:3837
+1484:2:3848
+1485:2:3855
+1486:0:4863
+1487:2:3721
+1488:0:4863
+1489:2:3859
+1490:2:3860
+1491:2:3861
+1492:2:3873
+1493:2:3874
+1494:2:3878
+1495:2:3879
+1496:2:3887
+1497:2:3892
+1498:2:3896
+1499:2:3897
+1500:2:3905
+1501:2:3906
+1502:2:3910
+1503:2:3911
+1504:2:3905
+1505:2:3906
+1506:2:3910
+1507:2:3911
+1508:2:3919
+1509:2:3924
+1510:2:3925
+1511:2:3936
+1512:2:3937
+1513:2:3938
+1514:2:3949
+1515:2:3954
+1516:2:3955
+1517:2:3966
+1518:2:3967
+1519:2:3968
+1520:2:3966
+1521:2:3967
+1522:2:3968
+1523:2:3979
+1524:2:3990
+1525:2:3991
+1526:0:4863
+1527:2:3721
+1528:0:4863
+1529:2:3997
+1530:2:3998
+1531:2:4002
+1532:2:4003
+1533:2:4011
+1534:2:4012
+1535:2:4016
+1536:2:4017
+1537:2:4025
+1538:2:4030
+1539:2:4034
+1540:2:4035
+1541:2:4043
+1542:2:4044
+1543:2:4048
+1544:2:4049
+1545:2:4043
+1546:2:4044
+1547:2:4048
+1548:2:4049
+1549:2:4057
+1550:2:4062
+1551:2:4063
+1552:2:4074
+1553:2:4075
+1554:2:4076
+1555:2:4087
+1556:2:4092
+1557:2:4093
+1558:2:4104
+1559:2:4105
+1560:2:4106
+1561:2:4104
+1562:2:4105
+1563:2:4106
+1564:2:4117
+1565:0:4863
+1566:2:3721
+1567:0:4863
+1568:2:4126
+1569:2:4127
+1570:2:4131
+1571:2:4132
+1572:2:4140
+1573:2:4141
+1574:2:4145
+1575:2:4146
+1576:2:4154
+1577:2:4159
+1578:2:4163
+1579:2:4164
+1580:2:4172
+1581:2:4173
+1582:2:4177
+1583:2:4178
+1584:2:4172
+1585:2:4173
+1586:2:4177
+1587:2:4178
+1588:2:4186
+1589:2:4191
+1590:2:4192
+1591:2:4203
+1592:2:4204
+1593:2:4205
+1594:2:4216
+1595:2:4221
+1596:2:4222
+1597:2:4233
+1598:2:4234
+1599:2:4235
+1600:2:4233
+1601:2:4234
+1602:2:4235
+1603:2:4246
+1604:2:4253
+1605:0:4863
+1606:2:3721
+1607:0:4863
+1608:2:4257
+1609:2:4258
+1610:2:4259
+1611:2:4271
+1612:2:4272
+1613:2:4276
+1614:2:4277
+1615:2:4285
+1616:2:4290
+1617:2:4294
+1618:2:4295
+1619:2:4303
+1620:2:4304
+1621:2:4308
+1622:2:4309
+1623:2:4303
+1624:2:4304
+1625:2:4308
+1626:2:4309
+1627:2:4317
+1628:2:4322
+1629:2:4323
+1630:2:4334
+1631:2:4335
+1632:2:4336
+1633:2:4347
+1634:2:4352
+1635:2:4353
+1636:2:4364
+1637:2:4365
+1638:2:4366
+1639:2:4364
+1640:2:4365
+1641:2:4366
+1642:2:4377
+1643:2:4387
+1644:2:4388
+1645:0:4863
+1646:2:3721
+1647:0:4863
+1648:2:4394
+1649:0:4863
+1650:2:4696
+1651:2:4697
+1652:2:4701
+1653:2:4705
+1654:2:4706
+1655:2:4710
+1656:2:4718
+1657:2:4719
+1658:2:4723
+1659:2:4727
+1660:2:4728
+1661:2:4723
+1662:2:4727
+1663:2:4728
+1664:2:4732
+1665:2:4739
+1666:2:4746
+1667:2:4747
+1668:2:4754
+1669:2:4759
+1670:2:4766
+1671:2:4767
+1672:2:4766
+1673:2:4767
+1674:2:4774
+1675:2:4778
+1676:0:4863
+1677:2:4396
+1678:2:4401
+1679:0:4863
+1680:2:3721
+1681:0:4863
+1682:2:4397
+1683:0:4863
+1684:2:4405
+1685:0:4863
+1686:2:4406
+1687:0:4863
+1688:2:3286
+1689:0:4863
+1690:2:3289
+1691:2:3293
+1692:2:3294
+1693:2:3302
+1694:2:3303
+1695:2:3307
+1696:2:3308
+1697:2:3316
+1698:2:3321
+1699:2:3325
+1700:2:3326
+1701:2:3334
+1702:2:3335
+1703:2:3339
+1704:2:3340
+1705:2:3334
+1706:2:3335
+1707:2:3336
+1708:2:3348
+1709:2:3353
+1710:2:3354
+1711:2:3365
+1712:2:3366
+1713:2:3367
+1714:2:3378
+1715:2:3383
+1716:2:3384
+1717:2:3395
+1718:2:3396
+1719:2:3397
+1720:2:3395
+1721:2:3396
+1722:2:3397
+1723:2:3408
+1724:2:3412
+1725:0:4863
+1726:2:3415
+1727:0:4863
+1728:1:2
+1729:0:4863
+1730:1:8
+1731:0:4863
+1732:1:9
+1733:0:4863
+1734:1:10
+1735:0:4863
+1736:1:11
+1737:0:4863
+1738:1:12
+1739:1:13
+1740:1:17
+1741:1:18
+1742:1:26
+1743:1:27
+1744:1:31
+1745:1:32
+1746:1:40
+1747:1:45
+1748:1:49
+1749:1:50
+1750:1:58
+1751:1:59
+1752:1:63
+1753:1:64
+1754:1:58
+1755:1:59
+1756:1:63
+1757:1:64
+1758:1:72
+1759:1:77
+1760:1:78
+1761:1:89
+1762:1:90
+1763:1:91
+1764:1:102
+1765:1:107
+1766:1:108
+1767:1:119
+1768:1:120
+1769:1:121
+1770:1:119
+1771:1:120
+1772:1:121
+1773:1:132
+1774:0:4863
+1775:1:11
+1776:0:4863
+1777:1:141
+1778:1:142
+1779:0:4863
+1780:1:11
+1781:0:4863
+1782:1:148
+1783:1:149
+1784:1:153
+1785:1:154
+1786:1:162
+1787:1:163
+1788:1:167
+1789:1:168
+1790:1:176
+1791:1:181
+1792:1:185
+1793:1:186
+1794:1:194
+1795:1:195
+1796:1:199
+1797:1:200
+1798:1:194
+1799:1:195
+1800:1:199
+1801:1:200
+1802:1:208
+1803:1:213
+1804:1:214
+1805:1:225
+1806:1:226
+1807:1:227
+1808:1:238
+1809:1:243
+1810:1:244
+1811:1:255
+1812:1:256
+1813:1:257
+1814:1:255
+1815:1:256
+1816:1:257
+1817:1:268
+1818:0:4863
+1819:1:11
+1820:0:4863
+1821:1:277
+1822:1:278
+1823:1:282
+1824:1:283
+1825:1:291
+1826:1:292
+1827:1:296
+1828:1:297
+1829:1:305
+1830:1:310
+1831:1:314
+1832:1:315
+1833:1:323
+1834:1:324
+1835:1:328
+1836:1:329
+1837:1:323
+1838:1:324
+1839:1:328
+1840:1:329
+1841:1:337
+1842:1:342
+1843:1:343
+1844:1:354
+1845:1:355
+1846:1:356
+1847:1:367
+1848:1:372
+1849:1:373
+1850:1:384
+1851:1:385
+1852:1:386
+1853:1:384
+1854:1:385
+1855:1:386
+1856:1:397
+1857:1:404
+1858:0:4863
+1859:1:11
+1860:0:4863
+1861:1:540
+1862:1:544
+1863:1:545
+1864:1:549
+1865:1:550
+1866:1:558
+1867:1:566
+1868:1:567
+1869:1:571
+1870:1:575
+1871:1:576
+1872:1:571
+1873:1:575
+1874:1:576
+1875:1:580
+1876:1:587
+1877:1:594
+1878:1:595
+1879:1:602
+1880:1:607
+1881:1:614
+1882:1:615
+1883:1:614
+1884:1:615
+1885:1:622
+1886:0:4863
+1887:1:11
+1888:0:4863
+1889:2:3421
+1890:2:3422
+1891:2:3426
+1892:2:3430
+1893:2:3431
+1894:2:3435
+1895:2:3443
+1896:2:3444
+1897:2:3448
+1898:2:3452
+1899:2:3453
+1900:2:3448
+1901:2:3449
+1902:2:3457
+1903:2:3461
+1904:0:4863
+1905:2:3464
+1906:0:4863
+1907:2:3465
+1908:2:3469
+1909:2:3470
+1910:2:3478
+1911:2:3479
+1912:2:3483
+1913:2:3484
+1914:2:3492
+1915:2:3497
+1916:2:3501
+1917:2:3502
+1918:2:3510
+1919:2:3511
+1920:2:3515
+1921:2:3516
+1922:2:3510
+1923:2:3511
+1924:2:3515
+1925:2:3516
+1926:2:3524
+1927:2:3529
+1928:2:3530
+1929:2:3541
+1930:2:3542
+1931:2:3543
+1932:2:3554
+1933:2:3559
+1934:2:3560
+1935:2:3571
+1936:2:3572
+1937:2:3573
+1938:2:3571
+1939:2:3572
+1940:2:3573
+1941:2:3584
+1942:2:3588
+1943:0:4863
+1944:2:3591
+1945:0:4863
+1946:2:3594
+1947:2:3598
+1948:2:3599
+1949:2:3607
+1950:2:3608
+1951:2:3612
+1952:2:3613
+1953:2:3621
+1954:2:3626
+1955:2:3627
+1956:2:3639
+1957:2:3640
+1958:2:3644
+1959:2:3645
+1960:2:3639
+1961:2:3640
+1962:2:3644
+1963:2:3645
+1964:2:3653
+1965:2:3658
+1966:2:3659
+1967:2:3670
+1968:2:3671
+1969:2:3672
+1970:2:3683
+1971:2:3688
+1972:2:3689
+1973:2:3700
+1974:2:3701
+1975:2:3702
+1976:2:3700
+1977:2:3701
+1978:2:3702
+1979:2:3713
+1980:2:3717
+1981:0:4863
+1982:2:3720
+1983:0:4863
+1984:2:3721
+1985:0:4863
+1986:2:3722
+1987:0:4863
+1988:2:4423
+1989:2:4424
+1990:2:4428
+1991:2:4432
+1992:2:4433
+1993:2:4437
+1994:2:4445
+1995:2:4446
+1996:2:4450
+1997:2:4454
+1998:2:4455
+1999:2:4450
+2000:2:4454
+2001:2:4455
+2002:2:4459
+2003:2:4466
+2004:2:4473
+2005:2:4474
+2006:2:4481
+2007:2:4486
+2008:2:4493
+2009:2:4494
+2010:2:4493
+2011:2:4494
+2012:2:4501
+2013:2:4505
+2014:0:4863
+2015:2:3724
+2016:2:4401
+2017:0:4863
+2018:2:3721
+2019:0:4863
+2020:2:3725
+2021:0:4863
+2022:2:3721
+2023:0:4863
+2024:2:3728
+2025:2:3729
+2026:2:3733
+2027:2:3734
+2028:2:3742
+2029:2:3743
+2030:2:3747
+2031:2:3748
+2032:2:3756
+2033:2:3761
+2034:2:3765
+2035:2:3766
+2036:2:3774
+2037:2:3775
+2038:2:3779
+2039:2:3780
+2040:2:3774
+2041:2:3775
+2042:2:3779
+2043:2:3780
+2044:2:3788
+2045:2:3793
+2046:2:3794
+2047:2:3805
+2048:2:3806
+2049:2:3807
+2050:2:3818
+2051:2:3823
+2052:2:3824
+2053:2:3835
+2054:2:3836
+2055:2:3837
+2056:2:3835
+2057:2:3836
+2058:2:3837
+2059:2:3848
+2060:2:3855
+2061:0:4863
+2062:2:3721
+2063:0:4863
+2064:2:3859
+2065:2:3860
+2066:2:3861
+2067:2:3873
+2068:2:3874
+2069:2:3878
+2070:2:3879
+2071:2:3887
+2072:2:3892
+2073:2:3896
+2074:2:3897
+2075:2:3905
+2076:2:3906
+2077:2:3910
+2078:2:3911
+2079:2:3905
+2080:2:3906
+2081:2:3910
+2082:2:3911
+2083:2:3919
+2084:2:3924
+2085:2:3925
+2086:2:3936
+2087:2:3937
+2088:2:3938
+2089:2:3949
+2090:2:3954
+2091:2:3955
+2092:2:3966
+2093:2:3967
+2094:2:3968
+2095:2:3966
+2096:2:3967
+2097:2:3968
+2098:2:3979
+2099:2:3988
+2100:0:4863
+2101:2:3721
+2102:0:4863
+2103:2:3994
+2104:0:4863
+2105:2:4514
+2106:2:4515
+2107:2:4519
+2108:2:4523
+2109:2:4524
+2110:2:4528
+2111:2:4536
+2112:2:4537
+2113:2:4541
+2114:2:4545
+2115:2:4546
+2116:2:4541
+2117:2:4545
+2118:2:4546
+2119:2:4550
+2120:2:4557
+2121:2:4564
+2122:2:4565
+2123:2:4572
+2124:2:4577
+2125:2:4584
+2126:2:4585
+2127:2:4584
+2128:2:4585
+2129:2:4592
+2130:2:4596
+2131:0:4863
+2132:2:3996
+2133:2:4401
+2134:0:4863
+2135:2:3721
+2136:0:4863
+2137:1:632
+2138:1:633
+2139:1:637
+2140:1:638
+2141:1:646
+2142:1:647
+2143:1:651
+2144:1:652
+2145:1:660
+2146:1:665
+2147:1:669
+2148:1:670
+2149:1:678
+2150:1:679
+2151:1:683
+2152:1:684
+2153:1:678
+2154:1:679
+2155:1:683
+2156:1:684
+2157:1:692
+2158:1:697
+2159:1:698
+2160:1:709
+2161:1:710
+2162:1:711
+2163:1:722
+2164:1:727
+2165:1:728
+2166:1:739
+2167:1:740
+2168:1:741
+2169:1:739
+2170:1:747
+2171:1:748
+2172:1:752
+2173:0:4863
+2174:1:11
+2175:0:4863
+2176:2:3859
+2177:2:3860
+2178:2:3864
+2179:2:3865
+2180:2:3873
+2181:2:3874
+2182:2:3878
+2183:2:3879
+2184:2:3887
+2185:2:3892
+2186:2:3896
+2187:2:3897
+2188:2:3905
+2189:2:3906
+2190:2:3910
+2191:2:3911
+2192:2:3905
+2193:2:3906
+2194:2:3910
+2195:2:3911
+2196:2:3919
+2197:2:3924
+2198:2:3925
+2199:2:3936
+2200:2:3937
+2201:2:3938
+2202:2:3949
+2203:2:3954
+2204:2:3955
+2205:2:3966
+2206:2:3967
+2207:2:3968
+2208:2:3966
+2209:2:3967
+2210:2:3968
+2211:2:3979
+2212:2:3988
+2213:0:4863
+2214:2:3721
+2215:0:4863
+2216:2:3994
+2217:0:4863
+2218:2:4514
+2219:2:4515
+2220:2:4519
+2221:2:4523
+2222:2:4524
+2223:2:4528
+2224:2:4536
+2225:2:4537
+2226:2:4541
+2227:2:4545
+2228:2:4546
+2229:2:4541
+2230:2:4545
+2231:2:4546
+2232:2:4550
+2233:2:4557
+2234:2:4564
+2235:2:4565
+2236:2:4572
+2237:2:4577
+2238:2:4584
+2239:2:4585
+2240:2:4584
+2241:2:4585
+2242:2:4592
+2243:2:4596
+2244:0:4863
+2245:2:3996
+2246:2:4401
+2247:0:4863
+2248:1:761
+2249:1:764
+2250:1:765
+2251:0:4863
+2252:2:3721
+2253:0:4863
+2254:1:11
+2255:0:4863
+2256:2:3859
+2257:2:3860
+2258:2:3864
+2259:2:3865
+2260:2:3873
+2261:2:3874
+2262:2:3878
+2263:2:3879
+2264:2:3887
+2265:2:3892
+2266:2:3896
+2267:2:3897
+2268:2:3905
+2269:2:3906
+2270:2:3910
+2271:2:3911
+2272:2:3905
+2273:2:3906
+2274:2:3910
+2275:2:3911
+2276:2:3919
+2277:2:3924
+2278:2:3925
+2279:2:3936
+2280:2:3937
+2281:2:3938
+2282:2:3949
+2283:2:3954
+2284:2:3955
+2285:2:3966
+2286:2:3967
+2287:2:3968
+2288:2:3966
+2289:2:3967
+2290:2:3968
+2291:2:3979
+2292:2:3988
+2293:0:4863
+2294:2:3721
+2295:0:4863
+2296:2:3994
+2297:0:4863
+2298:2:4514
+2299:2:4515
+2300:2:4519
+2301:2:4523
+2302:2:4524
+2303:2:4528
+2304:2:4536
+2305:2:4537
+2306:2:4541
+2307:2:4545
+2308:2:4546
+2309:2:4541
+2310:2:4545
+2311:2:4546
+2312:2:4550
+2313:2:4557
+2314:2:4564
+2315:2:4565
+2316:2:4572
+2317:2:4577
+2318:2:4584
+2319:2:4585
+2320:2:4584
+2321:2:4585
+2322:2:4592
+2323:2:4596
+2324:0:4863
+2325:2:3996
+2326:2:4401
+2327:0:4863
+2328:1:1028
+2329:1:1029
+2330:1:1033
+2331:1:1034
+2332:1:1042
+2333:1:1043
+2334:1:1047
+2335:1:1048
+2336:1:1056
+2337:1:1061
+2338:1:1065
+2339:1:1066
+2340:1:1074
+2341:1:1075
+2342:1:1079
+2343:1:1080
+2344:1:1074
+2345:1:1075
+2346:1:1079
+2347:1:1080
+2348:1:1088
+2349:1:1093
+2350:1:1094
+2351:1:1105
+2352:1:1106
+2353:1:1107
+2354:1:1118
+2355:1:1123
+2356:1:1124
+2357:1:1135
+2358:1:1136
+2359:1:1137
+2360:1:1135
+2361:1:1143
+2362:1:1144
+2363:1:1148
+2364:1:1155
+2365:1:1159
+2366:0:4863
+2367:2:3721
+2368:0:4863
+2369:1:11
+2370:0:4863
+2371:2:3859
+2372:2:3860
+2373:2:3864
+2374:2:3865
+2375:2:3873
+2376:2:3874
+2377:2:3878
+2378:2:3879
+2379:2:3887
+2380:2:3892
+2381:2:3896
+2382:2:3897
+2383:2:3905
+2384:2:3906
+2385:2:3910
+2386:2:3911
+2387:2:3905
+2388:2:3906
+2389:2:3910
+2390:2:3911
+2391:2:3919
+2392:2:3924
+2393:2:3925
+2394:2:3936
+2395:2:3937
+2396:2:3938
+2397:2:3949
+2398:2:3954
+2399:2:3955
+2400:2:3966
+2401:2:3967
+2402:2:3968
+2403:2:3966
+2404:2:3967
+2405:2:3968
+2406:2:3979
+2407:2:3988
+2408:0:4863
+2409:2:3721
+2410:0:4863
+2411:2:3994
+2412:0:4863
+2413:2:4514
+2414:2:4515
+2415:2:4519
+2416:2:4523
+2417:2:4524
+2418:2:4528
+2419:2:4536
+2420:2:4537
+2421:2:4541
+2422:2:4545
+2423:2:4546
+2424:2:4541
+2425:2:4545
+2426:2:4546
+2427:2:4550
+2428:2:4557
+2429:2:4564
+2430:2:4565
+2431:2:4572
+2432:2:4577
+2433:2:4584
+2434:2:4585
+2435:2:4584
+2436:2:4585
+2437:2:4592
+2438:2:4596
+2439:0:4863
+2440:2:3996
+2441:2:4401
+2442:0:4863
+2443:1:1160
+2444:1:1161
+2445:1:1165
+2446:1:1166
+2447:1:1174
+2448:1:1175
+2449:1:1176
+2450:1:1188
+2451:1:1193
+2452:1:1197
+2453:1:1198
+2454:1:1206
+2455:1:1207
+2456:1:1211
+2457:1:1212
+2458:1:1206
+2459:1:1207
+2460:1:1211
+2461:1:1212
+2462:1:1220
+2463:1:1225
+2464:1:1226
+2465:1:1237
+2466:1:1238
+2467:1:1239
+2468:1:1250
+2469:1:1255
+2470:1:1256
+2471:1:1267
+2472:1:1268
+2473:1:1269
+2474:1:1267
+2475:1:1275
+2476:1:1276
+2477:1:1280
+2478:0:4863
+2479:2:3721
+2480:0:4863
+2481:1:11
+2482:0:4863
+2483:2:3859
+2484:2:3860
+2485:2:3864
+2486:2:3865
+2487:2:3873
+2488:2:3874
+2489:2:3878
+2490:2:3879
+2491:2:3887
+2492:2:3892
+2493:2:3896
+2494:2:3897
+2495:2:3905
+2496:2:3906
+2497:2:3910
+2498:2:3911
+2499:2:3905
+2500:2:3906
+2501:2:3910
+2502:2:3911
+2503:2:3919
+2504:2:3924
+2505:2:3925
+2506:2:3936
+2507:2:3937
+2508:2:3938
+2509:2:3949
+2510:2:3954
+2511:2:3955
+2512:2:3966
+2513:2:3967
+2514:2:3968
+2515:2:3966
+2516:2:3967
+2517:2:3968
+2518:2:3979
+2519:2:3988
+2520:0:4863
+2521:2:3721
+2522:0:4863
+2523:2:3994
+2524:0:4863
+2525:2:4514
+2526:2:4515
+2527:2:4519
+2528:2:4523
+2529:2:4524
+2530:2:4528
+2531:2:4536
+2532:2:4537
+2533:2:4541
+2534:2:4545
+2535:2:4546
+2536:2:4541
+2537:2:4545
+2538:2:4546
+2539:2:4550
+2540:2:4557
+2541:2:4564
+2542:2:4565
+2543:2:4572
+2544:2:4577
+2545:2:4584
+2546:2:4585
+2547:2:4584
+2548:2:4585
+2549:2:4592
+2550:2:4596
+2551:0:4863
+2552:2:3996
+2553:2:4401
+2554:0:4863
+2555:2:3721
+2556:0:4863
+2557:1:1289
+2558:1:1290
+2559:1:1294
+2560:1:1295
+2561:1:1303
+2562:1:1304
+2563:1:1308
+2564:1:1309
+2565:1:1317
+2566:1:1322
+2567:1:1326
+2568:1:1327
+2569:1:1335
+2570:1:1336
+2571:1:1340
+2572:1:1341
+2573:1:1335
+2574:1:1336
+2575:1:1340
+2576:1:1341
+2577:1:1349
+2578:1:1354
+2579:1:1355
+2580:1:1366
+2581:1:1367
+2582:1:1368
+2583:1:1379
+2584:1:1384
+2585:1:1385
+2586:1:1396
+2587:1:1397
+2588:1:1398
+2589:1:1396
+2590:1:1404
+2591:1:1405
+2592:1:1409
+2593:0:4861
+2594:1:11
+2595:0:4867
+2596:0:4863
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_nested.define b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_nested.define
new file mode 100644 (file)
index 0000000..0fb59bd
--- /dev/null
@@ -0,0 +1 @@
+#define READER_NEST_LEVEL 2
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_mb.define b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_mb.define
new file mode 100644 (file)
index 0000000..d99d793
--- /dev/null
@@ -0,0 +1 @@
+#define NO_MB
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_mb.log b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_mb.log
new file mode 100644 (file)
index 0000000..282f866
--- /dev/null
@@ -0,0 +1,880 @@
+make[1]: Entering directory `/home/compudj/doc/userspace-rcu/formal-model/urcu-controldataflow'
+rm -f pan* trail.out .input.spin* *.spin.trail .input.define
+touch .input.define
+cat .input.define >> pan.ltl
+cat DEFINES >> pan.ltl
+spin -f "!(`cat urcu_free.ltl | grep -v ^//`)" >> pan.ltl
+cp urcu_free_no_mb.define .input.define
+cat .input.define > .input.spin
+cat DEFINES >> .input.spin
+cat urcu.spin >> .input.spin
+rm -f .input.spin.trail
+spin -a -X -N pan.ltl .input.spin
+Exit-Status 0
+gcc -O2 -w -DHASH64 -o pan pan.c
+./pan -a -v -c1 -X -m10000000 -w20
+warning: for p.o. reduction to be valid the never claim must be stutter-invariant
+(never claims generated from LTL formulae are stutter-invariant)
+depth 0: Claim reached state 5 (line 1245)
+Depth=    9118 States=    1e+06 Transitions= 1.65e+08 Memory=   550.432        t=    207 R=   5e+03
+Depth=    9118 States=    2e+06 Transitions= 3.77e+08 Memory=   634.318        t=    477 R=   4e+03
+Depth=    9118 States=    3e+06 Transitions= 5.23e+08 Memory=   718.303        t=    664 R=   5e+03
+pan: resizing hashtable to -w22..  done
+pan: claim violated! (at depth 1384)
+pan: wrote .input.spin.trail
+
+(Spin Version 5.1.7 -- 23 December 2008)
+Warning: Search not completed
+       + Partial Order Reduction
+
+Full statespace search for:
+       never claim             +
+       assertion violations    + (if within scope of claim)
+       acceptance   cycles     + (fairness disabled)
+       invalid end states      - (disabled by never claim)
+
+State-vector 88 byte, depth reached 9118, errors: 1
+  3611143 states, stored
+6.1053642e+08 states, matched
+6.1414756e+08 transitions (= stored+matched)
+3.4001615e+09 atomic steps
+hash conflicts: 3.9831098e+08 (resolved)
+
+Stats on memory usage (in Megabytes):
+  399.487      equivalent memory usage for states (stored*(State-vector + overhead))
+  311.150      actual memory usage for states (compression: 77.89%)
+               state-vector as stored = 62 byte + 28 byte overhead
+   32.000      memory used for hash table (-w22)
+  457.764      memory used for DFS stack (-m10000000)
+  800.693      total actual memory usage
+
+unreached in proctype urcu_reader
+       line 250, "pan.___", state 36, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 58, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 67, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 83, "(1)"
+       line 231, "pan.___", state 91, "(1)"
+       line 235, "pan.___", state 103, "(1)"
+       line 239, "pan.___", state 111, "(1)"
+       line 387, "pan.___", state 136, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 168, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 182, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 201, "(1)"
+       line 413, "pan.___", state 231, "(1)"
+       line 417, "pan.___", state 244, "(1)"
+       line 672, "pan.___", state 265, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<1))"
+       line 387, "pan.___", state 272, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 304, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 318, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 337, "(1)"
+       line 413, "pan.___", state 367, "(1)"
+       line 417, "pan.___", state 380, "(1)"
+       line 387, "pan.___", state 401, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 433, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 447, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 466, "(1)"
+       line 413, "pan.___", state 496, "(1)"
+       line 417, "pan.___", state 509, "(1)"
+       line 387, "pan.___", state 532, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 534, "(1)"
+       line 387, "pan.___", state 535, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 387, "pan.___", state 535, "else"
+       line 387, "pan.___", state 538, "(1)"
+       line 391, "pan.___", state 546, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 548, "(1)"
+       line 391, "pan.___", state 549, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 391, "pan.___", state 549, "else"
+       line 391, "pan.___", state 552, "(1)"
+       line 391, "pan.___", state 553, "(1)"
+       line 391, "pan.___", state 553, "(1)"
+       line 389, "pan.___", state 558, "((i<1))"
+       line 389, "pan.___", state 558, "((i>=1))"
+       line 396, "pan.___", state 564, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 566, "(1)"
+       line 396, "pan.___", state 567, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 567, "else"
+       line 396, "pan.___", state 570, "(1)"
+       line 396, "pan.___", state 571, "(1)"
+       line 396, "pan.___", state 571, "(1)"
+       line 400, "pan.___", state 578, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 580, "(1)"
+       line 400, "pan.___", state 581, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 581, "else"
+       line 400, "pan.___", state 584, "(1)"
+       line 400, "pan.___", state 585, "(1)"
+       line 400, "pan.___", state 585, "(1)"
+       line 398, "pan.___", state 590, "((i<2))"
+       line 398, "pan.___", state 590, "((i>=2))"
+       line 404, "pan.___", state 597, "(1)"
+       line 404, "pan.___", state 598, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 598, "else"
+       line 404, "pan.___", state 601, "(1)"
+       line 404, "pan.___", state 602, "(1)"
+       line 404, "pan.___", state 602, "(1)"
+       line 408, "pan.___", state 610, "(1)"
+       line 408, "pan.___", state 611, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 611, "else"
+       line 408, "pan.___", state 614, "(1)"
+       line 408, "pan.___", state 615, "(1)"
+       line 408, "pan.___", state 615, "(1)"
+       line 406, "pan.___", state 620, "((i<1))"
+       line 406, "pan.___", state 620, "((i>=1))"
+       line 413, "pan.___", state 627, "(1)"
+       line 413, "pan.___", state 628, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 628, "else"
+       line 413, "pan.___", state 631, "(1)"
+       line 413, "pan.___", state 632, "(1)"
+       line 413, "pan.___", state 632, "(1)"
+       line 417, "pan.___", state 640, "(1)"
+       line 417, "pan.___", state 641, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 641, "else"
+       line 417, "pan.___", state 644, "(1)"
+       line 417, "pan.___", state 645, "(1)"
+       line 417, "pan.___", state 645, "(1)"
+       line 415, "pan.___", state 650, "((i<2))"
+       line 415, "pan.___", state 650, "((i>=2))"
+       line 422, "pan.___", state 654, "(1)"
+       line 422, "pan.___", state 654, "(1)"
+       line 672, "pan.___", state 657, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 672, "pan.___", state 658, "_proc_urcu_reader = (_proc_urcu_reader|(1<<5))"
+       line 672, "pan.___", state 659, "(1)"
+       line 387, "pan.___", state 666, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 698, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 712, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 731, "(1)"
+       line 413, "pan.___", state 761, "(1)"
+       line 417, "pan.___", state 774, "(1)"
+       line 387, "pan.___", state 802, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 804, "(1)"
+       line 387, "pan.___", state 805, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 387, "pan.___", state 805, "else"
+       line 387, "pan.___", state 808, "(1)"
+       line 391, "pan.___", state 816, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 818, "(1)"
+       line 391, "pan.___", state 819, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 391, "pan.___", state 819, "else"
+       line 391, "pan.___", state 822, "(1)"
+       line 391, "pan.___", state 823, "(1)"
+       line 391, "pan.___", state 823, "(1)"
+       line 389, "pan.___", state 828, "((i<1))"
+       line 389, "pan.___", state 828, "((i>=1))"
+       line 396, "pan.___", state 834, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 836, "(1)"
+       line 396, "pan.___", state 837, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 837, "else"
+       line 396, "pan.___", state 840, "(1)"
+       line 396, "pan.___", state 841, "(1)"
+       line 396, "pan.___", state 841, "(1)"
+       line 400, "pan.___", state 848, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 850, "(1)"
+       line 400, "pan.___", state 851, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 851, "else"
+       line 400, "pan.___", state 854, "(1)"
+       line 400, "pan.___", state 855, "(1)"
+       line 400, "pan.___", state 855, "(1)"
+       line 398, "pan.___", state 860, "((i<2))"
+       line 398, "pan.___", state 860, "((i>=2))"
+       line 404, "pan.___", state 867, "(1)"
+       line 404, "pan.___", state 868, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 868, "else"
+       line 404, "pan.___", state 871, "(1)"
+       line 404, "pan.___", state 872, "(1)"
+       line 404, "pan.___", state 872, "(1)"
+       line 408, "pan.___", state 880, "(1)"
+       line 408, "pan.___", state 881, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 881, "else"
+       line 408, "pan.___", state 884, "(1)"
+       line 408, "pan.___", state 885, "(1)"
+       line 408, "pan.___", state 885, "(1)"
+       line 406, "pan.___", state 890, "((i<1))"
+       line 406, "pan.___", state 890, "((i>=1))"
+       line 413, "pan.___", state 897, "(1)"
+       line 413, "pan.___", state 898, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 898, "else"
+       line 413, "pan.___", state 901, "(1)"
+       line 413, "pan.___", state 902, "(1)"
+       line 413, "pan.___", state 902, "(1)"
+       line 417, "pan.___", state 910, "(1)"
+       line 417, "pan.___", state 911, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 911, "else"
+       line 417, "pan.___", state 914, "(1)"
+       line 417, "pan.___", state 915, "(1)"
+       line 417, "pan.___", state 915, "(1)"
+       line 422, "pan.___", state 924, "(1)"
+       line 422, "pan.___", state 924, "(1)"
+       line 387, "pan.___", state 931, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 933, "(1)"
+       line 387, "pan.___", state 934, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 387, "pan.___", state 934, "else"
+       line 387, "pan.___", state 937, "(1)"
+       line 391, "pan.___", state 945, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 947, "(1)"
+       line 391, "pan.___", state 948, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 391, "pan.___", state 948, "else"
+       line 391, "pan.___", state 951, "(1)"
+       line 391, "pan.___", state 952, "(1)"
+       line 391, "pan.___", state 952, "(1)"
+       line 389, "pan.___", state 957, "((i<1))"
+       line 389, "pan.___", state 957, "((i>=1))"
+       line 396, "pan.___", state 963, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 965, "(1)"
+       line 396, "pan.___", state 966, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 966, "else"
+       line 396, "pan.___", state 969, "(1)"
+       line 396, "pan.___", state 970, "(1)"
+       line 396, "pan.___", state 970, "(1)"
+       line 400, "pan.___", state 977, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 979, "(1)"
+       line 400, "pan.___", state 980, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 980, "else"
+       line 400, "pan.___", state 983, "(1)"
+       line 400, "pan.___", state 984, "(1)"
+       line 400, "pan.___", state 984, "(1)"
+       line 398, "pan.___", state 989, "((i<2))"
+       line 398, "pan.___", state 989, "((i>=2))"
+       line 404, "pan.___", state 996, "(1)"
+       line 404, "pan.___", state 997, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 997, "else"
+       line 404, "pan.___", state 1000, "(1)"
+       line 404, "pan.___", state 1001, "(1)"
+       line 404, "pan.___", state 1001, "(1)"
+       line 408, "pan.___", state 1009, "(1)"
+       line 408, "pan.___", state 1010, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 1010, "else"
+       line 408, "pan.___", state 1013, "(1)"
+       line 408, "pan.___", state 1014, "(1)"
+       line 408, "pan.___", state 1014, "(1)"
+       line 406, "pan.___", state 1019, "((i<1))"
+       line 406, "pan.___", state 1019, "((i>=1))"
+       line 413, "pan.___", state 1026, "(1)"
+       line 413, "pan.___", state 1027, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 1027, "else"
+       line 413, "pan.___", state 1030, "(1)"
+       line 413, "pan.___", state 1031, "(1)"
+       line 413, "pan.___", state 1031, "(1)"
+       line 417, "pan.___", state 1039, "(1)"
+       line 417, "pan.___", state 1040, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 1040, "else"
+       line 417, "pan.___", state 1043, "(1)"
+       line 417, "pan.___", state 1044, "(1)"
+       line 417, "pan.___", state 1044, "(1)"
+       line 415, "pan.___", state 1049, "((i<2))"
+       line 415, "pan.___", state 1049, "((i>=2))"
+       line 422, "pan.___", state 1053, "(1)"
+       line 422, "pan.___", state 1053, "(1)"
+       line 680, "pan.___", state 1057, "_proc_urcu_reader = (_proc_urcu_reader|(1<<11))"
+       line 387, "pan.___", state 1062, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1094, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1108, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1127, "(1)"
+       line 413, "pan.___", state 1157, "(1)"
+       line 417, "pan.___", state 1170, "(1)"
+       line 387, "pan.___", state 1194, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1226, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1240, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1259, "(1)"
+       line 413, "pan.___", state 1289, "(1)"
+       line 417, "pan.___", state 1302, "(1)"
+       line 387, "pan.___", state 1327, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1359, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1373, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1392, "(1)"
+       line 413, "pan.___", state 1422, "(1)"
+       line 417, "pan.___", state 1435, "(1)"
+       line 387, "pan.___", state 1456, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1488, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1502, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1521, "(1)"
+       line 413, "pan.___", state 1551, "(1)"
+       line 417, "pan.___", state 1564, "(1)"
+       line 387, "pan.___", state 1590, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1622, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1636, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1655, "(1)"
+       line 413, "pan.___", state 1685, "(1)"
+       line 417, "pan.___", state 1698, "(1)"
+       line 387, "pan.___", state 1719, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1751, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1765, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1784, "(1)"
+       line 413, "pan.___", state 1814, "(1)"
+       line 417, "pan.___", state 1827, "(1)"
+       line 387, "pan.___", state 1851, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1883, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1897, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1916, "(1)"
+       line 413, "pan.___", state 1946, "(1)"
+       line 417, "pan.___", state 1959, "(1)"
+       line 719, "pan.___", state 1980, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<19))"
+       line 387, "pan.___", state 1987, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2019, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2033, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2052, "(1)"
+       line 413, "pan.___", state 2082, "(1)"
+       line 417, "pan.___", state 2095, "(1)"
+       line 387, "pan.___", state 2116, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2148, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2162, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2181, "(1)"
+       line 413, "pan.___", state 2211, "(1)"
+       line 417, "pan.___", state 2224, "(1)"
+       line 387, "pan.___", state 2247, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 2249, "(1)"
+       line 387, "pan.___", state 2250, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 387, "pan.___", state 2250, "else"
+       line 387, "pan.___", state 2253, "(1)"
+       line 391, "pan.___", state 2261, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 2263, "(1)"
+       line 391, "pan.___", state 2264, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 391, "pan.___", state 2264, "else"
+       line 391, "pan.___", state 2267, "(1)"
+       line 391, "pan.___", state 2268, "(1)"
+       line 391, "pan.___", state 2268, "(1)"
+       line 389, "pan.___", state 2273, "((i<1))"
+       line 389, "pan.___", state 2273, "((i>=1))"
+       line 396, "pan.___", state 2279, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2281, "(1)"
+       line 396, "pan.___", state 2282, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 2282, "else"
+       line 396, "pan.___", state 2285, "(1)"
+       line 396, "pan.___", state 2286, "(1)"
+       line 396, "pan.___", state 2286, "(1)"
+       line 400, "pan.___", state 2293, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2295, "(1)"
+       line 400, "pan.___", state 2296, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 2296, "else"
+       line 400, "pan.___", state 2299, "(1)"
+       line 400, "pan.___", state 2300, "(1)"
+       line 400, "pan.___", state 2300, "(1)"
+       line 398, "pan.___", state 2305, "((i<2))"
+       line 398, "pan.___", state 2305, "((i>=2))"
+       line 404, "pan.___", state 2312, "(1)"
+       line 404, "pan.___", state 2313, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 2313, "else"
+       line 404, "pan.___", state 2316, "(1)"
+       line 404, "pan.___", state 2317, "(1)"
+       line 404, "pan.___", state 2317, "(1)"
+       line 408, "pan.___", state 2325, "(1)"
+       line 408, "pan.___", state 2326, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 2326, "else"
+       line 408, "pan.___", state 2329, "(1)"
+       line 408, "pan.___", state 2330, "(1)"
+       line 408, "pan.___", state 2330, "(1)"
+       line 406, "pan.___", state 2335, "((i<1))"
+       line 406, "pan.___", state 2335, "((i>=1))"
+       line 413, "pan.___", state 2342, "(1)"
+       line 413, "pan.___", state 2343, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 2343, "else"
+       line 413, "pan.___", state 2346, "(1)"
+       line 413, "pan.___", state 2347, "(1)"
+       line 413, "pan.___", state 2347, "(1)"
+       line 417, "pan.___", state 2355, "(1)"
+       line 417, "pan.___", state 2356, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 2356, "else"
+       line 417, "pan.___", state 2359, "(1)"
+       line 417, "pan.___", state 2360, "(1)"
+       line 417, "pan.___", state 2360, "(1)"
+       line 415, "pan.___", state 2365, "((i<2))"
+       line 415, "pan.___", state 2365, "((i>=2))"
+       line 422, "pan.___", state 2369, "(1)"
+       line 422, "pan.___", state 2369, "(1)"
+       line 719, "pan.___", state 2372, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 719, "pan.___", state 2373, "_proc_urcu_reader = (_proc_urcu_reader|(1<<23))"
+       line 719, "pan.___", state 2374, "(1)"
+       line 387, "pan.___", state 2381, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2413, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2427, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2446, "(1)"
+       line 413, "pan.___", state 2476, "(1)"
+       line 417, "pan.___", state 2489, "(1)"
+       line 387, "pan.___", state 2516, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2548, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2562, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2581, "(1)"
+       line 413, "pan.___", state 2611, "(1)"
+       line 417, "pan.___", state 2624, "(1)"
+       line 387, "pan.___", state 2645, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2677, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2691, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2710, "(1)"
+       line 413, "pan.___", state 2740, "(1)"
+       line 417, "pan.___", state 2753, "(1)"
+       line 227, "pan.___", state 2786, "(1)"
+       line 235, "pan.___", state 2806, "(1)"
+       line 239, "pan.___", state 2814, "(1)"
+       line 227, "pan.___", state 2829, "(1)"
+       line 235, "pan.___", state 2849, "(1)"
+       line 239, "pan.___", state 2857, "(1)"
+       line 870, "pan.___", state 2874, "-end-"
+       (278 of 2874 states)
+unreached in proctype urcu_writer
+       line 387, "pan.___", state 20, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 26, "(1)"
+       line 391, "pan.___", state 34, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 40, "(1)"
+       line 391, "pan.___", state 41, "(1)"
+       line 391, "pan.___", state 41, "(1)"
+       line 389, "pan.___", state 46, "((i<1))"
+       line 389, "pan.___", state 46, "((i>=1))"
+       line 396, "pan.___", state 52, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 58, "(1)"
+       line 396, "pan.___", state 59, "(1)"
+       line 396, "pan.___", state 59, "(1)"
+       line 400, "pan.___", state 72, "(1)"
+       line 400, "pan.___", state 73, "(1)"
+       line 400, "pan.___", state 73, "(1)"
+       line 398, "pan.___", state 78, "((i<2))"
+       line 398, "pan.___", state 78, "((i>=2))"
+       line 404, "pan.___", state 85, "(1)"
+       line 404, "pan.___", state 86, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 86, "else"
+       line 404, "pan.___", state 89, "(1)"
+       line 404, "pan.___", state 90, "(1)"
+       line 404, "pan.___", state 90, "(1)"
+       line 408, "pan.___", state 98, "(1)"
+       line 408, "pan.___", state 99, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 99, "else"
+       line 408, "pan.___", state 102, "(1)"
+       line 408, "pan.___", state 103, "(1)"
+       line 408, "pan.___", state 103, "(1)"
+       line 406, "pan.___", state 108, "((i<1))"
+       line 406, "pan.___", state 108, "((i>=1))"
+       line 413, "pan.___", state 115, "(1)"
+       line 413, "pan.___", state 116, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 116, "else"
+       line 413, "pan.___", state 119, "(1)"
+       line 413, "pan.___", state 120, "(1)"
+       line 413, "pan.___", state 120, "(1)"
+       line 417, "pan.___", state 128, "(1)"
+       line 417, "pan.___", state 129, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 129, "else"
+       line 417, "pan.___", state 132, "(1)"
+       line 417, "pan.___", state 133, "(1)"
+       line 417, "pan.___", state 133, "(1)"
+       line 415, "pan.___", state 138, "((i<2))"
+       line 415, "pan.___", state 138, "((i>=2))"
+       line 422, "pan.___", state 142, "(1)"
+       line 422, "pan.___", state 142, "(1)"
+       line 250, "pan.___", state 151, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 160, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 252, "pan.___", state 168, "((i<1))"
+       line 252, "pan.___", state 168, "((i>=1))"
+       line 258, "pan.___", state 173, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 993, "pan.___", state 201, "old_data = cached_rcu_ptr.val[_pid]"
+       line 1004, "pan.___", state 205, "_proc_urcu_writer = (_proc_urcu_writer|(1<<4))"
+       line 387, "pan.___", state 213, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 219, "(1)"
+       line 391, "pan.___", state 227, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 233, "(1)"
+       line 391, "pan.___", state 234, "(1)"
+       line 391, "pan.___", state 234, "(1)"
+       line 389, "pan.___", state 239, "((i<1))"
+       line 389, "pan.___", state 239, "((i>=1))"
+       line 396, "pan.___", state 247, "(1)"
+       line 396, "pan.___", state 248, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 248, "else"
+       line 396, "pan.___", state 251, "(1)"
+       line 396, "pan.___", state 252, "(1)"
+       line 396, "pan.___", state 252, "(1)"
+       line 400, "pan.___", state 259, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 265, "(1)"
+       line 400, "pan.___", state 266, "(1)"
+       line 400, "pan.___", state 266, "(1)"
+       line 398, "pan.___", state 271, "((i<2))"
+       line 398, "pan.___", state 271, "((i>=2))"
+       line 404, "pan.___", state 278, "(1)"
+       line 404, "pan.___", state 279, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 279, "else"
+       line 404, "pan.___", state 282, "(1)"
+       line 404, "pan.___", state 283, "(1)"
+       line 404, "pan.___", state 283, "(1)"
+       line 408, "pan.___", state 291, "(1)"
+       line 408, "pan.___", state 292, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 292, "else"
+       line 408, "pan.___", state 295, "(1)"
+       line 408, "pan.___", state 296, "(1)"
+       line 408, "pan.___", state 296, "(1)"
+       line 406, "pan.___", state 301, "((i<1))"
+       line 406, "pan.___", state 301, "((i>=1))"
+       line 413, "pan.___", state 308, "(1)"
+       line 413, "pan.___", state 309, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 309, "else"
+       line 413, "pan.___", state 312, "(1)"
+       line 413, "pan.___", state 313, "(1)"
+       line 413, "pan.___", state 313, "(1)"
+       line 417, "pan.___", state 321, "(1)"
+       line 417, "pan.___", state 322, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 322, "else"
+       line 417, "pan.___", state 325, "(1)"
+       line 417, "pan.___", state 326, "(1)"
+       line 417, "pan.___", state 326, "(1)"
+       line 415, "pan.___", state 331, "((i<2))"
+       line 415, "pan.___", state 331, "((i>=2))"
+       line 422, "pan.___", state 335, "(1)"
+       line 422, "pan.___", state 335, "(1)"
+       line 387, "pan.___", state 346, "(1)"
+       line 387, "pan.___", state 347, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 387, "pan.___", state 347, "else"
+       line 387, "pan.___", state 350, "(1)"
+       line 391, "pan.___", state 358, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 364, "(1)"
+       line 391, "pan.___", state 365, "(1)"
+       line 391, "pan.___", state 365, "(1)"
+       line 389, "pan.___", state 370, "((i<1))"
+       line 389, "pan.___", state 370, "((i>=1))"
+       line 396, "pan.___", state 376, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 382, "(1)"
+       line 396, "pan.___", state 383, "(1)"
+       line 396, "pan.___", state 383, "(1)"
+       line 400, "pan.___", state 390, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 396, "(1)"
+       line 400, "pan.___", state 397, "(1)"
+       line 400, "pan.___", state 397, "(1)"
+       line 398, "pan.___", state 402, "((i<2))"
+       line 398, "pan.___", state 402, "((i>=2))"
+       line 404, "pan.___", state 409, "(1)"
+       line 404, "pan.___", state 410, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 410, "else"
+       line 404, "pan.___", state 413, "(1)"
+       line 404, "pan.___", state 414, "(1)"
+       line 404, "pan.___", state 414, "(1)"
+       line 408, "pan.___", state 422, "(1)"
+       line 408, "pan.___", state 423, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 423, "else"
+       line 408, "pan.___", state 426, "(1)"
+       line 408, "pan.___", state 427, "(1)"
+       line 408, "pan.___", state 427, "(1)"
+       line 406, "pan.___", state 432, "((i<1))"
+       line 406, "pan.___", state 432, "((i>=1))"
+       line 413, "pan.___", state 439, "(1)"
+       line 413, "pan.___", state 440, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 440, "else"
+       line 413, "pan.___", state 443, "(1)"
+       line 413, "pan.___", state 444, "(1)"
+       line 413, "pan.___", state 444, "(1)"
+       line 417, "pan.___", state 452, "(1)"
+       line 417, "pan.___", state 453, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 453, "else"
+       line 417, "pan.___", state 456, "(1)"
+       line 417, "pan.___", state 457, "(1)"
+       line 417, "pan.___", state 457, "(1)"
+       line 415, "pan.___", state 462, "((i<2))"
+       line 415, "pan.___", state 462, "((i>=2))"
+       line 422, "pan.___", state 466, "(1)"
+       line 422, "pan.___", state 466, "(1)"
+       line 1056, "pan.___", state 477, "_proc_urcu_writer = (_proc_urcu_writer&~(((1<<8)|(1<<7))))"
+       line 387, "pan.___", state 482, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 488, "(1)"
+       line 391, "pan.___", state 496, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 502, "(1)"
+       line 391, "pan.___", state 503, "(1)"
+       line 391, "pan.___", state 503, "(1)"
+       line 389, "pan.___", state 508, "((i<1))"
+       line 389, "pan.___", state 508, "((i>=1))"
+       line 396, "pan.___", state 514, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 520, "(1)"
+       line 396, "pan.___", state 521, "(1)"
+       line 396, "pan.___", state 521, "(1)"
+       line 400, "pan.___", state 528, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 534, "(1)"
+       line 400, "pan.___", state 535, "(1)"
+       line 400, "pan.___", state 535, "(1)"
+       line 398, "pan.___", state 540, "((i<2))"
+       line 398, "pan.___", state 540, "((i>=2))"
+       line 404, "pan.___", state 547, "(1)"
+       line 404, "pan.___", state 548, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 548, "else"
+       line 404, "pan.___", state 551, "(1)"
+       line 404, "pan.___", state 552, "(1)"
+       line 404, "pan.___", state 552, "(1)"
+       line 408, "pan.___", state 560, "(1)"
+       line 408, "pan.___", state 561, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 561, "else"
+       line 408, "pan.___", state 564, "(1)"
+       line 408, "pan.___", state 565, "(1)"
+       line 408, "pan.___", state 565, "(1)"
+       line 406, "pan.___", state 570, "((i<1))"
+       line 406, "pan.___", state 570, "((i>=1))"
+       line 413, "pan.___", state 577, "(1)"
+       line 413, "pan.___", state 578, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 578, "else"
+       line 413, "pan.___", state 581, "(1)"
+       line 413, "pan.___", state 582, "(1)"
+       line 413, "pan.___", state 582, "(1)"
+       line 417, "pan.___", state 590, "(1)"
+       line 417, "pan.___", state 591, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 591, "else"
+       line 417, "pan.___", state 594, "(1)"
+       line 417, "pan.___", state 595, "(1)"
+       line 417, "pan.___", state 595, "(1)"
+       line 422, "pan.___", state 604, "(1)"
+       line 422, "pan.___", state 604, "(1)"
+       line 387, "pan.___", state 611, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 625, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 643, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 676, "(1)"
+       line 408, "pan.___", state 689, "(1)"
+       line 413, "pan.___", state 706, "(1)"
+       line 417, "pan.___", state 719, "(1)"
+       line 391, "pan.___", state 756, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 774, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 788, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 820, "(1)"
+       line 413, "pan.___", state 837, "(1)"
+       line 417, "pan.___", state 850, "(1)"
+       line 1128, "pan.___", state 877, "_proc_urcu_writer = (_proc_urcu_writer|(1<<13))"
+       line 250, "pan.___", state 905, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 250, "pan.___", state 907, "(1)"
+       line 254, "pan.___", state 914, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 916, "(1)"
+       line 254, "pan.___", state 917, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 254, "pan.___", state 917, "else"
+       line 252, "pan.___", state 922, "((i<1))"
+       line 252, "pan.___", state 922, "((i>=1))"
+       line 258, "pan.___", state 927, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 929, "(1)"
+       line 258, "pan.___", state 930, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 930, "else"
+       line 262, "pan.___", state 936, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 938, "(1)"
+       line 262, "pan.___", state 939, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 262, "pan.___", state 939, "else"
+       line 260, "pan.___", state 944, "((i<2))"
+       line 260, "pan.___", state 944, "((i>=2))"
+       line 227, "pan.___", state 952, "(1)"
+       line 231, "pan.___", state 960, "(1)"
+       line 231, "pan.___", state 961, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 961, "else"
+       line 229, "pan.___", state 966, "((i<1))"
+       line 229, "pan.___", state 966, "((i>=1))"
+       line 235, "pan.___", state 972, "(1)"
+       line 235, "pan.___", state 973, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 973, "else"
+       line 239, "pan.___", state 980, "(1)"
+       line 239, "pan.___", state 981, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 981, "else"
+       line 244, "pan.___", state 990, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 990, "else"
+       line 1176, "pan.___", state 1006, "((i<1))"
+       line 1176, "pan.___", state 1006, "((i>=1))"
+       line 250, "pan.___", state 1011, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 250, "pan.___", state 1013, "(1)"
+       line 254, "pan.___", state 1020, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1022, "(1)"
+       line 254, "pan.___", state 1023, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 254, "pan.___", state 1023, "else"
+       line 252, "pan.___", state 1028, "((i<1))"
+       line 252, "pan.___", state 1028, "((i>=1))"
+       line 258, "pan.___", state 1033, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1035, "(1)"
+       line 258, "pan.___", state 1036, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 1036, "else"
+       line 262, "pan.___", state 1042, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1044, "(1)"
+       line 262, "pan.___", state 1045, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 262, "pan.___", state 1045, "else"
+       line 260, "pan.___", state 1050, "((i<2))"
+       line 260, "pan.___", state 1050, "((i>=2))"
+       line 227, "pan.___", state 1058, "(1)"
+       line 231, "pan.___", state 1066, "(1)"
+       line 231, "pan.___", state 1067, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 1067, "else"
+       line 229, "pan.___", state 1072, "((i<1))"
+       line 229, "pan.___", state 1072, "((i>=1))"
+       line 235, "pan.___", state 1078, "(1)"
+       line 235, "pan.___", state 1079, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 1079, "else"
+       line 239, "pan.___", state 1086, "(1)"
+       line 239, "pan.___", state 1087, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 1087, "else"
+       line 244, "pan.___", state 1096, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 1096, "else"
+       line 277, "pan.___", state 1098, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 277, "pan.___", state 1098, "else"
+       line 1176, "pan.___", state 1099, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 1176, "pan.___", state 1099, "else"
+       line 250, "pan.___", state 1103, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 250, "pan.___", state 1105, "(1)"
+       line 254, "pan.___", state 1112, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1114, "(1)"
+       line 254, "pan.___", state 1115, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 254, "pan.___", state 1115, "else"
+       line 252, "pan.___", state 1120, "((i<1))"
+       line 252, "pan.___", state 1120, "((i>=1))"
+       line 258, "pan.___", state 1125, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1127, "(1)"
+       line 258, "pan.___", state 1128, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 1128, "else"
+       line 262, "pan.___", state 1134, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1136, "(1)"
+       line 262, "pan.___", state 1137, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 262, "pan.___", state 1137, "else"
+       line 260, "pan.___", state 1142, "((i<2))"
+       line 260, "pan.___", state 1142, "((i>=2))"
+       line 227, "pan.___", state 1150, "(1)"
+       line 231, "pan.___", state 1158, "(1)"
+       line 231, "pan.___", state 1159, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 1159, "else"
+       line 229, "pan.___", state 1164, "((i<1))"
+       line 229, "pan.___", state 1164, "((i>=1))"
+       line 235, "pan.___", state 1170, "(1)"
+       line 235, "pan.___", state 1171, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 1171, "else"
+       line 239, "pan.___", state 1178, "(1)"
+       line 239, "pan.___", state 1179, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 1179, "else"
+       line 244, "pan.___", state 1188, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 1188, "else"
+       line 1180, "pan.___", state 1191, "i = 0"
+       line 1180, "pan.___", state 1193, "reader_barrier = 1"
+       line 1180, "pan.___", state 1204, "((i<1))"
+       line 1180, "pan.___", state 1204, "((i>=1))"
+       line 250, "pan.___", state 1209, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 250, "pan.___", state 1211, "(1)"
+       line 254, "pan.___", state 1218, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1220, "(1)"
+       line 254, "pan.___", state 1221, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 254, "pan.___", state 1221, "else"
+       line 252, "pan.___", state 1226, "((i<1))"
+       line 252, "pan.___", state 1226, "((i>=1))"
+       line 258, "pan.___", state 1231, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1233, "(1)"
+       line 258, "pan.___", state 1234, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 1234, "else"
+       line 262, "pan.___", state 1240, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1242, "(1)"
+       line 262, "pan.___", state 1243, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 262, "pan.___", state 1243, "else"
+       line 260, "pan.___", state 1248, "((i<2))"
+       line 260, "pan.___", state 1248, "((i>=2))"
+       line 227, "pan.___", state 1256, "(1)"
+       line 231, "pan.___", state 1264, "(1)"
+       line 231, "pan.___", state 1265, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 1265, "else"
+       line 229, "pan.___", state 1270, "((i<1))"
+       line 229, "pan.___", state 1270, "((i>=1))"
+       line 235, "pan.___", state 1276, "(1)"
+       line 235, "pan.___", state 1277, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 1277, "else"
+       line 239, "pan.___", state 1284, "(1)"
+       line 239, "pan.___", state 1285, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 1285, "else"
+       line 244, "pan.___", state 1294, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 1294, "else"
+       line 277, "pan.___", state 1296, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 277, "pan.___", state 1296, "else"
+       line 1180, "pan.___", state 1297, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 1180, "pan.___", state 1297, "else"
+       line 254, "pan.___", state 1310, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1323, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1332, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1348, "(1)"
+       line 231, "pan.___", state 1356, "(1)"
+       line 235, "pan.___", state 1368, "(1)"
+       line 239, "pan.___", state 1376, "(1)"
+       line 250, "pan.___", state 1407, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1416, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1429, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1438, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1454, "(1)"
+       line 231, "pan.___", state 1462, "(1)"
+       line 235, "pan.___", state 1474, "(1)"
+       line 239, "pan.___", state 1482, "(1)"
+       line 250, "pan.___", state 1499, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 250, "pan.___", state 1501, "(1)"
+       line 254, "pan.___", state 1508, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1510, "(1)"
+       line 254, "pan.___", state 1511, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 254, "pan.___", state 1511, "else"
+       line 252, "pan.___", state 1516, "((i<1))"
+       line 252, "pan.___", state 1516, "((i>=1))"
+       line 258, "pan.___", state 1521, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1523, "(1)"
+       line 258, "pan.___", state 1524, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 1524, "else"
+       line 262, "pan.___", state 1530, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1532, "(1)"
+       line 262, "pan.___", state 1533, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 262, "pan.___", state 1533, "else"
+       line 260, "pan.___", state 1538, "((i<2))"
+       line 260, "pan.___", state 1538, "((i>=2))"
+       line 227, "pan.___", state 1546, "(1)"
+       line 231, "pan.___", state 1554, "(1)"
+       line 231, "pan.___", state 1555, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 1555, "else"
+       line 229, "pan.___", state 1560, "((i<1))"
+       line 229, "pan.___", state 1560, "((i>=1))"
+       line 235, "pan.___", state 1566, "(1)"
+       line 235, "pan.___", state 1567, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 1567, "else"
+       line 239, "pan.___", state 1574, "(1)"
+       line 239, "pan.___", state 1575, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 1575, "else"
+       line 244, "pan.___", state 1584, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 1584, "else"
+       line 1187, "pan.___", state 1587, "i = 0"
+       line 1187, "pan.___", state 1589, "reader_barrier = 1"
+       line 1187, "pan.___", state 1600, "((i<1))"
+       line 1187, "pan.___", state 1600, "((i>=1))"
+       line 250, "pan.___", state 1605, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 250, "pan.___", state 1607, "(1)"
+       line 254, "pan.___", state 1614, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1616, "(1)"
+       line 254, "pan.___", state 1617, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 254, "pan.___", state 1617, "else"
+       line 252, "pan.___", state 1622, "((i<1))"
+       line 252, "pan.___", state 1622, "((i>=1))"
+       line 258, "pan.___", state 1627, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1629, "(1)"
+       line 258, "pan.___", state 1630, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 1630, "else"
+       line 262, "pan.___", state 1636, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1638, "(1)"
+       line 262, "pan.___", state 1639, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 262, "pan.___", state 1639, "else"
+       line 260, "pan.___", state 1644, "((i<2))"
+       line 260, "pan.___", state 1644, "((i>=2))"
+       line 227, "pan.___", state 1652, "(1)"
+       line 231, "pan.___", state 1660, "(1)"
+       line 231, "pan.___", state 1661, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 1661, "else"
+       line 229, "pan.___", state 1666, "((i<1))"
+       line 229, "pan.___", state 1666, "((i>=1))"
+       line 235, "pan.___", state 1672, "(1)"
+       line 235, "pan.___", state 1673, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 1673, "else"
+       line 239, "pan.___", state 1680, "(1)"
+       line 239, "pan.___", state 1681, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 1681, "else"
+       line 244, "pan.___", state 1690, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 1690, "else"
+       line 277, "pan.___", state 1692, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 277, "pan.___", state 1692, "else"
+       line 1187, "pan.___", state 1693, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 1187, "pan.___", state 1693, "else"
+       line 1191, "pan.___", state 1696, "-end-"
+       (310 of 1696 states)
+unreached in proctype :init:
+       line 1202, "pan.___", state 9, "((j<2))"
+       line 1202, "pan.___", state 9, "((j>=2))"
+       line 1203, "pan.___", state 20, "((j<2))"
+       line 1203, "pan.___", state 20, "((j>=2))"
+       line 1208, "pan.___", state 33, "((j<2))"
+       line 1208, "pan.___", state 33, "((j>=2))"
+       line 1206, "pan.___", state 43, "((i<1))"
+       line 1206, "pan.___", state 43, "((i>=1))"
+       line 1216, "pan.___", state 54, "((j<2))"
+       line 1216, "pan.___", state 54, "((j>=2))"
+       line 1220, "pan.___", state 67, "((j<2))"
+       line 1220, "pan.___", state 67, "((j>=2))"
+       (6 of 78 states)
+unreached in proctype :never:
+       line 1250, "pan.___", state 8, "-end-"
+       (1 of 8 states)
+
+pan: elapsed time 781 seconds
+pan: rate 4622.6181 states/second
+pan: avg transition delay 1.272e-06 usec
+cp .input.spin urcu_free_no_mb.spin.input
+cp .input.spin.trail urcu_free_no_mb.spin.input.trail
+make[1]: Leaving directory `/home/compudj/doc/userspace-rcu/formal-model/urcu-controldataflow'
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_mb.spin.input b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_mb.spin.input
new file mode 100644 (file)
index 0000000..e95f5b1
--- /dev/null
@@ -0,0 +1,1227 @@
+#define NO_MB
+
+// Poison value for freed memory
+#define POISON 1
+// Memory with correct data
+#define WINE 0
+#define SLAB_SIZE 2
+
+#define read_poison    (data_read_first[0] == POISON || data_read_second[0] == POISON)
+
+#define RCU_GP_CTR_BIT (1 << 7)
+#define RCU_GP_CTR_NEST_MASK (RCU_GP_CTR_BIT - 1)
+
+//disabled
+#define REMOTE_BARRIERS
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+typedef per_proc_bit {
+       bit val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bitfield {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bitfield cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               smp_mb(i, j);
+               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
+               break;
+       od;
+}
+
+#ifdef WRITER_PROGRESS
+//#define PROGRESS_LABEL(progressid)   progress_writer_progid_##progressid:
+#define PROGRESS_LABEL(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;                                          \
+               /*                                                              \
+                * 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)                                                     \
+               do                                                              \
+               :: (reader_barrier[i] == 1) -> skip;                            \
+               :: (reader_barrier[i] == 0) -> break;                           \
+               od;                                                             \
+               i++;                                                            \
+       :: i >= NR_READERS ->                                                   \
+               break                                                           \
+       od;                                                                     \
+       smp_mb(i, j);                                                           \
+}
+
+#else
+
+#define smp_mb_send(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, smp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only one reader */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* RCU data */
+DECLARE_CACHED_VAR(bit, rcu_data[SLAB_SIZE]);
+
+/* RCU pointer */
+#if (SLAB_SIZE == 2)
+DECLARE_CACHED_VAR(bit, rcu_ptr);
+bit ptr_read_first[NR_READERS];
+bit ptr_read_second[NR_READERS];
+#else
+DECLARE_CACHED_VAR(byte, rcu_ptr);
+byte ptr_read_first[NR_READERS];
+byte ptr_read_second[NR_READERS];
+#endif
+
+bit data_read_first[NR_READERS];
+bit data_read_second[NR_READERS];
+
+bit init_done = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               :: 1 -> skip;
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               ptr_read_first[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb1;
+rmb1_end:
+                               data_read_first[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_first[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               ptr_read_second[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb2;
+rmb2_end:
+                               data_read_second[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_second[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+rmb1:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb1_end;
+rmb2:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_DATA                     (1 << 1)
+#define WRITE_PROC_WMB                 (1 << 2)
+#define WRITE_XCHG_PTR                 (1 << 3)
+
+#define WRITE_PROC_FIRST_MB            (1 << 4)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 5)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 6)
+#define WRITE_PROC_FIRST_WAIT          (1 << 7)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 8)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 9)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 10)
+#define WRITE_PROC_SECOND_WAIT         (1 << 11)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 12)
+
+#define WRITE_PROC_SECOND_MB           (1 << 13)
+
+#define WRITE_FREE                     (1 << 14)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_DATA                    \
+                                       | WRITE_PROC_WMB                \
+                                       | WRITE_XCHG_PTR                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB          \
+                                       | WRITE_FREE)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 15) - 1)
+
+/*
+ * Mutexes are implied around writer execution. A single writer at a time.
+ */
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte cur_data = 0, old_data, loop_nr = 0;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (loop_nr < 3) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               loop_nr = loop_nr + 1;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_WMB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+#endif
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_DATA) ->
+                       ooo_mem(i);
+                       cur_data = (cur_data + 1) % SLAB_SIZE;
+                       WRITE_CACHED_VAR(rcu_data[cur_data], WINE);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_DATA);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA,
+                                 WRITE_PROC_WMB) ->
+                       smp_wmb(i, j);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_WMB,
+                                 WRITE_XCHG_PTR) ->
+                       /* rcu_xchg_pointer() */
+                       atomic {
+                               old_data = READ_CACHED_VAR(rcu_ptr);
+                               WRITE_CACHED_VAR(rcu_ptr, cur_data);
+                       }
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_XCHG_PTR);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_WMB      /* No dependency on
+                                                        * WRITE_DATA because we
+                                                        * write to a
+                                                        * different location. */
+                                 | WRITE_PROC_SECOND_MB
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_FREE) ->
+                       WRITE_CACHED_VAR(rcu_data[old_data], POISON);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_FREE);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+               /*
+                * Note : Promela model adds implicit serialization of the
+                * WRITE_FREE instruction. Normally, it would be permitted to
+                * spill on the next loop execution. Given the validation we do
+                * checks for the data entry read to be poisoned, it's ok if
+                * we do not check "late arriving" memory poisoning.
+                */
+       :: 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
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(rcu_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       ptr_read_first[i] = 1;
+                       ptr_read_second[i] = 1;
+                       data_read_first[i] = WINE;
+                       data_read_second[i] = WINE;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               INIT_CACHED_VAR(rcu_data[0], WINE, j);
+               i = 1;
+               do
+               :: i < SLAB_SIZE ->
+                       INIT_CACHED_VAR(rcu_data[i], POISON, j);
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_mb.spin.input.trail b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_mb.spin.input.trail
new file mode 100644 (file)
index 0000000..4be75cd
--- /dev/null
@@ -0,0 +1,1387 @@
+-2:3:-2
+-4:-4:-4
+1:0:4650
+2:3:4570
+3:3:4573
+4:3:4573
+5:3:4576
+6:3:4584
+7:3:4584
+8:3:4587
+9:3:4593
+10:3:4597
+11:3:4597
+12:3:4600
+13:3:4610
+14:3:4618
+15:3:4618
+16:3:4621
+17:3:4627
+18:3:4631
+19:3:4631
+20:3:4634
+21:3:4640
+22:3:4644
+23:3:4645
+24:0:4650
+25:3:4647
+26:0:4650
+27:2:2876
+28:0:4650
+29:2:2882
+30:0:4650
+31:2:2883
+32:0:4650
+33:2:2885
+34:0:4650
+35:2:2886
+36:0:4650
+37:2:2887
+38:0:4650
+39:2:2888
+40:0:4650
+41:2:2889
+42:2:2890
+43:2:2894
+44:2:2895
+45:2:2903
+46:2:2904
+47:2:2908
+48:2:2909
+49:2:2917
+50:2:2922
+51:2:2926
+52:2:2927
+53:2:2935
+54:2:2936
+55:2:2940
+56:2:2941
+57:2:2935
+58:2:2936
+59:2:2940
+60:2:2941
+61:2:2949
+62:2:2954
+63:2:2955
+64:2:2966
+65:2:2967
+66:2:2968
+67:2:2979
+68:2:2984
+69:2:2985
+70:2:2996
+71:2:2997
+72:2:2998
+73:2:2996
+74:2:2997
+75:2:2998
+76:2:3009
+77:2:3017
+78:0:4650
+79:2:2888
+80:0:4650
+81:2:3021
+82:2:3025
+83:2:3026
+84:2:3030
+85:2:3034
+86:2:3035
+87:2:3039
+88:2:3047
+89:2:3048
+90:2:3052
+91:2:3056
+92:2:3057
+93:2:3052
+94:2:3053
+95:2:3061
+96:0:4650
+97:2:2888
+98:0:4650
+99:2:3069
+100:2:3070
+101:2:3071
+102:0:4650
+103:2:2888
+104:0:4650
+105:2:3079
+106:0:4650
+107:2:2888
+108:0:4650
+109:2:3082
+110:2:3083
+111:2:3087
+112:2:3088
+113:2:3096
+114:2:3097
+115:2:3101
+116:2:3102
+117:2:3110
+118:2:3115
+119:2:3116
+120:2:3128
+121:2:3129
+122:2:3133
+123:2:3134
+124:2:3128
+125:2:3129
+126:2:3133
+127:2:3134
+128:2:3142
+129:2:3147
+130:2:3148
+131:2:3159
+132:2:3160
+133:2:3161
+134:2:3172
+135:2:3177
+136:2:3178
+137:2:3189
+138:2:3190
+139:2:3191
+140:2:3189
+141:2:3190
+142:2:3191
+143:2:3202
+144:2:3209
+145:0:4650
+146:2:2888
+147:0:4650
+148:2:3213
+149:2:3214
+150:2:3215
+151:2:3227
+152:2:3228
+153:2:3232
+154:2:3233
+155:2:3241
+156:2:3246
+157:2:3250
+158:2:3251
+159:2:3259
+160:2:3260
+161:2:3264
+162:2:3265
+163:2:3259
+164:2:3260
+165:2:3264
+166:2:3265
+167:2:3273
+168:2:3278
+169:2:3279
+170:2:3290
+171:2:3291
+172:2:3292
+173:2:3303
+174:2:3308
+175:2:3309
+176:2:3320
+177:2:3321
+178:2:3322
+179:2:3320
+180:2:3321
+181:2:3322
+182:2:3333
+183:2:3344
+184:2:3345
+185:0:4650
+186:2:2888
+187:0:4650
+188:2:3351
+189:2:3352
+190:2:3356
+191:2:3357
+192:2:3365
+193:2:3366
+194:2:3370
+195:2:3371
+196:2:3379
+197:2:3384
+198:2:3388
+199:2:3389
+200:2:3397
+201:2:3398
+202:2:3402
+203:2:3403
+204:2:3397
+205:2:3398
+206:2:3402
+207:2:3403
+208:2:3411
+209:2:3416
+210:2:3417
+211:2:3428
+212:2:3429
+213:2:3430
+214:2:3441
+215:2:3446
+216:2:3447
+217:2:3458
+218:2:3459
+219:2:3460
+220:2:3458
+221:2:3459
+222:2:3460
+223:2:3471
+224:0:4650
+225:2:2888
+226:0:4650
+227:2:3480
+228:2:3481
+229:2:3485
+230:2:3486
+231:2:3494
+232:2:3495
+233:2:3499
+234:2:3500
+235:2:3508
+236:2:3513
+237:2:3517
+238:2:3518
+239:2:3526
+240:2:3527
+241:2:3531
+242:2:3532
+243:2:3526
+244:2:3527
+245:2:3531
+246:2:3532
+247:2:3540
+248:2:3545
+249:2:3546
+250:2:3557
+251:2:3558
+252:2:3559
+253:2:3570
+254:2:3575
+255:2:3576
+256:2:3587
+257:2:3588
+258:2:3589
+259:2:3587
+260:2:3588
+261:2:3589
+262:2:3600
+263:2:3607
+264:0:4650
+265:2:2888
+266:0:4650
+267:2:3611
+268:2:3612
+269:2:3613
+270:2:3625
+271:2:3626
+272:2:3630
+273:2:3631
+274:2:3639
+275:2:3644
+276:2:3648
+277:2:3649
+278:2:3657
+279:2:3658
+280:2:3662
+281:2:3663
+282:2:3657
+283:2:3658
+284:2:3662
+285:2:3663
+286:2:3671
+287:2:3676
+288:2:3677
+289:2:3688
+290:2:3689
+291:2:3690
+292:2:3701
+293:2:3706
+294:2:3707
+295:2:3718
+296:2:3719
+297:2:3720
+298:2:3718
+299:2:3719
+300:2:3720
+301:2:3731
+302:2:3741
+303:2:3742
+304:0:4650
+305:2:2888
+306:0:4650
+307:2:3751
+308:2:3752
+309:0:4650
+310:2:2888
+311:0:4650
+312:2:3756
+313:0:4650
+314:2:3764
+315:0:4650
+316:2:2883
+317:0:4650
+318:2:2885
+319:0:4650
+320:2:2886
+321:0:4650
+322:2:2887
+323:0:4650
+324:2:2888
+325:0:4650
+326:2:2889
+327:2:2890
+328:2:2894
+329:2:2895
+330:2:2903
+331:2:2904
+332:2:2908
+333:2:2909
+334:2:2917
+335:2:2922
+336:2:2926
+337:2:2927
+338:2:2935
+339:2:2936
+340:2:2937
+341:2:2935
+342:2:2936
+343:2:2940
+344:2:2941
+345:2:2949
+346:2:2954
+347:2:2955
+348:2:2966
+349:2:2967
+350:2:2968
+351:2:2979
+352:2:2984
+353:2:2985
+354:2:2996
+355:2:2997
+356:2:2998
+357:2:2996
+358:2:2997
+359:2:2998
+360:2:3009
+361:2:3017
+362:0:4650
+363:2:2888
+364:0:4650
+365:2:3021
+366:2:3025
+367:2:3026
+368:2:3030
+369:2:3034
+370:2:3035
+371:2:3039
+372:2:3047
+373:2:3048
+374:2:3052
+375:2:3053
+376:2:3052
+377:2:3056
+378:2:3057
+379:2:3061
+380:0:4650
+381:2:2888
+382:0:4650
+383:2:3069
+384:2:3070
+385:2:3071
+386:0:4650
+387:2:2888
+388:0:4650
+389:2:3079
+390:0:4650
+391:2:2888
+392:0:4650
+393:2:3082
+394:2:3083
+395:2:3087
+396:2:3088
+397:2:3096
+398:2:3097
+399:2:3101
+400:2:3102
+401:2:3110
+402:2:3115
+403:2:3116
+404:2:3128
+405:2:3129
+406:2:3133
+407:2:3134
+408:2:3128
+409:2:3129
+410:2:3133
+411:2:3134
+412:2:3142
+413:2:3147
+414:2:3148
+415:2:3159
+416:2:3160
+417:2:3161
+418:2:3172
+419:2:3177
+420:2:3178
+421:2:3189
+422:2:3190
+423:2:3191
+424:2:3189
+425:2:3190
+426:2:3191
+427:2:3202
+428:2:3209
+429:0:4650
+430:2:2888
+431:0:4650
+432:2:3213
+433:2:3214
+434:2:3215
+435:2:3227
+436:2:3228
+437:2:3232
+438:2:3233
+439:2:3241
+440:2:3246
+441:2:3250
+442:2:3251
+443:2:3259
+444:2:3260
+445:2:3264
+446:2:3265
+447:2:3259
+448:2:3260
+449:2:3264
+450:2:3265
+451:2:3273
+452:2:3278
+453:2:3279
+454:2:3290
+455:2:3291
+456:2:3292
+457:2:3303
+458:2:3308
+459:2:3309
+460:2:3320
+461:2:3321
+462:2:3322
+463:2:3320
+464:2:3321
+465:2:3322
+466:2:3333
+467:2:3344
+468:2:3345
+469:0:4650
+470:2:2888
+471:0:4650
+472:2:3351
+473:2:3352
+474:2:3356
+475:2:3357
+476:2:3365
+477:2:3366
+478:2:3370
+479:2:3371
+480:2:3379
+481:2:3384
+482:2:3388
+483:2:3389
+484:2:3397
+485:2:3398
+486:2:3402
+487:2:3403
+488:2:3397
+489:2:3398
+490:2:3402
+491:2:3403
+492:2:3411
+493:2:3416
+494:2:3417
+495:2:3428
+496:2:3429
+497:2:3430
+498:2:3441
+499:2:3446
+500:2:3447
+501:2:3458
+502:2:3459
+503:2:3460
+504:2:3458
+505:2:3459
+506:2:3460
+507:2:3471
+508:0:4650
+509:2:2888
+510:0:4650
+511:2:3480
+512:2:3481
+513:2:3485
+514:2:3486
+515:2:3494
+516:2:3495
+517:2:3499
+518:2:3500
+519:2:3508
+520:2:3513
+521:2:3517
+522:2:3518
+523:2:3526
+524:2:3527
+525:2:3531
+526:2:3532
+527:2:3526
+528:2:3527
+529:2:3531
+530:2:3532
+531:2:3540
+532:2:3545
+533:2:3546
+534:2:3557
+535:2:3558
+536:2:3559
+537:2:3570
+538:2:3575
+539:2:3576
+540:2:3587
+541:2:3588
+542:2:3589
+543:2:3587
+544:2:3588
+545:2:3589
+546:2:3600
+547:2:3607
+548:0:4650
+549:2:2888
+550:0:4650
+551:2:3611
+552:2:3612
+553:2:3613
+554:2:3625
+555:2:3626
+556:2:3630
+557:2:3631
+558:2:3639
+559:2:3644
+560:2:3648
+561:2:3649
+562:2:3657
+563:2:3658
+564:2:3662
+565:2:3663
+566:2:3657
+567:2:3658
+568:2:3662
+569:2:3663
+570:2:3671
+571:2:3676
+572:2:3677
+573:2:3688
+574:2:3689
+575:2:3690
+576:2:3701
+577:2:3706
+578:2:3707
+579:2:3718
+580:2:3719
+581:2:3720
+582:2:3718
+583:2:3719
+584:2:3720
+585:2:3731
+586:2:3741
+587:2:3742
+588:0:4650
+589:2:2888
+590:0:4650
+591:2:3751
+592:2:3752
+593:0:4650
+594:2:2888
+595:0:4650
+596:2:3756
+597:0:4650
+598:2:3764
+599:0:4650
+600:2:2883
+601:0:4650
+602:2:2885
+603:0:4650
+604:2:2886
+605:0:4650
+606:2:2887
+607:0:4650
+608:2:2888
+609:0:4650
+610:2:2889
+611:2:2890
+612:2:2894
+613:2:2895
+614:2:2903
+615:2:2904
+616:2:2908
+617:2:2909
+618:2:2917
+619:2:2922
+620:2:2926
+621:2:2927
+622:2:2935
+623:2:2936
+624:2:2940
+625:2:2941
+626:2:2935
+627:2:2936
+628:2:2937
+629:2:2949
+630:2:2954
+631:2:2955
+632:2:2966
+633:2:2967
+634:2:2968
+635:2:2979
+636:2:2984
+637:2:2985
+638:2:2996
+639:2:2997
+640:2:2998
+641:2:2996
+642:2:2997
+643:2:2998
+644:2:3009
+645:2:3017
+646:0:4650
+647:2:2888
+648:0:4650
+649:2:3021
+650:2:3025
+651:2:3026
+652:2:3030
+653:2:3034
+654:2:3035
+655:2:3039
+656:2:3047
+657:2:3048
+658:2:3052
+659:2:3056
+660:2:3057
+661:2:3052
+662:2:3053
+663:2:3061
+664:0:4650
+665:2:2888
+666:0:4650
+667:2:3069
+668:2:3070
+669:2:3071
+670:0:4650
+671:2:2888
+672:0:4650
+673:2:3079
+674:0:4650
+675:2:2888
+676:0:4650
+677:2:3082
+678:2:3083
+679:2:3087
+680:2:3088
+681:2:3096
+682:2:3097
+683:2:3101
+684:2:3102
+685:2:3110
+686:2:3115
+687:2:3116
+688:2:3128
+689:2:3129
+690:2:3133
+691:2:3134
+692:2:3128
+693:2:3129
+694:2:3133
+695:2:3134
+696:2:3142
+697:2:3147
+698:2:3148
+699:2:3159
+700:2:3160
+701:2:3161
+702:2:3172
+703:2:3177
+704:2:3178
+705:2:3189
+706:2:3190
+707:2:3191
+708:2:3189
+709:2:3190
+710:2:3191
+711:2:3202
+712:2:3209
+713:0:4650
+714:2:2888
+715:0:4650
+716:2:3213
+717:2:3214
+718:2:3215
+719:2:3227
+720:2:3228
+721:2:3232
+722:2:3233
+723:2:3241
+724:2:3246
+725:2:3250
+726:2:3251
+727:2:3259
+728:2:3260
+729:2:3264
+730:2:3265
+731:2:3259
+732:2:3260
+733:2:3264
+734:2:3265
+735:2:3273
+736:2:3278
+737:2:3279
+738:2:3290
+739:2:3291
+740:2:3292
+741:2:3303
+742:2:3308
+743:2:3309
+744:2:3320
+745:2:3321
+746:2:3322
+747:2:3320
+748:2:3321
+749:2:3322
+750:2:3333
+751:2:3344
+752:2:3345
+753:0:4650
+754:2:2888
+755:0:4650
+756:2:3351
+757:2:3352
+758:2:3356
+759:2:3357
+760:2:3365
+761:2:3366
+762:2:3370
+763:2:3371
+764:2:3379
+765:2:3384
+766:2:3388
+767:2:3389
+768:2:3397
+769:2:3398
+770:2:3402
+771:2:3403
+772:2:3397
+773:2:3398
+774:2:3402
+775:2:3403
+776:2:3411
+777:2:3416
+778:2:3417
+779:2:3428
+780:2:3429
+781:2:3430
+782:2:3441
+783:2:3446
+784:2:3447
+785:2:3458
+786:2:3459
+787:2:3460
+788:2:3458
+789:2:3459
+790:2:3460
+791:2:3471
+792:0:4650
+793:2:2888
+794:0:4650
+795:2:3611
+796:2:3612
+797:2:3616
+798:2:3617
+799:2:3625
+800:2:3626
+801:2:3630
+802:2:3631
+803:2:3639
+804:2:3644
+805:2:3648
+806:2:3649
+807:2:3657
+808:2:3658
+809:2:3662
+810:2:3663
+811:2:3657
+812:2:3658
+813:2:3662
+814:2:3663
+815:2:3671
+816:2:3676
+817:2:3677
+818:2:3688
+819:2:3689
+820:2:3690
+821:2:3701
+822:2:3706
+823:2:3707
+824:2:3718
+825:2:3719
+826:2:3720
+827:2:3718
+828:2:3719
+829:2:3720
+830:2:3731
+831:2:3741
+832:2:3742
+833:0:4650
+834:2:2888
+835:0:4650
+836:2:3751
+837:2:3752
+838:0:4650
+839:2:2888
+840:0:4650
+841:2:3480
+842:2:3481
+843:2:3485
+844:2:3486
+845:2:3494
+846:2:3495
+847:2:3499
+848:2:3500
+849:2:3508
+850:2:3513
+851:2:3517
+852:2:3518
+853:2:3526
+854:2:3527
+855:2:3528
+856:2:3526
+857:2:3527
+858:2:3531
+859:2:3532
+860:2:3540
+861:2:3545
+862:2:3546
+863:2:3557
+864:2:3558
+865:2:3559
+866:2:3570
+867:2:3575
+868:2:3576
+869:2:3587
+870:2:3588
+871:2:3589
+872:2:3587
+873:2:3588
+874:2:3589
+875:2:3600
+876:2:3607
+877:0:4650
+878:2:2888
+879:0:4650
+880:2:3756
+881:0:4650
+882:2:3764
+883:0:4650
+884:2:3765
+885:0:4650
+886:2:3770
+887:0:4650
+888:1:2
+889:0:4650
+890:2:3771
+891:0:4650
+892:1:8
+893:0:4650
+894:2:3770
+895:0:4650
+896:1:9
+897:0:4650
+898:2:3771
+899:0:4650
+900:1:10
+901:0:4650
+902:2:3770
+903:0:4650
+904:1:11
+905:0:4650
+906:2:3771
+907:0:4650
+908:1:12
+909:0:4650
+910:2:3770
+911:0:4650
+912:1:13
+913:0:4650
+914:2:3771
+915:0:4650
+916:1:14
+917:0:4650
+918:2:3770
+919:0:4650
+920:1:15
+921:0:4650
+922:2:3771
+923:0:4650
+924:1:16
+925:0:4650
+926:2:3770
+927:0:4650
+928:1:17
+929:0:4650
+930:2:3771
+931:0:4650
+932:1:18
+933:0:4650
+934:2:3770
+935:0:4650
+936:1:19
+937:0:4650
+938:2:3771
+939:0:4650
+940:1:20
+941:0:4650
+942:2:3770
+943:0:4650
+944:1:21
+945:0:4650
+946:2:3771
+947:0:4650
+948:1:124
+949:0:4650
+950:2:3770
+951:0:4650
+952:1:23
+953:0:4650
+954:2:3771
+955:0:4650
+956:1:131
+957:1:132
+958:1:136
+959:1:137
+960:1:145
+961:1:146
+962:1:150
+963:1:151
+964:1:159
+965:1:164
+966:1:168
+967:1:169
+968:1:177
+969:1:178
+970:1:182
+971:1:183
+972:1:177
+973:1:178
+974:1:182
+975:1:183
+976:1:191
+977:1:196
+978:1:197
+979:1:208
+980:1:209
+981:1:210
+982:1:221
+983:1:233
+984:1:234
+985:1:238
+986:1:239
+987:1:240
+988:1:238
+989:1:239
+990:1:240
+991:1:251
+992:0:4650
+993:2:3770
+994:0:4650
+995:1:19
+996:0:4650
+997:2:3771
+998:0:4650
+999:1:20
+1000:0:4650
+1001:2:3770
+1002:0:4650
+1003:1:21
+1004:0:4650
+1005:2:3771
+1006:0:4650
+1007:1:124
+1008:0:4650
+1009:2:3770
+1010:0:4650
+1011:1:23
+1012:0:4650
+1013:2:3771
+1014:0:4650
+1015:1:260
+1016:1:261
+1017:0:4650
+1018:2:3770
+1019:0:4650
+1020:1:19
+1021:0:4650
+1022:2:3771
+1023:0:4650
+1024:1:20
+1025:0:4650
+1026:2:3770
+1027:0:4650
+1028:1:21
+1029:0:4650
+1030:2:3771
+1031:0:4650
+1032:1:124
+1033:0:4650
+1034:2:3770
+1035:0:4650
+1036:1:23
+1037:0:4650
+1038:2:3771
+1039:0:4650
+1040:1:267
+1041:1:268
+1042:1:272
+1043:1:273
+1044:1:281
+1045:1:282
+1046:1:286
+1047:1:287
+1048:1:295
+1049:1:300
+1050:1:304
+1051:1:305
+1052:1:313
+1053:1:314
+1054:1:318
+1055:1:319
+1056:1:313
+1057:1:314
+1058:1:318
+1059:1:319
+1060:1:327
+1061:1:332
+1062:1:333
+1063:1:344
+1064:1:345
+1065:1:346
+1066:1:357
+1067:1:369
+1068:1:370
+1069:1:374
+1070:1:375
+1071:1:376
+1072:1:374
+1073:1:375
+1074:1:376
+1075:1:387
+1076:0:4650
+1077:2:3770
+1078:0:4650
+1079:1:19
+1080:0:4650
+1081:2:3771
+1082:0:4650
+1083:1:20
+1084:0:4650
+1085:2:3770
+1086:0:4650
+1087:1:21
+1088:0:4650
+1089:2:3771
+1090:0:4650
+1091:1:124
+1092:0:4650
+1093:2:3770
+1094:0:4650
+1095:1:23
+1096:0:4650
+1097:2:3771
+1098:0:4650
+1099:1:396
+1100:1:397
+1101:1:401
+1102:1:402
+1103:1:410
+1104:1:411
+1105:1:415
+1106:1:416
+1107:1:424
+1108:1:429
+1109:1:433
+1110:1:434
+1111:1:442
+1112:1:443
+1113:1:447
+1114:1:448
+1115:1:442
+1116:1:443
+1117:1:447
+1118:1:448
+1119:1:456
+1120:1:461
+1121:1:462
+1122:1:473
+1123:1:474
+1124:1:475
+1125:1:486
+1126:1:498
+1127:1:499
+1128:1:503
+1129:1:504
+1130:1:505
+1131:1:503
+1132:1:504
+1133:1:505
+1134:1:516
+1135:1:523
+1136:0:4650
+1137:2:3770
+1138:0:4650
+1139:1:19
+1140:0:4650
+1141:2:3771
+1142:0:4650
+1143:1:20
+1144:0:4650
+1145:2:3770
+1146:0:4650
+1147:1:21
+1148:0:4650
+1149:2:3771
+1150:0:4650
+1151:1:124
+1152:0:4650
+1153:2:3770
+1154:0:4650
+1155:1:23
+1156:0:4650
+1157:2:3771
+1158:0:4650
+1159:1:661
+1160:1:662
+1161:1:666
+1162:1:667
+1163:1:675
+1164:1:676
+1165:1:677
+1166:1:689
+1167:1:694
+1168:1:698
+1169:1:699
+1170:1:707
+1171:1:708
+1172:1:712
+1173:1:713
+1174:1:707
+1175:1:708
+1176:1:712
+1177:1:713
+1178:1:721
+1179:1:726
+1180:1:727
+1181:1:738
+1182:1:739
+1183:1:740
+1184:1:751
+1185:1:763
+1186:1:764
+1187:1:768
+1188:1:769
+1189:1:770
+1190:1:768
+1191:1:769
+1192:1:770
+1193:1:781
+1194:0:4650
+1195:2:3770
+1196:0:4650
+1197:1:19
+1198:0:4650
+1199:2:3771
+1200:0:4650
+1201:1:20
+1202:0:4650
+1203:2:3770
+1204:0:4650
+1205:1:21
+1206:0:4650
+1207:2:3771
+1208:0:4650
+1209:1:124
+1210:0:4650
+1211:2:3770
+1212:0:4650
+1213:1:23
+1214:0:4650
+1215:2:3771
+1216:0:4650
+1217:1:790
+1218:1:793
+1219:1:794
+1220:0:4650
+1221:2:3770
+1222:0:4650
+1223:1:19
+1224:0:4650
+1225:2:3771
+1226:0:4650
+1227:1:20
+1228:0:4650
+1229:2:3770
+1230:0:4650
+1231:1:21
+1232:0:4650
+1233:2:3771
+1234:0:4650
+1235:1:124
+1236:0:4650
+1237:2:3770
+1238:0:4650
+1239:1:23
+1240:0:4650
+1241:2:3771
+1242:0:4650
+1243:1:1057
+1244:1:1058
+1245:1:1062
+1246:1:1063
+1247:1:1071
+1248:1:1072
+1249:1:1076
+1250:1:1077
+1251:1:1085
+1252:1:1090
+1253:1:1094
+1254:1:1095
+1255:1:1103
+1256:1:1104
+1257:1:1108
+1258:1:1109
+1259:1:1103
+1260:1:1104
+1261:1:1108
+1262:1:1109
+1263:1:1117
+1264:1:1122
+1265:1:1123
+1266:1:1134
+1267:1:1135
+1268:1:1136
+1269:1:1147
+1270:1:1159
+1271:1:1160
+1272:1:1164
+1273:1:1165
+1274:1:1166
+1275:1:1164
+1276:1:1165
+1277:1:1166
+1278:1:1177
+1279:1:1184
+1280:1:1188
+1281:0:4650
+1282:2:3770
+1283:0:4650
+1284:1:19
+1285:0:4650
+1286:2:3771
+1287:0:4650
+1288:1:20
+1289:0:4650
+1290:2:3770
+1291:0:4650
+1292:1:21
+1293:0:4650
+1294:2:3771
+1295:0:4650
+1296:1:124
+1297:0:4650
+1298:2:3770
+1299:0:4650
+1300:1:23
+1301:0:4650
+1302:2:3771
+1303:0:4650
+1304:1:1189
+1305:1:1190
+1306:1:1194
+1307:1:1195
+1308:1:1203
+1309:1:1204
+1310:1:1205
+1311:1:1217
+1312:1:1222
+1313:1:1226
+1314:1:1227
+1315:1:1235
+1316:1:1236
+1317:1:1240
+1318:1:1241
+1319:1:1235
+1320:1:1236
+1321:1:1240
+1322:1:1241
+1323:1:1249
+1324:1:1254
+1325:1:1255
+1326:1:1266
+1327:1:1267
+1328:1:1268
+1329:1:1279
+1330:1:1291
+1331:1:1292
+1332:1:1296
+1333:1:1297
+1334:1:1298
+1335:1:1296
+1336:1:1297
+1337:1:1298
+1338:1:1309
+1339:0:4650
+1340:2:3770
+1341:0:4650
+1342:1:19
+1343:0:4650
+1344:2:3771
+1345:0:4650
+1346:1:20
+1347:0:4650
+1348:2:3770
+1349:0:4650
+1350:1:21
+1351:0:4650
+1352:2:3771
+1353:0:4650
+1354:1:124
+1355:0:4650
+1356:2:3770
+1357:0:4650
+1358:1:23
+1359:0:4650
+1360:2:3771
+1361:0:4650
+1362:1:1318
+1363:0:4650
+1364:2:3770
+1365:0:4650
+1366:1:2782
+1367:1:2789
+1368:1:2790
+1369:1:2797
+1370:1:2802
+1371:1:2809
+1372:1:2810
+1373:1:2809
+1374:1:2810
+1375:1:2817
+1376:1:2821
+1377:0:4650
+1378:2:3771
+1379:0:4650
+1380:1:1320
+1381:1:1321
+1382:0:4648
+1383:2:3770
+1384:0:4654
+1385:1:1438
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_rmb.define b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_rmb.define
new file mode 100644 (file)
index 0000000..73e61a4
--- /dev/null
@@ -0,0 +1 @@
+#define NO_RMB
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_rmb.log b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_rmb.log
new file mode 100644 (file)
index 0000000..43a1b71
--- /dev/null
@@ -0,0 +1,592 @@
+make[1]: Entering directory `/home/compudj/doc/userspace-rcu/formal-model/urcu-controldataflow'
+rm -f pan* trail.out .input.spin* *.spin.trail .input.define
+touch .input.define
+cat .input.define >> pan.ltl
+cat DEFINES >> pan.ltl
+spin -f "!(`cat urcu_free.ltl | grep -v ^//`)" >> pan.ltl
+cp urcu_free_no_rmb.define .input.define
+cat .input.define > .input.spin
+cat DEFINES >> .input.spin
+cat urcu.spin >> .input.spin
+rm -f .input.spin.trail
+spin -a -X -N pan.ltl .input.spin
+Exit-Status 0
+gcc -O2 -w -DHASH64 -o pan pan.c
+./pan -a -v -c1 -X -m10000000 -w20
+warning: for p.o. reduction to be valid the never claim must be stutter-invariant
+(never claims generated from LTL formulae are stutter-invariant)
+depth 0: Claim reached state 5 (line 1245)
+Depth=    8403 States=    1e+06 Transitions= 2.27e+08 Memory=   550.432        t=    277 R=   4e+03
+Depth=   10017 States=    2e+06 Transitions= 4.61e+08 Memory=   634.318        t=    573 R=   3e+03
+Depth=   10017 States=    3e+06 Transitions=  7.1e+08 Memory=   718.303        t=    888 R=   3e+03
+pan: resizing hashtable to -w22..  done
+Depth=   10017 States=    4e+06 Transitions=  9.4e+08 Memory=   833.311        t= 1.17e+03 R=   3e+03
+Depth=   10017 States=    5e+06 Transitions=  1.2e+09 Memory=   917.295        t= 1.49e+03 R=   3e+03
+Depth=   10017 States=    6e+06 Transitions= 1.73e+09 Memory=  1001.279        t= 2.17e+03 R=   3e+03
+Depth=   10017 States=    7e+06 Transitions= 2.17e+09 Memory=  1085.264        t= 2.72e+03 R=   3e+03
+Depth=   10017 States=    8e+06 Transitions= 2.56e+09 Memory=  1169.151        t= 3.23e+03 R=   2e+03
+Depth=   10017 States=    9e+06 Transitions= 2.96e+09 Memory=  1253.135        t= 3.74e+03 R=   2e+03
+pan: resizing hashtable to -w24..  done
+pan: claim violated! (at depth 1606)
+pan: wrote .input.spin.trail
+
+(Spin Version 5.1.7 -- 23 December 2008)
+Warning: Search not completed
+       + Partial Order Reduction
+
+Full statespace search for:
+       never claim             +
+       assertion violations    + (if within scope of claim)
+       acceptance   cycles     + (fairness disabled)
+       invalid end states      - (disabled by never claim)
+
+State-vector 88 byte, depth reached 10017, errors: 1
+  9005656 states, stored
+2.9547657e+09 states, matched
+2.9637714e+09 transitions (= stored+matched)
+1.6918577e+10 atomic steps
+hash conflicts: 2.3126803e+09 (resolved)
+
+Stats on memory usage (in Megabytes):
+  996.262      equivalent memory usage for states (stored*(State-vector + overhead))
+  795.835      actual memory usage for states (compression: 79.88%)
+               state-vector as stored = 65 byte + 28 byte overhead
+  128.000      memory used for hash table (-w24)
+  457.764      memory used for DFS stack (-m10000000)
+ 1381.135      total actual memory usage
+
+unreached in proctype urcu_reader
+       line 250, "pan.___", state 32, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 54, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 63, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 79, "(1)"
+       line 231, "pan.___", state 87, "(1)"
+       line 235, "pan.___", state 99, "(1)"
+       line 239, "pan.___", state 107, "(1)"
+       line 387, "pan.___", state 132, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 164, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 178, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 197, "(1)"
+       line 413, "pan.___", state 227, "(1)"
+       line 417, "pan.___", state 240, "(1)"
+       line 663, "pan.___", state 261, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<1))"
+       line 387, "pan.___", state 268, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 300, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 314, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 333, "(1)"
+       line 413, "pan.___", state 363, "(1)"
+       line 417, "pan.___", state 376, "(1)"
+       line 387, "pan.___", state 397, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 429, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 443, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 462, "(1)"
+       line 413, "pan.___", state 492, "(1)"
+       line 417, "pan.___", state 505, "(1)"
+       line 387, "pan.___", state 528, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 530, "(1)"
+       line 387, "pan.___", state 531, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 387, "pan.___", state 531, "else"
+       line 387, "pan.___", state 534, "(1)"
+       line 391, "pan.___", state 542, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 544, "(1)"
+       line 391, "pan.___", state 545, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 391, "pan.___", state 545, "else"
+       line 391, "pan.___", state 548, "(1)"
+       line 391, "pan.___", state 549, "(1)"
+       line 391, "pan.___", state 549, "(1)"
+       line 389, "pan.___", state 554, "((i<1))"
+       line 389, "pan.___", state 554, "((i>=1))"
+       line 396, "pan.___", state 560, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 562, "(1)"
+       line 396, "pan.___", state 563, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 563, "else"
+       line 396, "pan.___", state 566, "(1)"
+       line 396, "pan.___", state 567, "(1)"
+       line 396, "pan.___", state 567, "(1)"
+       line 400, "pan.___", state 574, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 576, "(1)"
+       line 400, "pan.___", state 577, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 577, "else"
+       line 400, "pan.___", state 580, "(1)"
+       line 400, "pan.___", state 581, "(1)"
+       line 400, "pan.___", state 581, "(1)"
+       line 398, "pan.___", state 586, "((i<2))"
+       line 398, "pan.___", state 586, "((i>=2))"
+       line 404, "pan.___", state 593, "(1)"
+       line 404, "pan.___", state 594, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 594, "else"
+       line 404, "pan.___", state 597, "(1)"
+       line 404, "pan.___", state 598, "(1)"
+       line 404, "pan.___", state 598, "(1)"
+       line 408, "pan.___", state 606, "(1)"
+       line 408, "pan.___", state 607, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 607, "else"
+       line 408, "pan.___", state 610, "(1)"
+       line 408, "pan.___", state 611, "(1)"
+       line 408, "pan.___", state 611, "(1)"
+       line 406, "pan.___", state 616, "((i<1))"
+       line 406, "pan.___", state 616, "((i>=1))"
+       line 413, "pan.___", state 623, "(1)"
+       line 413, "pan.___", state 624, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 624, "else"
+       line 413, "pan.___", state 627, "(1)"
+       line 413, "pan.___", state 628, "(1)"
+       line 413, "pan.___", state 628, "(1)"
+       line 417, "pan.___", state 636, "(1)"
+       line 417, "pan.___", state 637, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 637, "else"
+       line 417, "pan.___", state 640, "(1)"
+       line 417, "pan.___", state 641, "(1)"
+       line 417, "pan.___", state 641, "(1)"
+       line 415, "pan.___", state 646, "((i<2))"
+       line 415, "pan.___", state 646, "((i>=2))"
+       line 422, "pan.___", state 650, "(1)"
+       line 422, "pan.___", state 650, "(1)"
+       line 663, "pan.___", state 653, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 663, "pan.___", state 654, "_proc_urcu_reader = (_proc_urcu_reader|(1<<5))"
+       line 663, "pan.___", state 655, "(1)"
+       line 387, "pan.___", state 662, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 694, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 708, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 727, "(1)"
+       line 413, "pan.___", state 757, "(1)"
+       line 417, "pan.___", state 770, "(1)"
+       line 387, "pan.___", state 798, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 800, "(1)"
+       line 387, "pan.___", state 801, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 387, "pan.___", state 801, "else"
+       line 387, "pan.___", state 804, "(1)"
+       line 391, "pan.___", state 812, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 814, "(1)"
+       line 391, "pan.___", state 815, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 391, "pan.___", state 815, "else"
+       line 391, "pan.___", state 818, "(1)"
+       line 391, "pan.___", state 819, "(1)"
+       line 391, "pan.___", state 819, "(1)"
+       line 389, "pan.___", state 824, "((i<1))"
+       line 389, "pan.___", state 824, "((i>=1))"
+       line 396, "pan.___", state 830, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 832, "(1)"
+       line 396, "pan.___", state 833, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 833, "else"
+       line 396, "pan.___", state 836, "(1)"
+       line 396, "pan.___", state 837, "(1)"
+       line 396, "pan.___", state 837, "(1)"
+       line 400, "pan.___", state 844, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 846, "(1)"
+       line 400, "pan.___", state 847, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 847, "else"
+       line 400, "pan.___", state 850, "(1)"
+       line 400, "pan.___", state 851, "(1)"
+       line 400, "pan.___", state 851, "(1)"
+       line 398, "pan.___", state 856, "((i<2))"
+       line 398, "pan.___", state 856, "((i>=2))"
+       line 404, "pan.___", state 863, "(1)"
+       line 404, "pan.___", state 864, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 864, "else"
+       line 404, "pan.___", state 867, "(1)"
+       line 404, "pan.___", state 868, "(1)"
+       line 404, "pan.___", state 868, "(1)"
+       line 408, "pan.___", state 876, "(1)"
+       line 408, "pan.___", state 877, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 877, "else"
+       line 408, "pan.___", state 880, "(1)"
+       line 408, "pan.___", state 881, "(1)"
+       line 408, "pan.___", state 881, "(1)"
+       line 406, "pan.___", state 886, "((i<1))"
+       line 406, "pan.___", state 886, "((i>=1))"
+       line 413, "pan.___", state 893, "(1)"
+       line 413, "pan.___", state 894, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 894, "else"
+       line 413, "pan.___", state 897, "(1)"
+       line 413, "pan.___", state 898, "(1)"
+       line 413, "pan.___", state 898, "(1)"
+       line 417, "pan.___", state 906, "(1)"
+       line 417, "pan.___", state 907, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 907, "else"
+       line 417, "pan.___", state 910, "(1)"
+       line 417, "pan.___", state 911, "(1)"
+       line 417, "pan.___", state 911, "(1)"
+       line 422, "pan.___", state 920, "(1)"
+       line 422, "pan.___", state 920, "(1)"
+       line 387, "pan.___", state 927, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 929, "(1)"
+       line 387, "pan.___", state 930, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 387, "pan.___", state 930, "else"
+       line 387, "pan.___", state 933, "(1)"
+       line 391, "pan.___", state 941, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 943, "(1)"
+       line 391, "pan.___", state 944, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 391, "pan.___", state 944, "else"
+       line 391, "pan.___", state 947, "(1)"
+       line 391, "pan.___", state 948, "(1)"
+       line 391, "pan.___", state 948, "(1)"
+       line 389, "pan.___", state 953, "((i<1))"
+       line 389, "pan.___", state 953, "((i>=1))"
+       line 396, "pan.___", state 959, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 961, "(1)"
+       line 396, "pan.___", state 962, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 962, "else"
+       line 396, "pan.___", state 965, "(1)"
+       line 396, "pan.___", state 966, "(1)"
+       line 396, "pan.___", state 966, "(1)"
+       line 400, "pan.___", state 973, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 975, "(1)"
+       line 400, "pan.___", state 976, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 976, "else"
+       line 400, "pan.___", state 979, "(1)"
+       line 400, "pan.___", state 980, "(1)"
+       line 400, "pan.___", state 980, "(1)"
+       line 398, "pan.___", state 985, "((i<2))"
+       line 398, "pan.___", state 985, "((i>=2))"
+       line 404, "pan.___", state 992, "(1)"
+       line 404, "pan.___", state 993, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 993, "else"
+       line 404, "pan.___", state 996, "(1)"
+       line 404, "pan.___", state 997, "(1)"
+       line 404, "pan.___", state 997, "(1)"
+       line 408, "pan.___", state 1005, "(1)"
+       line 408, "pan.___", state 1006, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 1006, "else"
+       line 408, "pan.___", state 1009, "(1)"
+       line 408, "pan.___", state 1010, "(1)"
+       line 408, "pan.___", state 1010, "(1)"
+       line 406, "pan.___", state 1015, "((i<1))"
+       line 406, "pan.___", state 1015, "((i>=1))"
+       line 413, "pan.___", state 1022, "(1)"
+       line 413, "pan.___", state 1023, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 1023, "else"
+       line 413, "pan.___", state 1026, "(1)"
+       line 413, "pan.___", state 1027, "(1)"
+       line 413, "pan.___", state 1027, "(1)"
+       line 417, "pan.___", state 1035, "(1)"
+       line 417, "pan.___", state 1036, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 1036, "else"
+       line 417, "pan.___", state 1039, "(1)"
+       line 417, "pan.___", state 1040, "(1)"
+       line 417, "pan.___", state 1040, "(1)"
+       line 415, "pan.___", state 1045, "((i<2))"
+       line 415, "pan.___", state 1045, "((i>=2))"
+       line 422, "pan.___", state 1049, "(1)"
+       line 422, "pan.___", state 1049, "(1)"
+       line 671, "pan.___", state 1053, "_proc_urcu_reader = (_proc_urcu_reader|(1<<11))"
+       line 387, "pan.___", state 1058, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1090, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1104, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1123, "(1)"
+       line 413, "pan.___", state 1153, "(1)"
+       line 417, "pan.___", state 1166, "(1)"
+       line 387, "pan.___", state 1190, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1222, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1236, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1255, "(1)"
+       line 413, "pan.___", state 1285, "(1)"
+       line 417, "pan.___", state 1298, "(1)"
+       line 387, "pan.___", state 1323, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1355, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1369, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1388, "(1)"
+       line 413, "pan.___", state 1418, "(1)"
+       line 417, "pan.___", state 1431, "(1)"
+       line 387, "pan.___", state 1452, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1484, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1498, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1517, "(1)"
+       line 413, "pan.___", state 1547, "(1)"
+       line 417, "pan.___", state 1560, "(1)"
+       line 387, "pan.___", state 1586, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1618, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1632, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1651, "(1)"
+       line 413, "pan.___", state 1681, "(1)"
+       line 417, "pan.___", state 1694, "(1)"
+       line 387, "pan.___", state 1715, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1747, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1761, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1780, "(1)"
+       line 413, "pan.___", state 1810, "(1)"
+       line 417, "pan.___", state 1823, "(1)"
+       line 387, "pan.___", state 1847, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1879, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1893, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1912, "(1)"
+       line 413, "pan.___", state 1942, "(1)"
+       line 417, "pan.___", state 1955, "(1)"
+       line 710, "pan.___", state 1976, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<19))"
+       line 387, "pan.___", state 1983, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2015, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2029, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2048, "(1)"
+       line 413, "pan.___", state 2078, "(1)"
+       line 417, "pan.___", state 2091, "(1)"
+       line 387, "pan.___", state 2112, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2144, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2158, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2177, "(1)"
+       line 413, "pan.___", state 2207, "(1)"
+       line 417, "pan.___", state 2220, "(1)"
+       line 387, "pan.___", state 2243, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 2245, "(1)"
+       line 387, "pan.___", state 2246, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 387, "pan.___", state 2246, "else"
+       line 387, "pan.___", state 2249, "(1)"
+       line 391, "pan.___", state 2257, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 2259, "(1)"
+       line 391, "pan.___", state 2260, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 391, "pan.___", state 2260, "else"
+       line 391, "pan.___", state 2263, "(1)"
+       line 391, "pan.___", state 2264, "(1)"
+       line 391, "pan.___", state 2264, "(1)"
+       line 389, "pan.___", state 2269, "((i<1))"
+       line 389, "pan.___", state 2269, "((i>=1))"
+       line 396, "pan.___", state 2275, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2277, "(1)"
+       line 396, "pan.___", state 2278, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 2278, "else"
+       line 396, "pan.___", state 2281, "(1)"
+       line 396, "pan.___", state 2282, "(1)"
+       line 396, "pan.___", state 2282, "(1)"
+       line 400, "pan.___", state 2289, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2291, "(1)"
+       line 400, "pan.___", state 2292, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 2292, "else"
+       line 400, "pan.___", state 2295, "(1)"
+       line 400, "pan.___", state 2296, "(1)"
+       line 400, "pan.___", state 2296, "(1)"
+       line 398, "pan.___", state 2301, "((i<2))"
+       line 398, "pan.___", state 2301, "((i>=2))"
+       line 404, "pan.___", state 2308, "(1)"
+       line 404, "pan.___", state 2309, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 2309, "else"
+       line 404, "pan.___", state 2312, "(1)"
+       line 404, "pan.___", state 2313, "(1)"
+       line 404, "pan.___", state 2313, "(1)"
+       line 408, "pan.___", state 2321, "(1)"
+       line 408, "pan.___", state 2322, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 2322, "else"
+       line 408, "pan.___", state 2325, "(1)"
+       line 408, "pan.___", state 2326, "(1)"
+       line 408, "pan.___", state 2326, "(1)"
+       line 406, "pan.___", state 2331, "((i<1))"
+       line 406, "pan.___", state 2331, "((i>=1))"
+       line 413, "pan.___", state 2338, "(1)"
+       line 413, "pan.___", state 2339, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 2339, "else"
+       line 413, "pan.___", state 2342, "(1)"
+       line 413, "pan.___", state 2343, "(1)"
+       line 413, "pan.___", state 2343, "(1)"
+       line 417, "pan.___", state 2351, "(1)"
+       line 417, "pan.___", state 2352, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 2352, "else"
+       line 417, "pan.___", state 2355, "(1)"
+       line 417, "pan.___", state 2356, "(1)"
+       line 417, "pan.___", state 2356, "(1)"
+       line 415, "pan.___", state 2361, "((i<2))"
+       line 415, "pan.___", state 2361, "((i>=2))"
+       line 422, "pan.___", state 2365, "(1)"
+       line 422, "pan.___", state 2365, "(1)"
+       line 710, "pan.___", state 2368, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 710, "pan.___", state 2369, "_proc_urcu_reader = (_proc_urcu_reader|(1<<23))"
+       line 710, "pan.___", state 2370, "(1)"
+       line 387, "pan.___", state 2377, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2409, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2423, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2442, "(1)"
+       line 413, "pan.___", state 2472, "(1)"
+       line 417, "pan.___", state 2485, "(1)"
+       line 387, "pan.___", state 2512, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2544, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2558, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2577, "(1)"
+       line 413, "pan.___", state 2607, "(1)"
+       line 417, "pan.___", state 2620, "(1)"
+       line 387, "pan.___", state 2641, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2673, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2687, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2706, "(1)"
+       line 413, "pan.___", state 2736, "(1)"
+       line 417, "pan.___", state 2749, "(1)"
+       line 387, "pan.___", state 2782, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2814, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2828, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2847, "(1)"
+       line 413, "pan.___", state 2877, "(1)"
+       line 417, "pan.___", state 2890, "(1)"
+       line 387, "pan.___", state 2909, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2941, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2955, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2974, "(1)"
+       line 413, "pan.___", state 3004, "(1)"
+       line 417, "pan.___", state 3017, "(1)"
+       line 870, "pan.___", state 3038, "-end-"
+       (284 of 3038 states)
+unreached in proctype urcu_writer
+       line 387, "pan.___", state 18, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 24, "(1)"
+       line 391, "pan.___", state 32, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 38, "(1)"
+       line 391, "pan.___", state 39, "(1)"
+       line 391, "pan.___", state 39, "(1)"
+       line 389, "pan.___", state 44, "((i<1))"
+       line 389, "pan.___", state 44, "((i>=1))"
+       line 396, "pan.___", state 50, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 56, "(1)"
+       line 396, "pan.___", state 57, "(1)"
+       line 396, "pan.___", state 57, "(1)"
+       line 400, "pan.___", state 70, "(1)"
+       line 400, "pan.___", state 71, "(1)"
+       line 400, "pan.___", state 71, "(1)"
+       line 398, "pan.___", state 76, "((i<2))"
+       line 398, "pan.___", state 76, "((i>=2))"
+       line 404, "pan.___", state 83, "(1)"
+       line 404, "pan.___", state 84, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 84, "else"
+       line 404, "pan.___", state 87, "(1)"
+       line 404, "pan.___", state 88, "(1)"
+       line 404, "pan.___", state 88, "(1)"
+       line 408, "pan.___", state 96, "(1)"
+       line 408, "pan.___", state 97, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 97, "else"
+       line 408, "pan.___", state 100, "(1)"
+       line 408, "pan.___", state 101, "(1)"
+       line 408, "pan.___", state 101, "(1)"
+       line 406, "pan.___", state 106, "((i<1))"
+       line 406, "pan.___", state 106, "((i>=1))"
+       line 413, "pan.___", state 113, "(1)"
+       line 413, "pan.___", state 114, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 114, "else"
+       line 413, "pan.___", state 117, "(1)"
+       line 413, "pan.___", state 118, "(1)"
+       line 413, "pan.___", state 118, "(1)"
+       line 417, "pan.___", state 126, "(1)"
+       line 417, "pan.___", state 127, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 127, "else"
+       line 417, "pan.___", state 130, "(1)"
+       line 417, "pan.___", state 131, "(1)"
+       line 417, "pan.___", state 131, "(1)"
+       line 415, "pan.___", state 136, "((i<2))"
+       line 415, "pan.___", state 136, "((i>=2))"
+       line 422, "pan.___", state 140, "(1)"
+       line 422, "pan.___", state 140, "(1)"
+       line 250, "pan.___", state 149, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 158, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 171, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 211, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 225, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 243, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 257, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 276, "(1)"
+       line 408, "pan.___", state 289, "(1)"
+       line 413, "pan.___", state 306, "(1)"
+       line 417, "pan.___", state 319, "(1)"
+       line 391, "pan.___", state 356, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 374, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 388, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 420, "(1)"
+       line 413, "pan.___", state 437, "(1)"
+       line 417, "pan.___", state 450, "(1)"
+       line 391, "pan.___", state 494, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 512, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 526, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 558, "(1)"
+       line 413, "pan.___", state 575, "(1)"
+       line 417, "pan.___", state 588, "(1)"
+       line 391, "pan.___", state 623, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 641, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 655, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 687, "(1)"
+       line 413, "pan.___", state 704, "(1)"
+       line 417, "pan.___", state 717, "(1)"
+       line 391, "pan.___", state 754, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 772, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 786, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 818, "(1)"
+       line 413, "pan.___", state 835, "(1)"
+       line 417, "pan.___", state 848, "(1)"
+       line 250, "pan.___", state 903, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 912, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 927, "(1)"
+       line 262, "pan.___", state 934, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 950, "(1)"
+       line 231, "pan.___", state 958, "(1)"
+       line 235, "pan.___", state 970, "(1)"
+       line 239, "pan.___", state 978, "(1)"
+       line 250, "pan.___", state 1009, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1018, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1031, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1040, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1056, "(1)"
+       line 231, "pan.___", state 1064, "(1)"
+       line 235, "pan.___", state 1076, "(1)"
+       line 239, "pan.___", state 1084, "(1)"
+       line 254, "pan.___", state 1110, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1123, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1132, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1148, "(1)"
+       line 231, "pan.___", state 1156, "(1)"
+       line 235, "pan.___", state 1168, "(1)"
+       line 239, "pan.___", state 1176, "(1)"
+       line 250, "pan.___", state 1207, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1216, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1229, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1238, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1254, "(1)"
+       line 231, "pan.___", state 1262, "(1)"
+       line 235, "pan.___", state 1274, "(1)"
+       line 239, "pan.___", state 1282, "(1)"
+       line 254, "pan.___", state 1308, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1321, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1330, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1346, "(1)"
+       line 231, "pan.___", state 1354, "(1)"
+       line 235, "pan.___", state 1366, "(1)"
+       line 239, "pan.___", state 1374, "(1)"
+       line 250, "pan.___", state 1405, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1414, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1427, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1436, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1452, "(1)"
+       line 231, "pan.___", state 1460, "(1)"
+       line 235, "pan.___", state 1472, "(1)"
+       line 239, "pan.___", state 1480, "(1)"
+       line 254, "pan.___", state 1506, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1519, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1528, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1544, "(1)"
+       line 231, "pan.___", state 1552, "(1)"
+       line 235, "pan.___", state 1564, "(1)"
+       line 239, "pan.___", state 1572, "(1)"
+       line 250, "pan.___", state 1603, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1612, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1625, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1634, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1650, "(1)"
+       line 231, "pan.___", state 1658, "(1)"
+       line 235, "pan.___", state 1670, "(1)"
+       line 239, "pan.___", state 1678, "(1)"
+       line 1191, "pan.___", state 1694, "-end-"
+       (128 of 1694 states)
+unreached in proctype :init:
+       line 1202, "pan.___", state 9, "((j<2))"
+       line 1202, "pan.___", state 9, "((j>=2))"
+       line 1203, "pan.___", state 20, "((j<2))"
+       line 1203, "pan.___", state 20, "((j>=2))"
+       line 1208, "pan.___", state 33, "((j<2))"
+       line 1208, "pan.___", state 33, "((j>=2))"
+       line 1206, "pan.___", state 43, "((i<1))"
+       line 1206, "pan.___", state 43, "((i>=1))"
+       line 1216, "pan.___", state 54, "((j<2))"
+       line 1216, "pan.___", state 54, "((j>=2))"
+       line 1220, "pan.___", state 67, "((j<2))"
+       line 1220, "pan.___", state 67, "((j>=2))"
+       (6 of 78 states)
+unreached in proctype :never:
+       line 1250, "pan.___", state 8, "-end-"
+       (1 of 8 states)
+
+pan: elapsed time 3.75e+03 seconds
+pan: rate 2403.4695 states/second
+pan: avg transition delay 1.2642e-06 usec
+cp .input.spin urcu_free_no_rmb.spin.input
+cp .input.spin.trail urcu_free_no_rmb.spin.input.trail
+make[1]: Leaving directory `/home/compudj/doc/userspace-rcu/formal-model/urcu-controldataflow'
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_rmb.spin.input b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_rmb.spin.input
new file mode 100644 (file)
index 0000000..c36940f
--- /dev/null
@@ -0,0 +1,1227 @@
+#define NO_RMB
+
+// Poison value for freed memory
+#define POISON 1
+// Memory with correct data
+#define WINE 0
+#define SLAB_SIZE 2
+
+#define read_poison    (data_read_first[0] == POISON || data_read_second[0] == POISON)
+
+#define RCU_GP_CTR_BIT (1 << 7)
+#define RCU_GP_CTR_NEST_MASK (RCU_GP_CTR_BIT - 1)
+
+//disabled
+#define REMOTE_BARRIERS
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+typedef per_proc_bit {
+       bit val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bitfield {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bitfield cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               smp_mb(i, j);
+               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
+               break;
+       od;
+}
+
+#ifdef WRITER_PROGRESS
+//#define PROGRESS_LABEL(progressid)   progress_writer_progid_##progressid:
+#define PROGRESS_LABEL(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;                                          \
+               /*                                                              \
+                * 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)                                                     \
+               do                                                              \
+               :: (reader_barrier[i] == 1) -> skip;                            \
+               :: (reader_barrier[i] == 0) -> break;                           \
+               od;                                                             \
+               i++;                                                            \
+       :: i >= NR_READERS ->                                                   \
+               break                                                           \
+       od;                                                                     \
+       smp_mb(i, j);                                                           \
+}
+
+#else
+
+#define smp_mb_send(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, smp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only one reader */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* RCU data */
+DECLARE_CACHED_VAR(bit, rcu_data[SLAB_SIZE]);
+
+/* RCU pointer */
+#if (SLAB_SIZE == 2)
+DECLARE_CACHED_VAR(bit, rcu_ptr);
+bit ptr_read_first[NR_READERS];
+bit ptr_read_second[NR_READERS];
+#else
+DECLARE_CACHED_VAR(byte, rcu_ptr);
+byte ptr_read_first[NR_READERS];
+byte ptr_read_second[NR_READERS];
+#endif
+
+bit data_read_first[NR_READERS];
+bit data_read_second[NR_READERS];
+
+bit init_done = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               :: 1 -> skip;
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               ptr_read_first[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb1;
+rmb1_end:
+                               data_read_first[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_first[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               ptr_read_second[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb2;
+rmb2_end:
+                               data_read_second[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_second[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+rmb1:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb1_end;
+rmb2:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_DATA                     (1 << 1)
+#define WRITE_PROC_WMB                 (1 << 2)
+#define WRITE_XCHG_PTR                 (1 << 3)
+
+#define WRITE_PROC_FIRST_MB            (1 << 4)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 5)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 6)
+#define WRITE_PROC_FIRST_WAIT          (1 << 7)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 8)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 9)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 10)
+#define WRITE_PROC_SECOND_WAIT         (1 << 11)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 12)
+
+#define WRITE_PROC_SECOND_MB           (1 << 13)
+
+#define WRITE_FREE                     (1 << 14)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_DATA                    \
+                                       | WRITE_PROC_WMB                \
+                                       | WRITE_XCHG_PTR                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB          \
+                                       | WRITE_FREE)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 15) - 1)
+
+/*
+ * Mutexes are implied around writer execution. A single writer at a time.
+ */
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte cur_data = 0, old_data, loop_nr = 0;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (loop_nr < 3) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               loop_nr = loop_nr + 1;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_WMB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+#endif
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_DATA) ->
+                       ooo_mem(i);
+                       cur_data = (cur_data + 1) % SLAB_SIZE;
+                       WRITE_CACHED_VAR(rcu_data[cur_data], WINE);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_DATA);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA,
+                                 WRITE_PROC_WMB) ->
+                       smp_wmb(i, j);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_WMB,
+                                 WRITE_XCHG_PTR) ->
+                       /* rcu_xchg_pointer() */
+                       atomic {
+                               old_data = READ_CACHED_VAR(rcu_ptr);
+                               WRITE_CACHED_VAR(rcu_ptr, cur_data);
+                       }
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_XCHG_PTR);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_WMB      /* No dependency on
+                                                        * WRITE_DATA because we
+                                                        * write to a
+                                                        * different location. */
+                                 | WRITE_PROC_SECOND_MB
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_FREE) ->
+                       WRITE_CACHED_VAR(rcu_data[old_data], POISON);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_FREE);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+               /*
+                * Note : Promela model adds implicit serialization of the
+                * WRITE_FREE instruction. Normally, it would be permitted to
+                * spill on the next loop execution. Given the validation we do
+                * checks for the data entry read to be poisoned, it's ok if
+                * we do not check "late arriving" memory poisoning.
+                */
+       :: 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
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(rcu_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       ptr_read_first[i] = 1;
+                       ptr_read_second[i] = 1;
+                       data_read_first[i] = WINE;
+                       data_read_second[i] = WINE;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               INIT_CACHED_VAR(rcu_data[0], WINE, j);
+               i = 1;
+               do
+               :: i < SLAB_SIZE ->
+                       INIT_CACHED_VAR(rcu_data[i], POISON, j);
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_rmb.spin.input.trail b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_rmb.spin.input.trail
new file mode 100644 (file)
index 0000000..abd4423
--- /dev/null
@@ -0,0 +1,1609 @@
+-2:3:-2
+-4:-4:-4
+1:0:4812
+2:3:4732
+3:3:4735
+4:3:4735
+5:3:4738
+6:3:4746
+7:3:4746
+8:3:4749
+9:3:4755
+10:3:4759
+11:3:4759
+12:3:4762
+13:3:4772
+14:3:4780
+15:3:4780
+16:3:4783
+17:3:4789
+18:3:4793
+19:3:4793
+20:3:4796
+21:3:4802
+22:3:4806
+23:3:4807
+24:0:4812
+25:3:4809
+26:0:4812
+27:2:3040
+28:0:4812
+29:2:3046
+30:0:4812
+31:2:3047
+32:0:4812
+33:2:3049
+34:0:4812
+35:2:3050
+36:0:4812
+37:2:3051
+38:2:3052
+39:2:3056
+40:2:3057
+41:2:3065
+42:2:3066
+43:2:3070
+44:2:3071
+45:2:3079
+46:2:3084
+47:2:3088
+48:2:3089
+49:2:3097
+50:2:3098
+51:2:3102
+52:2:3103
+53:2:3097
+54:2:3098
+55:2:3102
+56:2:3103
+57:2:3111
+58:2:3116
+59:2:3117
+60:2:3128
+61:2:3129
+62:2:3130
+63:2:3141
+64:2:3146
+65:2:3147
+66:2:3158
+67:2:3159
+68:2:3160
+69:2:3158
+70:2:3159
+71:2:3160
+72:2:3171
+73:2:3179
+74:0:4812
+75:2:3050
+76:0:4812
+77:2:3183
+78:2:3187
+79:2:3188
+80:2:3192
+81:2:3196
+82:2:3197
+83:2:3201
+84:2:3209
+85:2:3210
+86:2:3214
+87:2:3218
+88:2:3219
+89:2:3214
+90:2:3215
+91:2:3223
+92:0:4812
+93:2:3050
+94:0:4812
+95:2:3231
+96:2:3232
+97:2:3233
+98:0:4812
+99:2:3050
+100:0:4812
+101:2:3238
+102:0:4812
+103:2:3941
+104:2:3942
+105:2:3946
+106:2:3950
+107:2:3951
+108:2:3955
+109:2:3960
+110:2:3968
+111:2:3972
+112:2:3973
+113:2:3968
+114:2:3972
+115:2:3973
+116:2:3977
+117:2:3984
+118:2:3991
+119:2:3992
+120:2:3999
+121:2:4004
+122:2:4011
+123:2:4012
+124:2:4011
+125:2:4012
+126:2:4019
+127:2:4023
+128:0:4812
+129:2:4028
+130:0:4812
+131:2:4029
+132:0:4812
+133:2:4030
+134:0:4812
+135:2:4031
+136:0:4812
+137:1:2
+138:0:4812
+139:2:4032
+140:0:4812
+141:1:8
+142:0:4812
+143:1:9
+144:0:4812
+145:2:4031
+146:0:4812
+147:1:10
+148:0:4812
+149:2:4032
+150:0:4812
+151:1:11
+152:0:4812
+153:2:4031
+154:0:4812
+155:1:12
+156:0:4812
+157:2:4032
+158:0:4812
+159:1:13
+160:0:4812
+161:2:4031
+162:0:4812
+163:1:14
+164:0:4812
+165:2:4032
+166:0:4812
+167:1:15
+168:0:4812
+169:1:16
+170:0:4812
+171:2:4031
+172:0:4812
+173:1:17
+174:0:4812
+175:2:4032
+176:0:4812
+177:1:28
+178:0:4812
+179:2:4031
+180:0:4812
+181:1:32
+182:1:33
+183:1:37
+184:1:41
+185:1:42
+186:1:46
+187:1:54
+188:1:55
+189:1:59
+190:1:63
+191:1:64
+192:1:59
+193:1:63
+194:1:64
+195:1:68
+196:1:75
+197:1:82
+198:1:83
+199:1:90
+200:1:95
+201:1:102
+202:1:103
+203:1:102
+204:1:103
+205:1:110
+206:1:114
+207:0:4812
+208:2:4032
+209:0:4812
+210:1:119
+211:0:4812
+212:2:4033
+213:0:4812
+214:2:4038
+215:0:4812
+216:2:4039
+217:0:4812
+218:2:4047
+219:2:4048
+220:2:4052
+221:2:4056
+222:2:4057
+223:2:4061
+224:2:4069
+225:2:4070
+226:2:4074
+227:2:4078
+228:2:4079
+229:2:4074
+230:2:4078
+231:2:4079
+232:2:4083
+233:2:4090
+234:2:4097
+235:2:4098
+236:2:4105
+237:2:4110
+238:2:4117
+239:2:4118
+240:2:4117
+241:2:4118
+242:2:4125
+243:2:4129
+244:0:4812
+245:2:3240
+246:2:3922
+247:0:4812
+248:2:3050
+249:0:4812
+250:2:3241
+251:0:4812
+252:2:3050
+253:0:4812
+254:2:3244
+255:2:3245
+256:2:3249
+257:2:3250
+258:2:3258
+259:2:3259
+260:2:3263
+261:2:3264
+262:2:3272
+263:2:3277
+264:2:3281
+265:2:3282
+266:2:3290
+267:2:3291
+268:2:3295
+269:2:3296
+270:2:3290
+271:2:3291
+272:2:3295
+273:2:3296
+274:2:3304
+275:2:3309
+276:2:3310
+277:2:3321
+278:2:3322
+279:2:3323
+280:2:3334
+281:2:3339
+282:2:3340
+283:2:3351
+284:2:3352
+285:2:3353
+286:2:3351
+287:2:3352
+288:2:3353
+289:2:3364
+290:2:3371
+291:0:4812
+292:2:3050
+293:0:4812
+294:2:3375
+295:2:3376
+296:2:3377
+297:2:3389
+298:2:3390
+299:2:3394
+300:2:3395
+301:2:3403
+302:2:3408
+303:2:3412
+304:2:3413
+305:2:3421
+306:2:3422
+307:2:3426
+308:2:3427
+309:2:3421
+310:2:3422
+311:2:3426
+312:2:3427
+313:2:3435
+314:2:3440
+315:2:3441
+316:2:3452
+317:2:3453
+318:2:3454
+319:2:3465
+320:2:3470
+321:2:3471
+322:2:3482
+323:2:3483
+324:2:3484
+325:2:3482
+326:2:3483
+327:2:3484
+328:2:3495
+329:2:3506
+330:2:3507
+331:0:4812
+332:2:3050
+333:0:4812
+334:2:3513
+335:2:3514
+336:2:3518
+337:2:3519
+338:2:3527
+339:2:3528
+340:2:3532
+341:2:3533
+342:2:3541
+343:2:3546
+344:2:3550
+345:2:3551
+346:2:3559
+347:2:3560
+348:2:3564
+349:2:3565
+350:2:3559
+351:2:3560
+352:2:3564
+353:2:3565
+354:2:3573
+355:2:3578
+356:2:3579
+357:2:3590
+358:2:3591
+359:2:3592
+360:2:3603
+361:2:3608
+362:2:3609
+363:2:3620
+364:2:3621
+365:2:3622
+366:2:3620
+367:2:3621
+368:2:3622
+369:2:3633
+370:0:4812
+371:2:3050
+372:0:4812
+373:2:3642
+374:2:3643
+375:2:3647
+376:2:3648
+377:2:3656
+378:2:3657
+379:2:3661
+380:2:3662
+381:2:3670
+382:2:3675
+383:2:3679
+384:2:3680
+385:2:3688
+386:2:3689
+387:2:3693
+388:2:3694
+389:2:3688
+390:2:3689
+391:2:3693
+392:2:3694
+393:2:3702
+394:2:3707
+395:2:3708
+396:2:3719
+397:2:3720
+398:2:3721
+399:2:3732
+400:2:3737
+401:2:3738
+402:2:3749
+403:2:3750
+404:2:3751
+405:2:3749
+406:2:3750
+407:2:3751
+408:2:3762
+409:2:3769
+410:0:4812
+411:2:3050
+412:0:4812
+413:2:3773
+414:2:3774
+415:2:3775
+416:2:3787
+417:2:3788
+418:2:3792
+419:2:3793
+420:2:3801
+421:2:3806
+422:2:3810
+423:2:3811
+424:2:3819
+425:2:3820
+426:2:3824
+427:2:3825
+428:2:3819
+429:2:3820
+430:2:3824
+431:2:3825
+432:2:3833
+433:2:3838
+434:2:3839
+435:2:3850
+436:2:3851
+437:2:3852
+438:2:3863
+439:2:3868
+440:2:3869
+441:2:3880
+442:2:3881
+443:2:3882
+444:2:3880
+445:2:3881
+446:2:3882
+447:2:3893
+448:2:3903
+449:2:3904
+450:0:4812
+451:2:3050
+452:0:4812
+453:2:3910
+454:0:4812
+455:2:4535
+456:2:4536
+457:2:4540
+458:2:4544
+459:2:4545
+460:2:4549
+461:2:4557
+462:2:4558
+463:2:4562
+464:2:4566
+465:2:4567
+466:2:4562
+467:2:4566
+468:2:4567
+469:2:4571
+470:2:4578
+471:2:4585
+472:2:4586
+473:2:4593
+474:2:4598
+475:2:4605
+476:2:4606
+477:2:4605
+478:2:4606
+479:2:4613
+480:2:4617
+481:0:4812
+482:2:4622
+483:0:4812
+484:2:4623
+485:0:4812
+486:2:4624
+487:0:4812
+488:2:4625
+489:0:4812
+490:1:28
+491:0:4812
+492:2:4626
+493:0:4812
+494:1:32
+495:1:33
+496:1:37
+497:1:41
+498:1:42
+499:1:46
+500:1:54
+501:1:55
+502:1:59
+503:1:63
+504:1:64
+505:1:59
+506:1:63
+507:1:64
+508:1:68
+509:1:75
+510:1:82
+511:1:83
+512:1:90
+513:1:95
+514:1:102
+515:1:103
+516:1:102
+517:1:103
+518:1:110
+519:1:114
+520:0:4812
+521:2:4625
+522:0:4812
+523:1:119
+524:0:4812
+525:2:4626
+526:0:4812
+527:2:4627
+528:0:4812
+529:2:4632
+530:0:4812
+531:2:4633
+532:0:4812
+533:2:4641
+534:2:4642
+535:2:4646
+536:2:4650
+537:2:4651
+538:2:4655
+539:2:4663
+540:2:4664
+541:2:4668
+542:2:4672
+543:2:4673
+544:2:4668
+545:2:4672
+546:2:4673
+547:2:4677
+548:2:4684
+549:2:4691
+550:2:4692
+551:2:4699
+552:2:4704
+553:2:4711
+554:2:4712
+555:2:4711
+556:2:4712
+557:2:4719
+558:2:4723
+559:0:4812
+560:2:3912
+561:2:3922
+562:0:4812
+563:2:3050
+564:0:4812
+565:2:3913
+566:2:3914
+567:0:4812
+568:2:3050
+569:0:4812
+570:2:3918
+571:0:4812
+572:2:3926
+573:0:4812
+574:2:3047
+575:0:4812
+576:2:3049
+577:0:4812
+578:2:3050
+579:0:4812
+580:2:3051
+581:2:3052
+582:2:3056
+583:2:3057
+584:2:3065
+585:2:3066
+586:2:3070
+587:2:3071
+588:2:3079
+589:2:3084
+590:2:3088
+591:2:3089
+592:2:3097
+593:2:3098
+594:2:3099
+595:2:3097
+596:2:3098
+597:2:3102
+598:2:3103
+599:2:3111
+600:2:3116
+601:2:3117
+602:2:3128
+603:2:3129
+604:2:3130
+605:2:3141
+606:2:3146
+607:2:3147
+608:2:3158
+609:2:3159
+610:2:3160
+611:2:3158
+612:2:3159
+613:2:3160
+614:2:3171
+615:2:3179
+616:0:4812
+617:2:3050
+618:0:4812
+619:2:3183
+620:2:3187
+621:2:3188
+622:2:3192
+623:2:3196
+624:2:3197
+625:2:3201
+626:2:3209
+627:2:3210
+628:2:3214
+629:2:3215
+630:2:3214
+631:2:3218
+632:2:3219
+633:2:3223
+634:0:4812
+635:2:3050
+636:0:4812
+637:2:3231
+638:2:3232
+639:2:3233
+640:0:4812
+641:2:3050
+642:0:4812
+643:2:3238
+644:0:4812
+645:2:3941
+646:2:3942
+647:2:3946
+648:2:3950
+649:2:3951
+650:2:3955
+651:2:3960
+652:2:3968
+653:2:3972
+654:2:3973
+655:2:3968
+656:2:3972
+657:2:3973
+658:2:3977
+659:2:3984
+660:2:3991
+661:2:3992
+662:2:3999
+663:2:4004
+664:2:4011
+665:2:4012
+666:2:4011
+667:2:4012
+668:2:4019
+669:2:4023
+670:0:4812
+671:2:4028
+672:0:4812
+673:2:4029
+674:0:4812
+675:2:4030
+676:0:4812
+677:2:4031
+678:0:4812
+679:1:28
+680:0:4812
+681:2:4032
+682:0:4812
+683:1:32
+684:1:33
+685:1:37
+686:1:41
+687:1:42
+688:1:46
+689:1:54
+690:1:55
+691:1:59
+692:1:63
+693:1:64
+694:1:59
+695:1:63
+696:1:64
+697:1:68
+698:1:75
+699:1:82
+700:1:83
+701:1:90
+702:1:95
+703:1:102
+704:1:103
+705:1:102
+706:1:103
+707:1:110
+708:1:114
+709:0:4812
+710:2:4031
+711:0:4812
+712:1:119
+713:0:4812
+714:2:4032
+715:0:4812
+716:2:4033
+717:0:4812
+718:2:4038
+719:0:4812
+720:2:4039
+721:0:4812
+722:2:4047
+723:2:4048
+724:2:4052
+725:2:4056
+726:2:4057
+727:2:4061
+728:2:4069
+729:2:4070
+730:2:4074
+731:2:4078
+732:2:4079
+733:2:4074
+734:2:4078
+735:2:4079
+736:2:4083
+737:2:4090
+738:2:4097
+739:2:4098
+740:2:4105
+741:2:4110
+742:2:4117
+743:2:4118
+744:2:4117
+745:2:4118
+746:2:4125
+747:2:4129
+748:0:4812
+749:2:3240
+750:2:3922
+751:0:4812
+752:2:3050
+753:0:4812
+754:2:3241
+755:0:4812
+756:2:3050
+757:0:4812
+758:2:3244
+759:2:3245
+760:2:3249
+761:2:3250
+762:2:3258
+763:2:3259
+764:2:3263
+765:2:3264
+766:2:3272
+767:2:3277
+768:2:3281
+769:2:3282
+770:2:3290
+771:2:3291
+772:2:3295
+773:2:3296
+774:2:3290
+775:2:3291
+776:2:3295
+777:2:3296
+778:2:3304
+779:2:3309
+780:2:3310
+781:2:3321
+782:2:3322
+783:2:3323
+784:2:3334
+785:2:3339
+786:2:3340
+787:2:3351
+788:2:3352
+789:2:3353
+790:2:3351
+791:2:3352
+792:2:3353
+793:2:3364
+794:2:3371
+795:0:4812
+796:2:3050
+797:0:4812
+798:2:3375
+799:2:3376
+800:2:3377
+801:2:3389
+802:2:3390
+803:2:3394
+804:2:3395
+805:2:3403
+806:2:3408
+807:2:3412
+808:2:3413
+809:2:3421
+810:2:3422
+811:2:3426
+812:2:3427
+813:2:3421
+814:2:3422
+815:2:3426
+816:2:3427
+817:2:3435
+818:2:3440
+819:2:3441
+820:2:3452
+821:2:3453
+822:2:3454
+823:2:3465
+824:2:3470
+825:2:3471
+826:2:3482
+827:2:3483
+828:2:3484
+829:2:3482
+830:2:3483
+831:2:3484
+832:2:3495
+833:2:3506
+834:2:3507
+835:0:4812
+836:2:3050
+837:0:4812
+838:2:3513
+839:2:3514
+840:2:3518
+841:2:3519
+842:2:3527
+843:2:3528
+844:2:3532
+845:2:3533
+846:2:3541
+847:2:3546
+848:2:3550
+849:2:3551
+850:2:3559
+851:2:3560
+852:2:3564
+853:2:3565
+854:2:3559
+855:2:3560
+856:2:3564
+857:2:3565
+858:2:3573
+859:2:3578
+860:2:3579
+861:2:3590
+862:2:3591
+863:2:3592
+864:2:3603
+865:2:3608
+866:2:3609
+867:2:3620
+868:2:3621
+869:2:3622
+870:2:3620
+871:2:3621
+872:2:3622
+873:2:3633
+874:0:4812
+875:2:3050
+876:0:4812
+877:2:3642
+878:2:3643
+879:2:3647
+880:2:3648
+881:2:3656
+882:2:3657
+883:2:3661
+884:2:3662
+885:2:3670
+886:2:3675
+887:2:3679
+888:2:3680
+889:2:3688
+890:2:3689
+891:2:3693
+892:2:3694
+893:2:3688
+894:2:3689
+895:2:3693
+896:2:3694
+897:2:3702
+898:2:3707
+899:2:3708
+900:2:3719
+901:2:3720
+902:2:3721
+903:2:3732
+904:2:3737
+905:2:3738
+906:2:3749
+907:2:3750
+908:2:3751
+909:2:3749
+910:2:3750
+911:2:3751
+912:2:3762
+913:2:3769
+914:0:4812
+915:2:3050
+916:0:4812
+917:2:3773
+918:2:3774
+919:2:3775
+920:2:3787
+921:2:3788
+922:2:3792
+923:2:3793
+924:2:3801
+925:2:3806
+926:2:3810
+927:2:3811
+928:2:3819
+929:2:3820
+930:2:3824
+931:2:3825
+932:2:3819
+933:2:3820
+934:2:3824
+935:2:3825
+936:2:3833
+937:2:3838
+938:2:3839
+939:2:3850
+940:2:3851
+941:2:3852
+942:2:3863
+943:2:3868
+944:2:3869
+945:2:3880
+946:2:3881
+947:2:3882
+948:2:3880
+949:2:3881
+950:2:3882
+951:2:3893
+952:2:3903
+953:2:3904
+954:0:4812
+955:2:3050
+956:0:4812
+957:2:3910
+958:0:4812
+959:2:4535
+960:2:4536
+961:2:4540
+962:2:4544
+963:2:4545
+964:2:4549
+965:2:4557
+966:2:4558
+967:2:4562
+968:2:4566
+969:2:4567
+970:2:4562
+971:2:4566
+972:2:4567
+973:2:4571
+974:2:4578
+975:2:4585
+976:2:4586
+977:2:4593
+978:2:4598
+979:2:4605
+980:2:4606
+981:2:4605
+982:2:4606
+983:2:4613
+984:2:4617
+985:0:4812
+986:2:4622
+987:0:4812
+988:2:4623
+989:0:4812
+990:2:4624
+991:0:4812
+992:2:4625
+993:0:4812
+994:1:28
+995:0:4812
+996:2:4626
+997:0:4812
+998:1:32
+999:1:33
+1000:1:37
+1001:1:41
+1002:1:42
+1003:1:46
+1004:1:54
+1005:1:55
+1006:1:59
+1007:1:63
+1008:1:64
+1009:1:59
+1010:1:63
+1011:1:64
+1012:1:68
+1013:1:75
+1014:1:82
+1015:1:83
+1016:1:90
+1017:1:95
+1018:1:102
+1019:1:103
+1020:1:102
+1021:1:103
+1022:1:110
+1023:1:114
+1024:0:4812
+1025:2:4625
+1026:0:4812
+1027:1:119
+1028:0:4812
+1029:2:4626
+1030:0:4812
+1031:2:4627
+1032:0:4812
+1033:2:4632
+1034:0:4812
+1035:2:4633
+1036:0:4812
+1037:2:4641
+1038:2:4642
+1039:2:4646
+1040:2:4650
+1041:2:4651
+1042:2:4655
+1043:2:4663
+1044:2:4664
+1045:2:4668
+1046:2:4672
+1047:2:4673
+1048:2:4668
+1049:2:4672
+1050:2:4673
+1051:2:4677
+1052:2:4684
+1053:2:4691
+1054:2:4692
+1055:2:4699
+1056:2:4704
+1057:2:4711
+1058:2:4712
+1059:2:4711
+1060:2:4712
+1061:2:4719
+1062:2:4723
+1063:0:4812
+1064:2:3912
+1065:2:3922
+1066:0:4812
+1067:2:3050
+1068:0:4812
+1069:2:3913
+1070:2:3914
+1071:0:4812
+1072:2:3050
+1073:0:4812
+1074:2:3918
+1075:0:4812
+1076:2:3926
+1077:0:4812
+1078:2:3047
+1079:0:4812
+1080:2:3049
+1081:0:4812
+1082:2:3050
+1083:0:4812
+1084:2:3051
+1085:2:3052
+1086:2:3056
+1087:2:3057
+1088:2:3065
+1089:2:3066
+1090:2:3070
+1091:2:3071
+1092:2:3079
+1093:2:3084
+1094:2:3088
+1095:2:3089
+1096:2:3097
+1097:2:3098
+1098:2:3102
+1099:2:3103
+1100:2:3097
+1101:2:3098
+1102:2:3099
+1103:2:3111
+1104:2:3116
+1105:2:3117
+1106:2:3128
+1107:2:3129
+1108:2:3130
+1109:2:3141
+1110:2:3146
+1111:2:3147
+1112:2:3158
+1113:2:3159
+1114:2:3160
+1115:2:3158
+1116:2:3159
+1117:2:3160
+1118:2:3171
+1119:2:3179
+1120:0:4812
+1121:2:3050
+1122:0:4812
+1123:1:120
+1124:0:4812
+1125:1:19
+1126:0:4812
+1127:1:127
+1128:1:128
+1129:1:132
+1130:1:133
+1131:1:141
+1132:1:142
+1133:1:146
+1134:1:147
+1135:1:155
+1136:1:160
+1137:1:164
+1138:1:165
+1139:1:173
+1140:1:174
+1141:1:178
+1142:1:179
+1143:1:173
+1144:1:174
+1145:1:178
+1146:1:179
+1147:1:187
+1148:1:192
+1149:1:193
+1150:1:204
+1151:1:205
+1152:1:206
+1153:1:217
+1154:1:222
+1155:1:223
+1156:1:234
+1157:1:235
+1158:1:236
+1159:1:234
+1160:1:235
+1161:1:236
+1162:1:247
+1163:0:4812
+1164:1:15
+1165:0:4812
+1166:1:16
+1167:0:4812
+1168:2:3183
+1169:2:3187
+1170:2:3188
+1171:2:3192
+1172:2:3196
+1173:2:3197
+1174:2:3201
+1175:2:3209
+1176:2:3210
+1177:2:3214
+1178:2:3218
+1179:2:3219
+1180:2:3214
+1181:2:3215
+1182:2:3223
+1183:0:4812
+1184:2:3050
+1185:0:4812
+1186:2:3231
+1187:2:3232
+1188:2:3233
+1189:0:4812
+1190:2:3050
+1191:0:4812
+1192:2:3238
+1193:0:4812
+1194:2:3941
+1195:2:3942
+1196:2:3946
+1197:2:3950
+1198:2:3951
+1199:2:3955
+1200:2:3960
+1201:2:3968
+1202:2:3972
+1203:2:3973
+1204:2:3968
+1205:2:3972
+1206:2:3973
+1207:2:3977
+1208:2:3984
+1209:2:3991
+1210:2:3992
+1211:2:3999
+1212:2:4004
+1213:2:4011
+1214:2:4012
+1215:2:4011
+1216:2:4012
+1217:2:4019
+1218:2:4023
+1219:0:4812
+1220:2:4028
+1221:0:4812
+1222:2:4029
+1223:0:4812
+1224:2:4030
+1225:0:4812
+1226:2:4031
+1227:0:4812
+1228:1:17
+1229:0:4812
+1230:2:4032
+1231:0:4812
+1232:1:120
+1233:0:4812
+1234:2:4031
+1235:0:4812
+1236:1:19
+1237:0:4812
+1238:2:4032
+1239:0:4812
+1240:1:256
+1241:1:257
+1242:0:4812
+1243:1:15
+1244:0:4812
+1245:1:16
+1246:0:4812
+1247:2:4031
+1248:0:4812
+1249:1:17
+1250:0:4812
+1251:2:4032
+1252:0:4812
+1253:1:120
+1254:0:4812
+1255:2:4031
+1256:0:4812
+1257:1:19
+1258:0:4812
+1259:2:4032
+1260:0:4812
+1261:1:263
+1262:1:264
+1263:1:268
+1264:1:269
+1265:1:277
+1266:1:278
+1267:1:282
+1268:1:283
+1269:1:291
+1270:1:296
+1271:1:300
+1272:1:301
+1273:1:309
+1274:1:310
+1275:1:314
+1276:1:315
+1277:1:309
+1278:1:310
+1279:1:314
+1280:1:315
+1281:1:323
+1282:1:328
+1283:1:329
+1284:1:340
+1285:1:341
+1286:1:342
+1287:1:353
+1288:1:358
+1289:1:359
+1290:1:370
+1291:1:371
+1292:1:372
+1293:1:370
+1294:1:378
+1295:1:379
+1296:1:383
+1297:0:4812
+1298:1:15
+1299:0:4812
+1300:1:16
+1301:0:4812
+1302:2:4031
+1303:0:4812
+1304:1:17
+1305:0:4812
+1306:2:4032
+1307:0:4812
+1308:1:120
+1309:0:4812
+1310:2:4031
+1311:0:4812
+1312:1:19
+1313:0:4812
+1314:2:4032
+1315:0:4812
+1316:1:392
+1317:1:393
+1318:1:397
+1319:1:398
+1320:1:406
+1321:1:407
+1322:1:411
+1323:1:412
+1324:1:420
+1325:1:425
+1326:1:429
+1327:1:430
+1328:1:438
+1329:1:439
+1330:1:443
+1331:1:444
+1332:1:438
+1333:1:439
+1334:1:443
+1335:1:444
+1336:1:452
+1337:1:457
+1338:1:458
+1339:1:469
+1340:1:470
+1341:1:471
+1342:1:482
+1343:1:487
+1344:1:488
+1345:1:499
+1346:1:500
+1347:1:501
+1348:1:499
+1349:1:507
+1350:1:508
+1351:1:512
+1352:1:519
+1353:0:4812
+1354:1:15
+1355:0:4812
+1356:1:16
+1357:0:4812
+1358:2:4031
+1359:0:4812
+1360:1:17
+1361:0:4812
+1362:2:4032
+1363:0:4812
+1364:1:120
+1365:0:4812
+1366:2:4031
+1367:0:4812
+1368:1:19
+1369:0:4812
+1370:2:4032
+1371:0:4812
+1372:1:657
+1373:1:658
+1374:1:662
+1375:1:663
+1376:1:671
+1377:1:672
+1378:1:673
+1379:1:685
+1380:1:690
+1381:1:694
+1382:1:695
+1383:1:703
+1384:1:704
+1385:1:708
+1386:1:709
+1387:1:703
+1388:1:704
+1389:1:708
+1390:1:709
+1391:1:717
+1392:1:722
+1393:1:723
+1394:1:734
+1395:1:735
+1396:1:736
+1397:1:747
+1398:1:752
+1399:1:753
+1400:1:764
+1401:1:765
+1402:1:766
+1403:1:764
+1404:1:772
+1405:1:773
+1406:1:777
+1407:0:4812
+1408:1:15
+1409:0:4812
+1410:1:16
+1411:0:4812
+1412:2:4031
+1413:0:4812
+1414:1:17
+1415:0:4812
+1416:2:4032
+1417:0:4812
+1418:1:120
+1419:0:4812
+1420:2:4031
+1421:0:4812
+1422:1:19
+1423:0:4812
+1424:2:4032
+1425:0:4812
+1426:1:786
+1427:1:789
+1428:1:790
+1429:0:4812
+1430:1:15
+1431:0:4812
+1432:1:16
+1433:0:4812
+1434:2:4031
+1435:0:4812
+1436:1:17
+1437:0:4812
+1438:2:4032
+1439:0:4812
+1440:1:120
+1441:0:4812
+1442:2:4031
+1443:0:4812
+1444:1:19
+1445:0:4812
+1446:2:4032
+1447:0:4812
+1448:1:1053
+1449:1:1054
+1450:1:1058
+1451:1:1059
+1452:1:1067
+1453:1:1068
+1454:1:1072
+1455:1:1073
+1456:1:1081
+1457:1:1086
+1458:1:1090
+1459:1:1091
+1460:1:1099
+1461:1:1100
+1462:1:1104
+1463:1:1105
+1464:1:1099
+1465:1:1100
+1466:1:1104
+1467:1:1105
+1468:1:1113
+1469:1:1118
+1470:1:1119
+1471:1:1130
+1472:1:1131
+1473:1:1132
+1474:1:1143
+1475:1:1148
+1476:1:1149
+1477:1:1160
+1478:1:1161
+1479:1:1162
+1480:1:1160
+1481:1:1168
+1482:1:1169
+1483:1:1173
+1484:1:1180
+1485:1:1184
+1486:0:4812
+1487:1:15
+1488:0:4812
+1489:1:16
+1490:0:4812
+1491:2:4031
+1492:0:4812
+1493:1:17
+1494:0:4812
+1495:2:4032
+1496:0:4812
+1497:1:120
+1498:0:4812
+1499:2:4031
+1500:0:4812
+1501:1:19
+1502:0:4812
+1503:2:4032
+1504:0:4812
+1505:1:1185
+1506:1:1186
+1507:1:1190
+1508:1:1191
+1509:1:1199
+1510:1:1200
+1511:1:1201
+1512:1:1213
+1513:1:1218
+1514:1:1222
+1515:1:1223
+1516:1:1231
+1517:1:1232
+1518:1:1236
+1519:1:1237
+1520:1:1231
+1521:1:1232
+1522:1:1236
+1523:1:1237
+1524:1:1245
+1525:1:1250
+1526:1:1251
+1527:1:1262
+1528:1:1263
+1529:1:1264
+1530:1:1275
+1531:1:1280
+1532:1:1281
+1533:1:1292
+1534:1:1293
+1535:1:1294
+1536:1:1292
+1537:1:1300
+1538:1:1301
+1539:1:1305
+1540:0:4812
+1541:1:15
+1542:0:4812
+1543:1:16
+1544:0:4812
+1545:2:4031
+1546:0:4812
+1547:1:17
+1548:0:4812
+1549:2:4032
+1550:0:4812
+1551:1:120
+1552:0:4812
+1553:2:4031
+1554:0:4812
+1555:1:19
+1556:0:4812
+1557:2:4032
+1558:0:4812
+1559:1:1314
+1560:0:4812
+1561:2:4031
+1562:0:4812
+1563:1:2778
+1564:1:2782
+1565:1:2783
+1566:1:2791
+1567:1:2792
+1568:1:2796
+1569:1:2797
+1570:1:2805
+1571:1:2810
+1572:1:2814
+1573:1:2815
+1574:1:2823
+1575:1:2824
+1576:1:2828
+1577:1:2829
+1578:1:2823
+1579:1:2824
+1580:1:2828
+1581:1:2829
+1582:1:2837
+1583:1:2842
+1584:1:2843
+1585:1:2854
+1586:1:2855
+1587:1:2856
+1588:1:2867
+1589:1:2872
+1590:1:2873
+1591:1:2884
+1592:1:2885
+1593:1:2886
+1594:1:2884
+1595:1:2892
+1596:1:2893
+1597:1:2897
+1598:1:2901
+1599:0:4812
+1600:2:4032
+1601:0:4812
+1602:1:1316
+1603:1:1317
+1604:0:4810
+1605:1:15
+1606:0:4816
+1607:1:1637
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_wmb.define b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_wmb.define
new file mode 100644 (file)
index 0000000..710f29d
--- /dev/null
@@ -0,0 +1 @@
+#define NO_WMB
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_wmb.log b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_wmb.log
new file mode 100644 (file)
index 0000000..e829e4b
--- /dev/null
@@ -0,0 +1,613 @@
+make[1]: Entering directory `/home/compudj/doc/userspace-rcu/formal-model/urcu-controldataflow'
+rm -f pan* trail.out .input.spin* *.spin.trail .input.define
+touch .input.define
+cat .input.define >> pan.ltl
+cat DEFINES >> pan.ltl
+spin -f "!(`cat urcu_free.ltl | grep -v ^//`)" >> pan.ltl
+cp urcu_free_no_wmb.define .input.define
+cat .input.define > .input.spin
+cat DEFINES >> .input.spin
+cat urcu.spin >> .input.spin
+rm -f .input.spin.trail
+spin -a -X -N pan.ltl .input.spin
+Exit-Status 0
+gcc -O2 -w -DHASH64 -o pan pan.c
+./pan -a -v -c1 -X -m10000000 -w20
+warning: for p.o. reduction to be valid the never claim must be stutter-invariant
+(never claims generated from LTL formulae are stutter-invariant)
+depth 0: Claim reached state 5 (line 1245)
+Depth=    8041 States=    1e+06 Transitions= 1.63e+08 Memory=   550.432        t=    203 R=   5e+03
+Depth=    9655 States=    2e+06 Transitions= 3.34e+08 Memory=   634.318        t=    424 R=   5e+03
+Depth=    9655 States=    3e+06 Transitions= 5.11e+08 Memory=   718.303        t=    654 R=   5e+03
+pan: resizing hashtable to -w22..  done
+Depth=    9655 States=    4e+06 Transitions= 6.76e+08 Memory=   833.311        t=    861 R=   5e+03
+Depth=    9655 States=    5e+06 Transitions=    9e+08 Memory=   917.295        t= 1.15e+03 R=   4e+03
+Depth=    9655 States=    6e+06 Transitions= 1.34e+09 Memory=  1001.279        t= 1.71e+03 R=   3e+03
+Depth=    9655 States=    7e+06 Transitions= 1.71e+09 Memory=  1085.264        t= 2.2e+03 R=   3e+03
+Depth=    9655 States=    8e+06 Transitions= 2.07e+09 Memory=  1169.151        t= 2.68e+03 R=   3e+03
+Depth=    9655 States=    9e+06 Transitions= 2.39e+09 Memory=  1253.135        t= 3.11e+03 R=   3e+03
+pan: resizing hashtable to -w24..  done
+Depth=    9655 States=    1e+07 Transitions= 2.56e+09 Memory=  1461.115        t= 3.32e+03 R=   3e+03
+Depth=    9655 States=  1.1e+07 Transitions= 2.73e+09 Memory=  1545.100        t= 3.53e+03 R=   3e+03
+Depth=    9655 States=  1.2e+07 Transitions= 2.93e+09 Memory=  1629.084        t= 3.78e+03 R=   3e+03
+Depth=    9655 States=  1.3e+07 Transitions= 3.09e+09 Memory=  1713.068        t= 3.99e+03 R=   3e+03
+Depth=    9655 States=  1.4e+07 Transitions= 3.27e+09 Memory=  1797.053        t= 4.22e+03 R=   3e+03
+Depth=    9655 States=  1.5e+07 Transitions=  3.7e+09 Memory=  1881.037        t= 4.77e+03 R=   3e+03
+Depth=    9655 States=  1.6e+07 Transitions= 4.11e+09 Memory=  1964.924        t= 5.32e+03 R=   3e+03
+Depth=    9655 States=  1.7e+07 Transitions= 4.42e+09 Memory=  2048.908        t= 5.72e+03 R=   3e+03
+Depth=    9655 States=  1.8e+07 Transitions= 4.62e+09 Memory=  2132.893        t= 5.98e+03 R=   3e+03
+Depth=    9655 States=  1.9e+07 Transitions= 4.92e+09 Memory=  2216.877        t= 6.35e+03 R=   3e+03
+Depth=    9655 States=    2e+07 Transitions= 5.24e+09 Memory=  2300.861        t= 6.77e+03 R=   3e+03
+Depth=    9655 States=  2.1e+07 Transitions= 5.94e+09 Memory=  2384.846        t= 7.68e+03 R=   3e+03
+Depth=    9655 States=  2.2e+07 Transitions= 6.65e+09 Memory=  2468.830        t= 8.63e+03 R=   3e+03
+Depth=    9655 States=  2.3e+07 Transitions=  7.1e+09 Memory=  2552.717        t= 9.22e+03 R=   2e+03
+Depth=    9655 States=  2.4e+07 Transitions= 7.54e+09 Memory=  2636.701        t= 9.8e+03 R=   2e+03
+Depth=    9655 States=  2.5e+07 Transitions= 7.74e+09 Memory=  2720.686        t= 1.01e+04 R=   2e+03
+Depth=    9655 States=  2.6e+07 Transitions= 8.03e+09 Memory=  2804.670        t= 1.04e+04 R=   2e+03
+Depth=    9655 States=  2.7e+07 Transitions=  8.4e+09 Memory=  2888.654        t= 1.09e+04 R=   2e+03
+Depth=    9655 States=  2.8e+07 Transitions= 9.12e+09 Memory=  2972.639        t= 1.19e+04 R=   2e+03
+Depth=    9655 States=  2.9e+07 Transitions= 9.83e+09 Memory=  3056.526        t= 1.29e+04 R=   2e+03
+Depth=    9655 States=    3e+07 Transitions= 1.02e+10 Memory=  3140.510        t= 1.33e+04 R=   2e+03
+Depth=    9655 States=  3.1e+07 Transitions= 1.04e+10 Memory=  3224.494        t= 1.36e+04 R=   2e+03
+Depth=    9655 States=  3.2e+07 Transitions= 1.08e+10 Memory=  3308.479        t= 1.42e+04 R=   2e+03
+Depth=    9655 States=  3.3e+07 Transitions= 1.12e+10 Memory=  3392.463        t= 1.48e+04 R=   2e+03
+Depth=    9655 States=  3.4e+07 Transitions= 1.17e+10 Memory=  3476.447        t= 1.54e+04 R=   2e+03
+pan: resizing hashtable to -w26..  done
+Depth=    9655 States=  3.5e+07 Transitions=  1.2e+10 Memory=  4056.416        t= 1.58e+04 R=   2e+03
+Depth=    9693 States=  3.6e+07 Transitions= 1.24e+10 Memory=  4140.401        t= 1.62e+04 R=   2e+03
+Depth=    9693 States=  3.7e+07 Transitions= 1.26e+10 Memory=  4224.385        t= 1.65e+04 R=   2e+03
+Depth=    9693 States=  3.8e+07 Transitions= 1.29e+10 Memory=  4308.369        t= 1.69e+04 R=   2e+03
+Depth=    9693 States=  3.9e+07 Transitions= 1.31e+10 Memory=  4392.354        t= 1.72e+04 R=   2e+03
+Depth=    9693 States=    4e+07 Transitions= 1.34e+10 Memory=  4476.338        t= 1.75e+04 R=   2e+03
+Depth=    9693 States=  4.1e+07 Transitions= 1.36e+10 Memory=  4560.225        t= 1.79e+04 R=   2e+03
+Depth=    9693 States=  4.2e+07 Transitions= 1.39e+10 Memory=  4644.209        t= 1.82e+04 R=   2e+03
+Depth=    9693 States=  4.3e+07 Transitions= 1.41e+10 Memory=  4728.193        t= 1.85e+04 R=   2e+03
+Depth=    9693 States=  4.4e+07 Transitions= 1.44e+10 Memory=  4812.178        t= 1.88e+04 R=   2e+03
+Depth=    9693 States=  4.5e+07 Transitions= 1.47e+10 Memory=  4896.162        t= 1.92e+04 R=   2e+03
+Depth=    9693 States=  4.6e+07 Transitions= 1.49e+10 Memory=  4980.147        t= 1.95e+04 R=   2e+03
+Depth=    9693 States=  4.7e+07 Transitions= 1.51e+10 Memory=  5064.131        t= 1.98e+04 R=   2e+03
+Depth=    9693 States=  4.8e+07 Transitions= 1.54e+10 Memory=  5148.018        t= 2.02e+04 R=   2e+03
+Depth=    9693 States=  4.9e+07 Transitions= 1.56e+10 Memory=  5232.002        t= 2.05e+04 R=   2e+03
+Depth=    9693 States=    5e+07 Transitions= 1.59e+10 Memory=  5315.986        t= 2.07e+04 R=   2e+03
+Depth=    9693 States=  5.1e+07 Transitions= 1.61e+10 Memory=  5399.971        t= 2.11e+04 R=   2e+03
+Depth=    9693 States=  5.2e+07 Transitions= 1.65e+10 Memory=  5483.955        t= 2.16e+04 R=   2e+03
+Depth=    9693 States=  5.3e+07 Transitions= 1.69e+10 Memory=  5567.940        t= 2.22e+04 R=   2e+03
+Depth=    9693 States=  5.4e+07 Transitions= 1.73e+10 Memory=  5651.826        t= 2.26e+04 R=   2e+03
+Depth=    9693 States=  5.5e+07 Transitions= 1.78e+10 Memory=  5735.811        t= 2.33e+04 R=   2e+03
+Depth=    9693 States=  5.6e+07 Transitions= 1.82e+10 Memory=  5819.795        t= 2.37e+04 R=   2e+03
+Depth=    9693 States=  5.7e+07 Transitions= 1.86e+10 Memory=  5903.779        t= 2.42e+04 R=   2e+03
+Depth=    9693 States=  5.8e+07 Transitions= 1.87e+10 Memory=  5987.764        t= 2.44e+04 R=   2e+03
+Depth=    9693 States=  5.9e+07 Transitions= 1.89e+10 Memory=  6071.748        t= 2.46e+04 R=   2e+03
+Depth=    9693 States=    6e+07 Transitions= 1.91e+10 Memory=  6155.733        t= 2.49e+04 R=   2e+03
+Depth=    9693 States=  6.1e+07 Transitions= 1.92e+10 Memory=  6239.619        t= 2.51e+04 R=   2e+03
+Depth=    9693 States=  6.2e+07 Transitions= 1.95e+10 Memory=  6323.604        t= 2.54e+04 R=   2e+03
+Depth=    9693 States=  6.3e+07 Transitions= 1.99e+10 Memory=  6407.588        t= 2.6e+04 R=   2e+03
+Depth=    9693 States=  6.4e+07 Transitions= 2.03e+10 Memory=  6491.572        t= 2.64e+04 R=   2e+03
+pan: claim violated! (at depth 1464)
+pan: wrote .input.spin.trail
+
+(Spin Version 5.1.7 -- 23 December 2008)
+Warning: Search not completed
+       + Partial Order Reduction
+
+Full statespace search for:
+       never claim             +
+       assertion violations    + (if within scope of claim)
+       acceptance   cycles     + (fairness disabled)
+       invalid end states      - (disabled by never claim)
+
+State-vector 88 byte, depth reached 9693, errors: 1
+ 64034146 states, stored
+2.0218243e+10 states, matched
+2.0282277e+10 transitions (= stored+matched)
+1.1654922e+11 atomic steps
+hash conflicts: 1.2215901e+10 (resolved)
+
+Stats on memory usage (in Megabytes):
+ 7083.856      equivalent memory usage for states (stored*(State-vector + overhead))
+ 5527.722      actual memory usage for states (compression: 78.03%)
+               state-vector as stored = 63 byte + 28 byte overhead
+  512.000      memory used for hash table (-w26)
+  457.764      memory used for DFS stack (-m10000000)
+    3.082      memory lost to fragmentation
+ 6494.404      total actual memory usage
+
+unreached in proctype urcu_reader
+       line 250, "pan.___", state 32, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 54, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 63, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 79, "(1)"
+       line 231, "pan.___", state 87, "(1)"
+       line 235, "pan.___", state 99, "(1)"
+       line 239, "pan.___", state 107, "(1)"
+       line 387, "pan.___", state 132, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 164, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 178, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 197, "(1)"
+       line 413, "pan.___", state 227, "(1)"
+       line 417, "pan.___", state 240, "(1)"
+       line 663, "pan.___", state 261, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<1))"
+       line 387, "pan.___", state 268, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 300, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 314, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 333, "(1)"
+       line 413, "pan.___", state 363, "(1)"
+       line 417, "pan.___", state 376, "(1)"
+       line 387, "pan.___", state 397, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 429, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 443, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 462, "(1)"
+       line 413, "pan.___", state 492, "(1)"
+       line 417, "pan.___", state 505, "(1)"
+       line 387, "pan.___", state 528, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 530, "(1)"
+       line 387, "pan.___", state 531, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 387, "pan.___", state 531, "else"
+       line 387, "pan.___", state 534, "(1)"
+       line 391, "pan.___", state 542, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 544, "(1)"
+       line 391, "pan.___", state 545, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 391, "pan.___", state 545, "else"
+       line 391, "pan.___", state 548, "(1)"
+       line 391, "pan.___", state 549, "(1)"
+       line 391, "pan.___", state 549, "(1)"
+       line 389, "pan.___", state 554, "((i<1))"
+       line 389, "pan.___", state 554, "((i>=1))"
+       line 396, "pan.___", state 560, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 562, "(1)"
+       line 396, "pan.___", state 563, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 563, "else"
+       line 396, "pan.___", state 566, "(1)"
+       line 396, "pan.___", state 567, "(1)"
+       line 396, "pan.___", state 567, "(1)"
+       line 400, "pan.___", state 574, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 576, "(1)"
+       line 400, "pan.___", state 577, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 577, "else"
+       line 400, "pan.___", state 580, "(1)"
+       line 400, "pan.___", state 581, "(1)"
+       line 400, "pan.___", state 581, "(1)"
+       line 398, "pan.___", state 586, "((i<2))"
+       line 398, "pan.___", state 586, "((i>=2))"
+       line 404, "pan.___", state 593, "(1)"
+       line 404, "pan.___", state 594, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 594, "else"
+       line 404, "pan.___", state 597, "(1)"
+       line 404, "pan.___", state 598, "(1)"
+       line 404, "pan.___", state 598, "(1)"
+       line 408, "pan.___", state 606, "(1)"
+       line 408, "pan.___", state 607, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 607, "else"
+       line 408, "pan.___", state 610, "(1)"
+       line 408, "pan.___", state 611, "(1)"
+       line 408, "pan.___", state 611, "(1)"
+       line 406, "pan.___", state 616, "((i<1))"
+       line 406, "pan.___", state 616, "((i>=1))"
+       line 413, "pan.___", state 623, "(1)"
+       line 413, "pan.___", state 624, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 624, "else"
+       line 413, "pan.___", state 627, "(1)"
+       line 413, "pan.___", state 628, "(1)"
+       line 413, "pan.___", state 628, "(1)"
+       line 417, "pan.___", state 636, "(1)"
+       line 417, "pan.___", state 637, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 637, "else"
+       line 417, "pan.___", state 640, "(1)"
+       line 417, "pan.___", state 641, "(1)"
+       line 417, "pan.___", state 641, "(1)"
+       line 415, "pan.___", state 646, "((i<2))"
+       line 415, "pan.___", state 646, "((i>=2))"
+       line 422, "pan.___", state 650, "(1)"
+       line 422, "pan.___", state 650, "(1)"
+       line 663, "pan.___", state 653, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 663, "pan.___", state 654, "_proc_urcu_reader = (_proc_urcu_reader|(1<<5))"
+       line 663, "pan.___", state 655, "(1)"
+       line 387, "pan.___", state 662, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 694, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 708, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 727, "(1)"
+       line 413, "pan.___", state 757, "(1)"
+       line 417, "pan.___", state 770, "(1)"
+       line 387, "pan.___", state 798, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 800, "(1)"
+       line 387, "pan.___", state 801, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 387, "pan.___", state 801, "else"
+       line 387, "pan.___", state 804, "(1)"
+       line 391, "pan.___", state 812, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 814, "(1)"
+       line 391, "pan.___", state 815, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 391, "pan.___", state 815, "else"
+       line 391, "pan.___", state 818, "(1)"
+       line 391, "pan.___", state 819, "(1)"
+       line 391, "pan.___", state 819, "(1)"
+       line 389, "pan.___", state 824, "((i<1))"
+       line 389, "pan.___", state 824, "((i>=1))"
+       line 396, "pan.___", state 830, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 832, "(1)"
+       line 396, "pan.___", state 833, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 833, "else"
+       line 396, "pan.___", state 836, "(1)"
+       line 396, "pan.___", state 837, "(1)"
+       line 396, "pan.___", state 837, "(1)"
+       line 400, "pan.___", state 844, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 846, "(1)"
+       line 400, "pan.___", state 847, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 847, "else"
+       line 400, "pan.___", state 850, "(1)"
+       line 400, "pan.___", state 851, "(1)"
+       line 400, "pan.___", state 851, "(1)"
+       line 398, "pan.___", state 856, "((i<2))"
+       line 398, "pan.___", state 856, "((i>=2))"
+       line 404, "pan.___", state 863, "(1)"
+       line 404, "pan.___", state 864, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 864, "else"
+       line 404, "pan.___", state 867, "(1)"
+       line 404, "pan.___", state 868, "(1)"
+       line 404, "pan.___", state 868, "(1)"
+       line 408, "pan.___", state 876, "(1)"
+       line 408, "pan.___", state 877, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 877, "else"
+       line 408, "pan.___", state 880, "(1)"
+       line 408, "pan.___", state 881, "(1)"
+       line 408, "pan.___", state 881, "(1)"
+       line 406, "pan.___", state 886, "((i<1))"
+       line 406, "pan.___", state 886, "((i>=1))"
+       line 413, "pan.___", state 893, "(1)"
+       line 413, "pan.___", state 894, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 894, "else"
+       line 413, "pan.___", state 897, "(1)"
+       line 413, "pan.___", state 898, "(1)"
+       line 413, "pan.___", state 898, "(1)"
+       line 417, "pan.___", state 906, "(1)"
+       line 417, "pan.___", state 907, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 907, "else"
+       line 417, "pan.___", state 910, "(1)"
+       line 417, "pan.___", state 911, "(1)"
+       line 417, "pan.___", state 911, "(1)"
+       line 422, "pan.___", state 920, "(1)"
+       line 422, "pan.___", state 920, "(1)"
+       line 387, "pan.___", state 927, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 929, "(1)"
+       line 387, "pan.___", state 930, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 387, "pan.___", state 930, "else"
+       line 387, "pan.___", state 933, "(1)"
+       line 391, "pan.___", state 941, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 943, "(1)"
+       line 391, "pan.___", state 944, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 391, "pan.___", state 944, "else"
+       line 391, "pan.___", state 947, "(1)"
+       line 391, "pan.___", state 948, "(1)"
+       line 391, "pan.___", state 948, "(1)"
+       line 389, "pan.___", state 953, "((i<1))"
+       line 389, "pan.___", state 953, "((i>=1))"
+       line 396, "pan.___", state 959, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 961, "(1)"
+       line 396, "pan.___", state 962, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 962, "else"
+       line 396, "pan.___", state 965, "(1)"
+       line 396, "pan.___", state 966, "(1)"
+       line 396, "pan.___", state 966, "(1)"
+       line 400, "pan.___", state 973, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 975, "(1)"
+       line 400, "pan.___", state 976, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 976, "else"
+       line 400, "pan.___", state 979, "(1)"
+       line 400, "pan.___", state 980, "(1)"
+       line 400, "pan.___", state 980, "(1)"
+       line 398, "pan.___", state 985, "((i<2))"
+       line 398, "pan.___", state 985, "((i>=2))"
+       line 404, "pan.___", state 992, "(1)"
+       line 404, "pan.___", state 993, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 993, "else"
+       line 404, "pan.___", state 996, "(1)"
+       line 404, "pan.___", state 997, "(1)"
+       line 404, "pan.___", state 997, "(1)"
+       line 408, "pan.___", state 1005, "(1)"
+       line 408, "pan.___", state 1006, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 1006, "else"
+       line 408, "pan.___", state 1009, "(1)"
+       line 408, "pan.___", state 1010, "(1)"
+       line 408, "pan.___", state 1010, "(1)"
+       line 406, "pan.___", state 1015, "((i<1))"
+       line 406, "pan.___", state 1015, "((i>=1))"
+       line 413, "pan.___", state 1022, "(1)"
+       line 413, "pan.___", state 1023, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 1023, "else"
+       line 413, "pan.___", state 1026, "(1)"
+       line 413, "pan.___", state 1027, "(1)"
+       line 413, "pan.___", state 1027, "(1)"
+       line 417, "pan.___", state 1035, "(1)"
+       line 417, "pan.___", state 1036, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 1036, "else"
+       line 417, "pan.___", state 1039, "(1)"
+       line 417, "pan.___", state 1040, "(1)"
+       line 417, "pan.___", state 1040, "(1)"
+       line 415, "pan.___", state 1045, "((i<2))"
+       line 415, "pan.___", state 1045, "((i>=2))"
+       line 422, "pan.___", state 1049, "(1)"
+       line 422, "pan.___", state 1049, "(1)"
+       line 671, "pan.___", state 1053, "_proc_urcu_reader = (_proc_urcu_reader|(1<<11))"
+       line 387, "pan.___", state 1058, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1090, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1104, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1123, "(1)"
+       line 413, "pan.___", state 1153, "(1)"
+       line 417, "pan.___", state 1166, "(1)"
+       line 387, "pan.___", state 1190, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1222, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1236, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1255, "(1)"
+       line 413, "pan.___", state 1285, "(1)"
+       line 417, "pan.___", state 1298, "(1)"
+       line 387, "pan.___", state 1323, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1355, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1369, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1388, "(1)"
+       line 413, "pan.___", state 1418, "(1)"
+       line 417, "pan.___", state 1431, "(1)"
+       line 387, "pan.___", state 1452, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1484, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1498, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1517, "(1)"
+       line 413, "pan.___", state 1547, "(1)"
+       line 417, "pan.___", state 1560, "(1)"
+       line 387, "pan.___", state 1586, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1618, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1632, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1651, "(1)"
+       line 413, "pan.___", state 1681, "(1)"
+       line 417, "pan.___", state 1694, "(1)"
+       line 387, "pan.___", state 1715, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1747, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1761, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1780, "(1)"
+       line 413, "pan.___", state 1810, "(1)"
+       line 417, "pan.___", state 1823, "(1)"
+       line 387, "pan.___", state 1847, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1879, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1893, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1912, "(1)"
+       line 413, "pan.___", state 1942, "(1)"
+       line 417, "pan.___", state 1955, "(1)"
+       line 710, "pan.___", state 1976, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<19))"
+       line 387, "pan.___", state 1983, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2015, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2029, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2048, "(1)"
+       line 413, "pan.___", state 2078, "(1)"
+       line 417, "pan.___", state 2091, "(1)"
+       line 387, "pan.___", state 2112, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2144, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2158, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2177, "(1)"
+       line 413, "pan.___", state 2207, "(1)"
+       line 417, "pan.___", state 2220, "(1)"
+       line 387, "pan.___", state 2243, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 2245, "(1)"
+       line 387, "pan.___", state 2246, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 387, "pan.___", state 2246, "else"
+       line 387, "pan.___", state 2249, "(1)"
+       line 391, "pan.___", state 2257, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 2259, "(1)"
+       line 391, "pan.___", state 2260, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 391, "pan.___", state 2260, "else"
+       line 391, "pan.___", state 2263, "(1)"
+       line 391, "pan.___", state 2264, "(1)"
+       line 391, "pan.___", state 2264, "(1)"
+       line 389, "pan.___", state 2269, "((i<1))"
+       line 389, "pan.___", state 2269, "((i>=1))"
+       line 396, "pan.___", state 2275, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2277, "(1)"
+       line 396, "pan.___", state 2278, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 2278, "else"
+       line 396, "pan.___", state 2281, "(1)"
+       line 396, "pan.___", state 2282, "(1)"
+       line 396, "pan.___", state 2282, "(1)"
+       line 400, "pan.___", state 2289, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2291, "(1)"
+       line 400, "pan.___", state 2292, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 2292, "else"
+       line 400, "pan.___", state 2295, "(1)"
+       line 400, "pan.___", state 2296, "(1)"
+       line 400, "pan.___", state 2296, "(1)"
+       line 398, "pan.___", state 2301, "((i<2))"
+       line 398, "pan.___", state 2301, "((i>=2))"
+       line 404, "pan.___", state 2308, "(1)"
+       line 404, "pan.___", state 2309, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 2309, "else"
+       line 404, "pan.___", state 2312, "(1)"
+       line 404, "pan.___", state 2313, "(1)"
+       line 404, "pan.___", state 2313, "(1)"
+       line 408, "pan.___", state 2321, "(1)"
+       line 408, "pan.___", state 2322, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 2322, "else"
+       line 408, "pan.___", state 2325, "(1)"
+       line 408, "pan.___", state 2326, "(1)"
+       line 408, "pan.___", state 2326, "(1)"
+       line 406, "pan.___", state 2331, "((i<1))"
+       line 406, "pan.___", state 2331, "((i>=1))"
+       line 413, "pan.___", state 2338, "(1)"
+       line 413, "pan.___", state 2339, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 2339, "else"
+       line 413, "pan.___", state 2342, "(1)"
+       line 413, "pan.___", state 2343, "(1)"
+       line 413, "pan.___", state 2343, "(1)"
+       line 417, "pan.___", state 2351, "(1)"
+       line 417, "pan.___", state 2352, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 2352, "else"
+       line 417, "pan.___", state 2355, "(1)"
+       line 417, "pan.___", state 2356, "(1)"
+       line 417, "pan.___", state 2356, "(1)"
+       line 415, "pan.___", state 2361, "((i<2))"
+       line 415, "pan.___", state 2361, "((i>=2))"
+       line 422, "pan.___", state 2365, "(1)"
+       line 422, "pan.___", state 2365, "(1)"
+       line 710, "pan.___", state 2368, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 710, "pan.___", state 2369, "_proc_urcu_reader = (_proc_urcu_reader|(1<<23))"
+       line 710, "pan.___", state 2370, "(1)"
+       line 387, "pan.___", state 2377, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2409, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2423, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2442, "(1)"
+       line 413, "pan.___", state 2472, "(1)"
+       line 417, "pan.___", state 2485, "(1)"
+       line 387, "pan.___", state 2512, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2544, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2558, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2577, "(1)"
+       line 413, "pan.___", state 2607, "(1)"
+       line 417, "pan.___", state 2620, "(1)"
+       line 387, "pan.___", state 2641, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2673, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2687, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2706, "(1)"
+       line 413, "pan.___", state 2736, "(1)"
+       line 417, "pan.___", state 2749, "(1)"
+       line 227, "pan.___", state 2782, "(1)"
+       line 235, "pan.___", state 2802, "(1)"
+       line 239, "pan.___", state 2810, "(1)"
+       line 227, "pan.___", state 2825, "(1)"
+       line 235, "pan.___", state 2845, "(1)"
+       line 239, "pan.___", state 2853, "(1)"
+       line 870, "pan.___", state 2870, "-end-"
+       (278 of 2870 states)
+unreached in proctype urcu_writer
+       line 387, "pan.___", state 19, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 33, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 84, "(1)"
+       line 408, "pan.___", state 97, "(1)"
+       line 250, "pan.___", state 150, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 250, "pan.___", state 152, "(1)"
+       line 254, "pan.___", state 159, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 161, "(1)"
+       line 254, "pan.___", state 162, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 254, "pan.___", state 162, "else"
+       line 252, "pan.___", state 167, "((i<1))"
+       line 252, "pan.___", state 167, "((i>=1))"
+       line 258, "pan.___", state 172, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 174, "(1)"
+       line 258, "pan.___", state 175, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 175, "else"
+       line 262, "pan.___", state 181, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 183, "(1)"
+       line 262, "pan.___", state 184, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 262, "pan.___", state 184, "else"
+       line 267, "pan.___", state 193, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 267, "pan.___", state 193, "else"
+       line 387, "pan.___", state 212, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 226, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 244, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 258, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 277, "(1)"
+       line 408, "pan.___", state 290, "(1)"
+       line 413, "pan.___", state 307, "(1)"
+       line 417, "pan.___", state 320, "(1)"
+       line 391, "pan.___", state 357, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 375, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 389, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 421, "(1)"
+       line 413, "pan.___", state 438, "(1)"
+       line 417, "pan.___", state 451, "(1)"
+       line 391, "pan.___", state 495, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 513, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 527, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 559, "(1)"
+       line 413, "pan.___", state 576, "(1)"
+       line 417, "pan.___", state 589, "(1)"
+       line 391, "pan.___", state 624, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 642, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 656, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 688, "(1)"
+       line 413, "pan.___", state 705, "(1)"
+       line 417, "pan.___", state 718, "(1)"
+       line 391, "pan.___", state 755, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 773, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 787, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 819, "(1)"
+       line 413, "pan.___", state 836, "(1)"
+       line 417, "pan.___", state 849, "(1)"
+       line 250, "pan.___", state 904, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 913, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 951, "(1)"
+       line 231, "pan.___", state 959, "(1)"
+       line 235, "pan.___", state 971, "(1)"
+       line 239, "pan.___", state 979, "(1)"
+       line 250, "pan.___", state 1010, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1019, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1032, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1041, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1057, "(1)"
+       line 231, "pan.___", state 1065, "(1)"
+       line 235, "pan.___", state 1077, "(1)"
+       line 239, "pan.___", state 1085, "(1)"
+       line 254, "pan.___", state 1111, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1124, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1133, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1149, "(1)"
+       line 231, "pan.___", state 1157, "(1)"
+       line 235, "pan.___", state 1169, "(1)"
+       line 239, "pan.___", state 1177, "(1)"
+       line 250, "pan.___", state 1208, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1217, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1230, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1239, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1255, "(1)"
+       line 231, "pan.___", state 1263, "(1)"
+       line 235, "pan.___", state 1275, "(1)"
+       line 239, "pan.___", state 1283, "(1)"
+       line 254, "pan.___", state 1309, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1322, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1331, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1347, "(1)"
+       line 231, "pan.___", state 1355, "(1)"
+       line 235, "pan.___", state 1367, "(1)"
+       line 239, "pan.___", state 1375, "(1)"
+       line 250, "pan.___", state 1406, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1415, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1428, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1437, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1453, "(1)"
+       line 231, "pan.___", state 1461, "(1)"
+       line 235, "pan.___", state 1473, "(1)"
+       line 239, "pan.___", state 1481, "(1)"
+       line 254, "pan.___", state 1507, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1520, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1529, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1545, "(1)"
+       line 231, "pan.___", state 1553, "(1)"
+       line 235, "pan.___", state 1565, "(1)"
+       line 239, "pan.___", state 1573, "(1)"
+       line 250, "pan.___", state 1604, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1613, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1626, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1635, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1651, "(1)"
+       line 231, "pan.___", state 1659, "(1)"
+       line 235, "pan.___", state 1671, "(1)"
+       line 239, "pan.___", state 1679, "(1)"
+       line 1191, "pan.___", state 1695, "-end-"
+       (109 of 1695 states)
+unreached in proctype :init:
+       line 1202, "pan.___", state 9, "((j<2))"
+       line 1202, "pan.___", state 9, "((j>=2))"
+       line 1203, "pan.___", state 20, "((j<2))"
+       line 1203, "pan.___", state 20, "((j>=2))"
+       line 1208, "pan.___", state 33, "((j<2))"
+       line 1208, "pan.___", state 33, "((j>=2))"
+       line 1206, "pan.___", state 43, "((i<1))"
+       line 1206, "pan.___", state 43, "((i>=1))"
+       line 1216, "pan.___", state 54, "((j<2))"
+       line 1216, "pan.___", state 54, "((j>=2))"
+       line 1220, "pan.___", state 67, "((j<2))"
+       line 1220, "pan.___", state 67, "((j>=2))"
+       (6 of 78 states)
+unreached in proctype :never:
+       line 1250, "pan.___", state 8, "-end-"
+       (1 of 8 states)
+
+pan: elapsed time 2.64e+04 seconds
+pan: rate 2423.5502 states/second
+pan: avg transition delay 1.3027e-06 usec
+cp .input.spin urcu_free_no_wmb.spin.input
+cp .input.spin.trail urcu_free_no_wmb.spin.input.trail
+make[1]: Leaving directory `/home/compudj/doc/userspace-rcu/formal-model/urcu-controldataflow'
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_wmb.spin.input b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_wmb.spin.input
new file mode 100644 (file)
index 0000000..f4c0ace
--- /dev/null
@@ -0,0 +1,1227 @@
+#define NO_WMB
+
+// Poison value for freed memory
+#define POISON 1
+// Memory with correct data
+#define WINE 0
+#define SLAB_SIZE 2
+
+#define read_poison    (data_read_first[0] == POISON || data_read_second[0] == POISON)
+
+#define RCU_GP_CTR_BIT (1 << 7)
+#define RCU_GP_CTR_NEST_MASK (RCU_GP_CTR_BIT - 1)
+
+//disabled
+#define REMOTE_BARRIERS
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+typedef per_proc_bit {
+       bit val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bitfield {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bitfield cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               smp_mb(i, j);
+               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
+               break;
+       od;
+}
+
+#ifdef WRITER_PROGRESS
+//#define PROGRESS_LABEL(progressid)   progress_writer_progid_##progressid:
+#define PROGRESS_LABEL(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;                                          \
+               /*                                                              \
+                * 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)                                                     \
+               do                                                              \
+               :: (reader_barrier[i] == 1) -> skip;                            \
+               :: (reader_barrier[i] == 0) -> break;                           \
+               od;                                                             \
+               i++;                                                            \
+       :: i >= NR_READERS ->                                                   \
+               break                                                           \
+       od;                                                                     \
+       smp_mb(i, j);                                                           \
+}
+
+#else
+
+#define smp_mb_send(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, smp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only one reader */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* RCU data */
+DECLARE_CACHED_VAR(bit, rcu_data[SLAB_SIZE]);
+
+/* RCU pointer */
+#if (SLAB_SIZE == 2)
+DECLARE_CACHED_VAR(bit, rcu_ptr);
+bit ptr_read_first[NR_READERS];
+bit ptr_read_second[NR_READERS];
+#else
+DECLARE_CACHED_VAR(byte, rcu_ptr);
+byte ptr_read_first[NR_READERS];
+byte ptr_read_second[NR_READERS];
+#endif
+
+bit data_read_first[NR_READERS];
+bit data_read_second[NR_READERS];
+
+bit init_done = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               :: 1 -> skip;
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               ptr_read_first[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb1;
+rmb1_end:
+                               data_read_first[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_first[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               ptr_read_second[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb2;
+rmb2_end:
+                               data_read_second[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_second[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+rmb1:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb1_end;
+rmb2:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_DATA                     (1 << 1)
+#define WRITE_PROC_WMB                 (1 << 2)
+#define WRITE_XCHG_PTR                 (1 << 3)
+
+#define WRITE_PROC_FIRST_MB            (1 << 4)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 5)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 6)
+#define WRITE_PROC_FIRST_WAIT          (1 << 7)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 8)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 9)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 10)
+#define WRITE_PROC_SECOND_WAIT         (1 << 11)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 12)
+
+#define WRITE_PROC_SECOND_MB           (1 << 13)
+
+#define WRITE_FREE                     (1 << 14)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_DATA                    \
+                                       | WRITE_PROC_WMB                \
+                                       | WRITE_XCHG_PTR                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB          \
+                                       | WRITE_FREE)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 15) - 1)
+
+/*
+ * Mutexes are implied around writer execution. A single writer at a time.
+ */
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte cur_data = 0, old_data, loop_nr = 0;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (loop_nr < 3) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               loop_nr = loop_nr + 1;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_WMB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+#endif
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_DATA) ->
+                       ooo_mem(i);
+                       cur_data = (cur_data + 1) % SLAB_SIZE;
+                       WRITE_CACHED_VAR(rcu_data[cur_data], WINE);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_DATA);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA,
+                                 WRITE_PROC_WMB) ->
+                       smp_wmb(i, j);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_WMB,
+                                 WRITE_XCHG_PTR) ->
+                       /* rcu_xchg_pointer() */
+                       atomic {
+                               old_data = READ_CACHED_VAR(rcu_ptr);
+                               WRITE_CACHED_VAR(rcu_ptr, cur_data);
+                       }
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_XCHG_PTR);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_WMB      /* No dependency on
+                                                        * WRITE_DATA because we
+                                                        * write to a
+                                                        * different location. */
+                                 | WRITE_PROC_SECOND_MB
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_FREE) ->
+                       WRITE_CACHED_VAR(rcu_data[old_data], POISON);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_FREE);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+               /*
+                * Note : Promela model adds implicit serialization of the
+                * WRITE_FREE instruction. Normally, it would be permitted to
+                * spill on the next loop execution. Given the validation we do
+                * checks for the data entry read to be poisoned, it's ok if
+                * we do not check "late arriving" memory poisoning.
+                */
+       :: 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
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(rcu_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       ptr_read_first[i] = 1;
+                       ptr_read_second[i] = 1;
+                       data_read_first[i] = WINE;
+                       data_read_second[i] = WINE;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               INIT_CACHED_VAR(rcu_data[0], WINE, j);
+               i = 1;
+               do
+               :: i < SLAB_SIZE ->
+                       INIT_CACHED_VAR(rcu_data[i], POISON, j);
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_wmb.spin.input.trail b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_no_wmb.spin.input.trail
new file mode 100644 (file)
index 0000000..befcb5f
--- /dev/null
@@ -0,0 +1,1467 @@
+-2:3:-2
+-4:-4:-4
+1:0:4645
+2:3:4565
+3:3:4568
+4:3:4568
+5:3:4571
+6:3:4579
+7:3:4579
+8:3:4582
+9:3:4588
+10:3:4592
+11:3:4592
+12:3:4595
+13:3:4605
+14:3:4613
+15:3:4613
+16:3:4616
+17:3:4622
+18:3:4626
+19:3:4626
+20:3:4629
+21:3:4635
+22:3:4639
+23:3:4640
+24:0:4645
+25:3:4642
+26:0:4645
+27:2:2872
+28:0:4645
+29:2:2878
+30:0:4645
+31:2:2879
+32:0:4645
+33:2:2881
+34:0:4645
+35:2:2882
+36:0:4645
+37:2:2883
+38:0:4645
+39:2:2884
+40:2:2885
+41:2:2889
+42:2:2890
+43:2:2898
+44:2:2899
+45:2:2903
+46:2:2904
+47:2:2912
+48:2:2917
+49:2:2921
+50:2:2922
+51:2:2930
+52:2:2931
+53:2:2935
+54:2:2936
+55:2:2930
+56:2:2931
+57:2:2935
+58:2:2936
+59:2:2944
+60:2:2949
+61:2:2950
+62:2:2961
+63:2:2962
+64:2:2963
+65:2:2974
+66:2:2979
+67:2:2980
+68:2:2991
+69:2:2992
+70:2:2993
+71:2:2991
+72:2:2992
+73:2:2993
+74:2:3004
+75:2:3012
+76:0:4645
+77:2:2883
+78:0:4645
+79:2:3064
+80:2:3065
+81:2:3066
+82:0:4645
+83:2:2883
+84:0:4645
+85:2:3071
+86:0:4645
+87:2:3774
+88:2:3775
+89:2:3779
+90:2:3783
+91:2:3784
+92:2:3788
+93:2:3793
+94:2:3801
+95:2:3805
+96:2:3806
+97:2:3801
+98:2:3802
+99:2:3810
+100:2:3817
+101:2:3824
+102:2:3825
+103:2:3832
+104:2:3837
+105:2:3844
+106:2:3845
+107:2:3844
+108:2:3845
+109:2:3852
+110:2:3856
+111:0:4645
+112:2:3861
+113:0:4645
+114:2:3862
+115:0:4645
+116:2:3863
+117:0:4645
+118:2:3864
+119:0:4645
+120:1:2
+121:0:4645
+122:2:3865
+123:0:4645
+124:1:8
+125:0:4645
+126:1:9
+127:0:4645
+128:2:3864
+129:0:4645
+130:1:10
+131:0:4645
+132:2:3865
+133:0:4645
+134:1:11
+135:0:4645
+136:2:3864
+137:0:4645
+138:1:12
+139:0:4645
+140:2:3865
+141:0:4645
+142:1:13
+143:0:4645
+144:2:3864
+145:0:4645
+146:1:14
+147:0:4645
+148:2:3865
+149:0:4645
+150:1:15
+151:0:4645
+152:1:16
+153:0:4645
+154:2:3864
+155:0:4645
+156:1:17
+157:0:4645
+158:2:3865
+159:0:4645
+160:1:28
+161:0:4645
+162:2:3864
+163:0:4645
+164:1:32
+165:1:33
+166:1:37
+167:1:41
+168:1:42
+169:1:46
+170:1:54
+171:1:55
+172:1:59
+173:1:63
+174:1:64
+175:1:59
+176:1:63
+177:1:64
+178:1:68
+179:1:75
+180:1:82
+181:1:83
+182:1:90
+183:1:95
+184:1:102
+185:1:103
+186:1:102
+187:1:103
+188:1:110
+189:1:114
+190:0:4645
+191:2:3865
+192:0:4645
+193:1:119
+194:0:4645
+195:2:3866
+196:0:4645
+197:2:3871
+198:0:4645
+199:2:3872
+200:0:4645
+201:2:3880
+202:2:3881
+203:2:3885
+204:2:3889
+205:2:3890
+206:2:3894
+207:2:3902
+208:2:3903
+209:2:3907
+210:2:3911
+211:2:3912
+212:2:3907
+213:2:3911
+214:2:3912
+215:2:3916
+216:2:3923
+217:2:3930
+218:2:3931
+219:2:3938
+220:2:3943
+221:2:3950
+222:2:3951
+223:2:3950
+224:2:3951
+225:2:3958
+226:2:3962
+227:0:4645
+228:2:3073
+229:2:3755
+230:0:4645
+231:2:2883
+232:0:4645
+233:2:3074
+234:0:4645
+235:2:2883
+236:0:4645
+237:2:3077
+238:2:3078
+239:2:3082
+240:2:3083
+241:2:3091
+242:2:3092
+243:2:3096
+244:2:3097
+245:2:3105
+246:2:3110
+247:2:3114
+248:2:3115
+249:2:3123
+250:2:3124
+251:2:3128
+252:2:3129
+253:2:3123
+254:2:3124
+255:2:3128
+256:2:3129
+257:2:3137
+258:2:3142
+259:2:3143
+260:2:3154
+261:2:3155
+262:2:3156
+263:2:3167
+264:2:3172
+265:2:3173
+266:2:3184
+267:2:3185
+268:2:3186
+269:2:3184
+270:2:3185
+271:2:3186
+272:2:3197
+273:2:3204
+274:0:4645
+275:2:2883
+276:0:4645
+277:2:3208
+278:2:3209
+279:2:3210
+280:2:3222
+281:2:3223
+282:2:3227
+283:2:3228
+284:2:3236
+285:2:3241
+286:2:3245
+287:2:3246
+288:2:3254
+289:2:3255
+290:2:3259
+291:2:3260
+292:2:3254
+293:2:3255
+294:2:3259
+295:2:3260
+296:2:3268
+297:2:3273
+298:2:3274
+299:2:3285
+300:2:3286
+301:2:3287
+302:2:3298
+303:2:3303
+304:2:3304
+305:2:3315
+306:2:3316
+307:2:3317
+308:2:3315
+309:2:3316
+310:2:3317
+311:2:3328
+312:2:3339
+313:2:3340
+314:0:4645
+315:2:2883
+316:0:4645
+317:2:3346
+318:2:3347
+319:2:3351
+320:2:3352
+321:2:3360
+322:2:3361
+323:2:3365
+324:2:3366
+325:2:3374
+326:2:3379
+327:2:3383
+328:2:3384
+329:2:3392
+330:2:3393
+331:2:3397
+332:2:3398
+333:2:3392
+334:2:3393
+335:2:3397
+336:2:3398
+337:2:3406
+338:2:3411
+339:2:3412
+340:2:3423
+341:2:3424
+342:2:3425
+343:2:3436
+344:2:3441
+345:2:3442
+346:2:3453
+347:2:3454
+348:2:3455
+349:2:3453
+350:2:3454
+351:2:3455
+352:2:3466
+353:0:4645
+354:2:2883
+355:0:4645
+356:2:3475
+357:2:3476
+358:2:3480
+359:2:3481
+360:2:3489
+361:2:3490
+362:2:3494
+363:2:3495
+364:2:3503
+365:2:3508
+366:2:3512
+367:2:3513
+368:2:3521
+369:2:3522
+370:2:3526
+371:2:3527
+372:2:3521
+373:2:3522
+374:2:3526
+375:2:3527
+376:2:3535
+377:2:3540
+378:2:3541
+379:2:3552
+380:2:3553
+381:2:3554
+382:2:3565
+383:2:3570
+384:2:3571
+385:2:3582
+386:2:3583
+387:2:3584
+388:2:3582
+389:2:3583
+390:2:3584
+391:2:3595
+392:2:3602
+393:0:4645
+394:2:2883
+395:0:4645
+396:2:3606
+397:2:3607
+398:2:3608
+399:2:3620
+400:2:3621
+401:2:3625
+402:2:3626
+403:2:3634
+404:2:3639
+405:2:3643
+406:2:3644
+407:2:3652
+408:2:3653
+409:2:3657
+410:2:3658
+411:2:3652
+412:2:3653
+413:2:3657
+414:2:3658
+415:2:3666
+416:2:3671
+417:2:3672
+418:2:3683
+419:2:3684
+420:2:3685
+421:2:3696
+422:2:3701
+423:2:3702
+424:2:3713
+425:2:3714
+426:2:3715
+427:2:3713
+428:2:3714
+429:2:3715
+430:2:3726
+431:2:3736
+432:2:3737
+433:0:4645
+434:2:2883
+435:0:4645
+436:2:3743
+437:0:4645
+438:2:4368
+439:2:4369
+440:2:4373
+441:2:4377
+442:2:4378
+443:2:4382
+444:2:4390
+445:2:4391
+446:2:4395
+447:2:4399
+448:2:4400
+449:2:4395
+450:2:4399
+451:2:4400
+452:2:4404
+453:2:4411
+454:2:4418
+455:2:4419
+456:2:4426
+457:2:4431
+458:2:4438
+459:2:4439
+460:2:4438
+461:2:4439
+462:2:4446
+463:2:4450
+464:0:4645
+465:2:4455
+466:0:4645
+467:2:4456
+468:0:4645
+469:2:4457
+470:0:4645
+471:2:4458
+472:0:4645
+473:1:28
+474:0:4645
+475:2:4459
+476:0:4645
+477:1:32
+478:1:33
+479:1:37
+480:1:41
+481:1:42
+482:1:46
+483:1:54
+484:1:55
+485:1:59
+486:1:63
+487:1:64
+488:1:59
+489:1:63
+490:1:64
+491:1:68
+492:1:75
+493:1:82
+494:1:83
+495:1:90
+496:1:95
+497:1:102
+498:1:103
+499:1:102
+500:1:103
+501:1:110
+502:1:114
+503:0:4645
+504:2:4458
+505:0:4645
+506:1:119
+507:0:4645
+508:2:4459
+509:0:4645
+510:2:4460
+511:0:4645
+512:2:4465
+513:0:4645
+514:2:4466
+515:0:4645
+516:2:4474
+517:2:4475
+518:2:4479
+519:2:4483
+520:2:4484
+521:2:4488
+522:2:4496
+523:2:4497
+524:2:4501
+525:2:4505
+526:2:4506
+527:2:4501
+528:2:4505
+529:2:4506
+530:2:4510
+531:2:4517
+532:2:4524
+533:2:4525
+534:2:4532
+535:2:4537
+536:2:4544
+537:2:4545
+538:2:4544
+539:2:4545
+540:2:4552
+541:2:4556
+542:0:4645
+543:2:3745
+544:2:3755
+545:0:4645
+546:2:2883
+547:0:4645
+548:2:3746
+549:2:3747
+550:0:4645
+551:2:2883
+552:0:4645
+553:2:3751
+554:0:4645
+555:2:3759
+556:0:4645
+557:2:2879
+558:0:4645
+559:2:2881
+560:0:4645
+561:2:2882
+562:0:4645
+563:2:2883
+564:0:4645
+565:2:3064
+566:2:3065
+567:2:3066
+568:0:4645
+569:2:2883
+570:0:4645
+571:2:2884
+572:2:2885
+573:2:2889
+574:2:2890
+575:2:2898
+576:2:2899
+577:2:2903
+578:2:2904
+579:2:2912
+580:2:2917
+581:2:2918
+582:2:2930
+583:2:2931
+584:2:2932
+585:2:2930
+586:2:2931
+587:2:2935
+588:2:2936
+589:2:2944
+590:2:2949
+591:2:2950
+592:2:2961
+593:2:2962
+594:2:2963
+595:2:2974
+596:2:2979
+597:2:2980
+598:2:2991
+599:2:2992
+600:2:2993
+601:2:2991
+602:2:2992
+603:2:2993
+604:2:3004
+605:2:3012
+606:0:4645
+607:2:2883
+608:0:4645
+609:2:3071
+610:0:4645
+611:2:3774
+612:2:3775
+613:2:3779
+614:2:3783
+615:2:3784
+616:2:3788
+617:2:3796
+618:2:3797
+619:2:3801
+620:2:3802
+621:2:3801
+622:2:3805
+623:2:3806
+624:2:3810
+625:2:3817
+626:2:3824
+627:2:3825
+628:2:3832
+629:2:3837
+630:2:3844
+631:2:3845
+632:2:3844
+633:2:3845
+634:2:3852
+635:2:3856
+636:0:4645
+637:2:3861
+638:0:4645
+639:2:3862
+640:0:4645
+641:2:3863
+642:0:4645
+643:2:3864
+644:0:4645
+645:1:28
+646:0:4645
+647:2:3865
+648:0:4645
+649:1:32
+650:1:33
+651:1:37
+652:1:41
+653:1:42
+654:1:46
+655:1:54
+656:1:55
+657:1:59
+658:1:63
+659:1:64
+660:1:59
+661:1:63
+662:1:64
+663:1:68
+664:1:75
+665:1:82
+666:1:83
+667:1:90
+668:1:95
+669:1:102
+670:1:103
+671:1:102
+672:1:103
+673:1:110
+674:1:114
+675:0:4645
+676:2:3864
+677:0:4645
+678:1:119
+679:0:4645
+680:2:3865
+681:0:4645
+682:2:3866
+683:0:4645
+684:2:3871
+685:0:4645
+686:2:3872
+687:0:4645
+688:2:3880
+689:2:3881
+690:2:3885
+691:2:3889
+692:2:3890
+693:2:3894
+694:2:3902
+695:2:3903
+696:2:3907
+697:2:3911
+698:2:3912
+699:2:3907
+700:2:3911
+701:2:3912
+702:2:3916
+703:2:3923
+704:2:3930
+705:2:3931
+706:2:3938
+707:2:3943
+708:2:3950
+709:2:3951
+710:2:3950
+711:2:3951
+712:2:3958
+713:2:3962
+714:0:4645
+715:2:3073
+716:2:3755
+717:0:4645
+718:2:2883
+719:0:4645
+720:2:3074
+721:0:4645
+722:2:2883
+723:0:4645
+724:2:3077
+725:2:3078
+726:2:3082
+727:2:3083
+728:2:3091
+729:2:3092
+730:2:3096
+731:2:3097
+732:2:3105
+733:2:3110
+734:2:3114
+735:2:3115
+736:2:3123
+737:2:3124
+738:2:3128
+739:2:3129
+740:2:3123
+741:2:3124
+742:2:3128
+743:2:3129
+744:2:3137
+745:2:3142
+746:2:3143
+747:2:3154
+748:2:3155
+749:2:3156
+750:2:3167
+751:2:3172
+752:2:3173
+753:2:3184
+754:2:3185
+755:2:3186
+756:2:3184
+757:2:3185
+758:2:3186
+759:2:3197
+760:2:3204
+761:0:4645
+762:2:2883
+763:0:4645
+764:2:3208
+765:2:3209
+766:2:3210
+767:2:3222
+768:2:3223
+769:2:3227
+770:2:3228
+771:2:3236
+772:2:3241
+773:2:3245
+774:2:3246
+775:2:3254
+776:2:3255
+777:2:3259
+778:2:3260
+779:2:3254
+780:2:3255
+781:2:3259
+782:2:3260
+783:2:3268
+784:2:3273
+785:2:3274
+786:2:3285
+787:2:3286
+788:2:3287
+789:2:3298
+790:2:3303
+791:2:3304
+792:2:3315
+793:2:3316
+794:2:3317
+795:2:3315
+796:2:3316
+797:2:3317
+798:2:3328
+799:2:3339
+800:2:3340
+801:0:4645
+802:2:2883
+803:0:4645
+804:2:3346
+805:2:3347
+806:2:3351
+807:2:3352
+808:2:3360
+809:2:3361
+810:2:3365
+811:2:3366
+812:2:3374
+813:2:3379
+814:2:3383
+815:2:3384
+816:2:3392
+817:2:3393
+818:2:3397
+819:2:3398
+820:2:3392
+821:2:3393
+822:2:3397
+823:2:3398
+824:2:3406
+825:2:3411
+826:2:3412
+827:2:3423
+828:2:3424
+829:2:3425
+830:2:3436
+831:2:3441
+832:2:3442
+833:2:3453
+834:2:3454
+835:2:3455
+836:2:3453
+837:2:3454
+838:2:3455
+839:2:3466
+840:0:4645
+841:2:2883
+842:0:4645
+843:2:3475
+844:2:3476
+845:2:3480
+846:2:3481
+847:2:3489
+848:2:3490
+849:2:3494
+850:2:3495
+851:2:3503
+852:2:3508
+853:2:3512
+854:2:3513
+855:2:3521
+856:2:3522
+857:2:3526
+858:2:3527
+859:2:3521
+860:2:3522
+861:2:3526
+862:2:3527
+863:2:3535
+864:2:3540
+865:2:3541
+866:2:3552
+867:2:3553
+868:2:3554
+869:2:3565
+870:2:3570
+871:2:3571
+872:2:3582
+873:2:3583
+874:2:3584
+875:2:3582
+876:2:3583
+877:2:3584
+878:2:3595
+879:2:3602
+880:0:4645
+881:2:2883
+882:0:4645
+883:2:3606
+884:2:3607
+885:2:3608
+886:2:3620
+887:2:3621
+888:2:3625
+889:2:3626
+890:2:3634
+891:2:3639
+892:2:3643
+893:2:3644
+894:2:3652
+895:2:3653
+896:2:3657
+897:2:3658
+898:2:3652
+899:2:3653
+900:2:3657
+901:2:3658
+902:2:3666
+903:2:3671
+904:2:3672
+905:2:3683
+906:2:3684
+907:2:3685
+908:2:3696
+909:2:3701
+910:2:3702
+911:2:3713
+912:2:3714
+913:2:3715
+914:2:3713
+915:2:3714
+916:2:3715
+917:2:3726
+918:2:3736
+919:2:3737
+920:0:4645
+921:2:2883
+922:0:4645
+923:2:3743
+924:0:4645
+925:2:4368
+926:2:4369
+927:2:4373
+928:2:4377
+929:2:4378
+930:2:4382
+931:2:4390
+932:2:4391
+933:2:4395
+934:2:4399
+935:2:4400
+936:2:4395
+937:2:4399
+938:2:4400
+939:2:4404
+940:2:4411
+941:2:4418
+942:2:4419
+943:2:4426
+944:2:4431
+945:2:4438
+946:2:4439
+947:2:4438
+948:2:4439
+949:2:4446
+950:2:4450
+951:0:4645
+952:2:4455
+953:0:4645
+954:2:4456
+955:0:4645
+956:2:4457
+957:0:4645
+958:2:4458
+959:0:4645
+960:1:28
+961:0:4645
+962:2:4459
+963:0:4645
+964:1:32
+965:1:33
+966:1:37
+967:1:41
+968:1:42
+969:1:46
+970:1:54
+971:1:55
+972:1:59
+973:1:63
+974:1:64
+975:1:59
+976:1:63
+977:1:64
+978:1:68
+979:1:75
+980:1:82
+981:1:83
+982:1:90
+983:1:95
+984:1:102
+985:1:103
+986:1:102
+987:1:103
+988:1:110
+989:1:114
+990:0:4645
+991:2:4458
+992:0:4645
+993:1:119
+994:0:4645
+995:2:4459
+996:0:4645
+997:2:4460
+998:0:4645
+999:2:4465
+1000:0:4645
+1001:2:4466
+1002:0:4645
+1003:2:4474
+1004:2:4475
+1005:2:4479
+1006:2:4483
+1007:2:4484
+1008:2:4488
+1009:2:4496
+1010:2:4497
+1011:2:4501
+1012:2:4505
+1013:2:4506
+1014:2:4501
+1015:2:4505
+1016:2:4506
+1017:2:4510
+1018:2:4517
+1019:2:4524
+1020:2:4525
+1021:2:4532
+1022:2:4537
+1023:2:4544
+1024:2:4545
+1025:2:4544
+1026:2:4545
+1027:2:4552
+1028:2:4556
+1029:0:4645
+1030:2:3745
+1031:2:3755
+1032:0:4645
+1033:2:2883
+1034:0:4645
+1035:2:3746
+1036:2:3747
+1037:0:4645
+1038:2:2883
+1039:0:4645
+1040:2:3751
+1041:0:4645
+1042:2:3759
+1043:0:4645
+1044:2:2879
+1045:0:4645
+1046:2:2881
+1047:0:4645
+1048:2:2882
+1049:0:4645
+1050:2:2883
+1051:0:4645
+1052:2:2884
+1053:2:2885
+1054:2:2889
+1055:2:2890
+1056:2:2898
+1057:2:2899
+1058:2:2903
+1059:2:2904
+1060:2:2912
+1061:2:2917
+1062:2:2921
+1063:2:2922
+1064:2:2930
+1065:2:2931
+1066:2:2935
+1067:2:2936
+1068:2:2930
+1069:2:2931
+1070:2:2932
+1071:2:2944
+1072:2:2949
+1073:2:2950
+1074:2:2961
+1075:2:2962
+1076:2:2963
+1077:2:2974
+1078:2:2979
+1079:2:2980
+1080:2:2991
+1081:2:2992
+1082:2:2993
+1083:2:2991
+1084:2:2992
+1085:2:2993
+1086:2:3004
+1087:2:3012
+1088:0:4645
+1089:2:2883
+1090:0:4645
+1091:2:3064
+1092:2:3065
+1093:2:3066
+1094:0:4645
+1095:2:2883
+1096:0:4645
+1097:2:3071
+1098:0:4645
+1099:1:120
+1100:0:4645
+1101:1:19
+1102:0:4645
+1103:1:127
+1104:1:128
+1105:1:132
+1106:1:133
+1107:1:141
+1108:1:142
+1109:1:146
+1110:1:147
+1111:1:155
+1112:1:160
+1113:1:164
+1114:1:165
+1115:1:173
+1116:1:174
+1117:1:178
+1118:1:179
+1119:1:173
+1120:1:174
+1121:1:178
+1122:1:179
+1123:1:187
+1124:1:192
+1125:1:193
+1126:1:204
+1127:1:205
+1128:1:206
+1129:1:217
+1130:1:222
+1131:1:223
+1132:1:234
+1133:1:235
+1134:1:236
+1135:1:234
+1136:1:235
+1137:1:236
+1138:1:247
+1139:0:4645
+1140:1:15
+1141:0:4645
+1142:1:16
+1143:0:4645
+1144:1:17
+1145:0:4645
+1146:1:120
+1147:0:4645
+1148:1:19
+1149:0:4645
+1150:1:256
+1151:1:257
+1152:0:4645
+1153:1:15
+1154:0:4645
+1155:1:16
+1156:0:4645
+1157:1:17
+1158:0:4645
+1159:1:120
+1160:0:4645
+1161:1:19
+1162:0:4645
+1163:1:263
+1164:1:264
+1165:1:268
+1166:1:269
+1167:1:277
+1168:1:278
+1169:1:282
+1170:1:283
+1171:1:291
+1172:1:296
+1173:1:300
+1174:1:301
+1175:1:309
+1176:1:310
+1177:1:314
+1178:1:315
+1179:1:309
+1180:1:310
+1181:1:314
+1182:1:315
+1183:1:323
+1184:1:328
+1185:1:329
+1186:1:340
+1187:1:341
+1188:1:342
+1189:1:353
+1190:1:358
+1191:1:359
+1192:1:370
+1193:1:371
+1194:1:372
+1195:1:370
+1196:1:371
+1197:1:372
+1198:1:383
+1199:0:4645
+1200:1:15
+1201:0:4645
+1202:1:16
+1203:0:4645
+1204:1:17
+1205:0:4645
+1206:1:120
+1207:0:4645
+1208:1:19
+1209:0:4645
+1210:1:392
+1211:1:393
+1212:1:397
+1213:1:398
+1214:1:406
+1215:1:407
+1216:1:411
+1217:1:412
+1218:1:420
+1219:1:425
+1220:1:429
+1221:1:430
+1222:1:438
+1223:1:439
+1224:1:443
+1225:1:444
+1226:1:438
+1227:1:439
+1228:1:443
+1229:1:444
+1230:1:452
+1231:1:457
+1232:1:458
+1233:1:469
+1234:1:470
+1235:1:471
+1236:1:482
+1237:1:487
+1238:1:488
+1239:1:499
+1240:1:500
+1241:1:501
+1242:1:499
+1243:1:500
+1244:1:501
+1245:1:512
+1246:1:519
+1247:0:4645
+1248:1:15
+1249:0:4645
+1250:1:16
+1251:0:4645
+1252:1:17
+1253:0:4645
+1254:1:120
+1255:0:4645
+1256:1:19
+1257:0:4645
+1258:1:657
+1259:1:658
+1260:1:662
+1261:1:663
+1262:1:671
+1263:1:672
+1264:1:673
+1265:1:685
+1266:1:690
+1267:1:694
+1268:1:695
+1269:1:703
+1270:1:704
+1271:1:708
+1272:1:709
+1273:1:703
+1274:1:704
+1275:1:708
+1276:1:709
+1277:1:717
+1278:1:722
+1279:1:723
+1280:1:734
+1281:1:735
+1282:1:736
+1283:1:747
+1284:1:752
+1285:1:753
+1286:1:764
+1287:1:765
+1288:1:766
+1289:1:764
+1290:1:765
+1291:1:766
+1292:1:777
+1293:0:4645
+1294:1:15
+1295:0:4645
+1296:1:16
+1297:0:4645
+1298:1:17
+1299:0:4645
+1300:1:120
+1301:0:4645
+1302:1:19
+1303:0:4645
+1304:1:786
+1305:1:789
+1306:1:790
+1307:0:4645
+1308:1:15
+1309:0:4645
+1310:1:16
+1311:0:4645
+1312:1:17
+1313:0:4645
+1314:1:120
+1315:0:4645
+1316:1:19
+1317:0:4645
+1318:1:1053
+1319:1:1054
+1320:1:1058
+1321:1:1059
+1322:1:1067
+1323:1:1068
+1324:1:1072
+1325:1:1073
+1326:1:1081
+1327:1:1086
+1328:1:1090
+1329:1:1091
+1330:1:1099
+1331:1:1100
+1332:1:1104
+1333:1:1105
+1334:1:1099
+1335:1:1100
+1336:1:1104
+1337:1:1105
+1338:1:1113
+1339:1:1118
+1340:1:1119
+1341:1:1130
+1342:1:1131
+1343:1:1132
+1344:1:1143
+1345:1:1148
+1346:1:1149
+1347:1:1160
+1348:1:1161
+1349:1:1162
+1350:1:1160
+1351:1:1161
+1352:1:1162
+1353:1:1173
+1354:1:1180
+1355:1:1184
+1356:0:4645
+1357:1:15
+1358:0:4645
+1359:1:16
+1360:0:4645
+1361:1:17
+1362:0:4645
+1363:1:120
+1364:0:4645
+1365:1:19
+1366:0:4645
+1367:1:1185
+1368:1:1186
+1369:1:1190
+1370:1:1191
+1371:1:1199
+1372:1:1200
+1373:1:1201
+1374:1:1213
+1375:1:1218
+1376:1:1222
+1377:1:1223
+1378:1:1231
+1379:1:1232
+1380:1:1236
+1381:1:1237
+1382:1:1231
+1383:1:1232
+1384:1:1236
+1385:1:1237
+1386:1:1245
+1387:1:1250
+1388:1:1251
+1389:1:1262
+1390:1:1263
+1391:1:1264
+1392:1:1275
+1393:1:1280
+1394:1:1281
+1395:1:1292
+1396:1:1293
+1397:1:1294
+1398:1:1292
+1399:1:1293
+1400:1:1294
+1401:1:1305
+1402:0:4645
+1403:1:15
+1404:0:4645
+1405:1:16
+1406:0:4645
+1407:1:17
+1408:0:4645
+1409:1:120
+1410:0:4645
+1411:1:19
+1412:0:4645
+1413:1:1314
+1414:0:4645
+1415:1:2778
+1416:1:2785
+1417:1:2786
+1418:1:2793
+1419:1:2798
+1420:1:2805
+1421:1:2806
+1422:1:2805
+1423:1:2806
+1424:1:2813
+1425:1:2817
+1426:0:4645
+1427:2:3774
+1428:2:3775
+1429:2:3779
+1430:2:3783
+1431:2:3784
+1432:2:3788
+1433:2:3793
+1434:2:3801
+1435:2:3805
+1436:2:3806
+1437:2:3801
+1438:2:3802
+1439:2:3810
+1440:2:3817
+1441:2:3824
+1442:2:3825
+1443:2:3832
+1444:2:3837
+1445:2:3844
+1446:2:3845
+1447:2:3844
+1448:2:3845
+1449:2:3852
+1450:2:3856
+1451:0:4645
+1452:2:3861
+1453:0:4645
+1454:2:3862
+1455:0:4645
+1456:2:3863
+1457:0:4645
+1458:2:3864
+1459:0:4645
+1460:1:1316
+1461:1:1317
+1462:0:4643
+1463:2:3865
+1464:0:4649
+1465:1:2475
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_single_flip.define b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_single_flip.define
new file mode 100644 (file)
index 0000000..5e642ef
--- /dev/null
@@ -0,0 +1 @@
+#define SINGLE_FLIP
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_single_flip.log b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_single_flip.log
new file mode 100644 (file)
index 0000000..4f60a26
--- /dev/null
@@ -0,0 +1,783 @@
+make[1]: Entering directory `/home/compudj/doc/userspace-rcu/formal-model/urcu-controldataflow'
+rm -f pan* trail.out .input.spin* *.spin.trail .input.define
+touch .input.define
+cat .input.define >> pan.ltl
+cat DEFINES >> pan.ltl
+spin -f "!(`cat urcu_free.ltl | grep -v ^//`)" >> pan.ltl
+cp urcu_free_single_flip.define .input.define
+cat .input.define > .input.spin
+cat DEFINES >> .input.spin
+cat urcu.spin >> .input.spin
+rm -f .input.spin.trail
+spin -a -X -N pan.ltl .input.spin
+Exit-Status 0
+gcc -O2 -w -DHASH64 -o pan pan.c
+./pan -a -v -c1 -X -m10000000 -w20
+warning: for p.o. reduction to be valid the never claim must be stutter-invariant
+(never claims generated from LTL formulae are stutter-invariant)
+depth 0: Claim reached state 5 (line 1245)
+Depth=    9313 States=    1e+06 Transitions=  1.5e+08 Memory=   550.432        t=    185 R=   5e+03
+Depth=    9313 States=    2e+06 Transitions= 3.71e+08 Memory=   634.318        t=    475 R=   4e+03
+Depth=    9313 States=    3e+06 Transitions= 6.52e+08 Memory=   718.303        t=    847 R=   4e+03
+pan: resizing hashtable to -w22..  done
+Depth=    9313 States=    4e+06 Transitions= 8.49e+08 Memory=   833.311        t= 1.09e+03 R=   4e+03
+Depth=    9313 States=    5e+06 Transitions= 1.02e+09 Memory=   917.295        t= 1.3e+03 R=   4e+03
+Depth=    9313 States=    6e+06 Transitions= 1.18e+09 Memory=  1001.279        t= 1.51e+03 R=   4e+03
+Depth=    9313 States=    7e+06 Transitions= 1.44e+09 Memory=  1085.264        t= 1.86e+03 R=   4e+03
+Depth=    9313 States=    8e+06 Transitions= 1.69e+09 Memory=  1169.151        t= 2.17e+03 R=   4e+03
+Depth=    9313 States=    9e+06 Transitions= 1.87e+09 Memory=  1253.135        t= 2.42e+03 R=   4e+03
+pan: resizing hashtable to -w24..  done
+Depth=    9313 States=    1e+07 Transitions= 2.08e+09 Memory=  1461.115        t= 2.68e+03 R=   4e+03
+Depth=    9313 States=  1.1e+07 Transitions= 2.38e+09 Memory=  1545.100        t= 3.06e+03 R=   4e+03
+Depth=    9530 States=  1.2e+07 Transitions=  2.6e+09 Memory=  1629.084        t= 3.35e+03 R=   4e+03
+Depth=    9530 States=  1.3e+07 Transitions= 2.85e+09 Memory=  1713.068        t= 3.67e+03 R=   4e+03
+Depth=    9530 States=  1.4e+07 Transitions= 3.06e+09 Memory=  1797.053        t= 3.93e+03 R=   4e+03
+Depth=    9530 States=  1.5e+07 Transitions= 3.32e+09 Memory=  1881.037        t= 4.28e+03 R=   4e+03
+Depth=    9530 States=  1.6e+07 Transitions= 3.52e+09 Memory=  1964.924        t= 4.54e+03 R=   4e+03
+Depth=    9530 States=  1.7e+07 Transitions= 3.85e+09 Memory=  2048.908        t= 4.96e+03 R=   3e+03
+Depth=    9530 States=  1.8e+07 Transitions= 4.15e+09 Memory=  2132.893        t= 5.34e+03 R=   3e+03
+Depth=    9530 States=  1.9e+07 Transitions= 4.35e+09 Memory=  2216.877        t= 5.58e+03 R=   3e+03
+Depth=    9530 States=    2e+07 Transitions= 4.59e+09 Memory=  2300.861        t= 5.89e+03 R=   3e+03
+Depth=    9530 States=  2.1e+07 Transitions= 4.83e+09 Memory=  2384.846        t= 6.21e+03 R=   3e+03
+Depth=    9530 States=  2.2e+07 Transitions= 5.07e+09 Memory=  2468.830        t= 6.52e+03 R=   3e+03
+Depth=    9530 States=  2.3e+07 Transitions= 5.31e+09 Memory=  2552.717        t= 6.83e+03 R=   3e+03
+Depth=    9530 States=  2.4e+07 Transitions=  5.5e+09 Memory=  2636.701        t= 7.08e+03 R=   3e+03
+pan: claim violated! (at depth 1365)
+pan: wrote .input.spin.trail
+
+(Spin Version 5.1.7 -- 23 December 2008)
+Warning: Search not completed
+       + Partial Order Reduction
+
+Full statespace search for:
+       never claim             +
+       assertion violations    + (if within scope of claim)
+       acceptance   cycles     + (fairness disabled)
+       invalid end states      - (disabled by never claim)
+
+State-vector 88 byte, depth reached 9530, errors: 1
+ 24603269 states, stored
+5.6549664e+09 states, matched
+5.6795697e+09 transitions (= stored+matched)
+3.17715e+10 atomic steps
+hash conflicts: 3.9132393e+09 (resolved)
+
+Stats on memory usage (in Megabytes):
+ 2721.767      equivalent memory usage for states (stored*(State-vector + overhead))
+ 2102.819      actual memory usage for states (compression: 77.26%)
+               state-vector as stored = 62 byte + 28 byte overhead
+  128.000      memory used for hash table (-w24)
+  457.764      memory used for DFS stack (-m10000000)
+    1.198      memory lost to fragmentation
+ 2687.385      total actual memory usage
+
+unreached in proctype urcu_reader
+       line 250, "pan.___", state 32, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 54, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 63, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 79, "(1)"
+       line 231, "pan.___", state 87, "(1)"
+       line 235, "pan.___", state 99, "(1)"
+       line 239, "pan.___", state 107, "(1)"
+       line 387, "pan.___", state 132, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 164, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 178, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 197, "(1)"
+       line 413, "pan.___", state 227, "(1)"
+       line 417, "pan.___", state 240, "(1)"
+       line 663, "pan.___", state 261, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<1))"
+       line 387, "pan.___", state 268, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 300, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 314, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 333, "(1)"
+       line 413, "pan.___", state 363, "(1)"
+       line 417, "pan.___", state 376, "(1)"
+       line 387, "pan.___", state 397, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 429, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 443, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 462, "(1)"
+       line 413, "pan.___", state 492, "(1)"
+       line 417, "pan.___", state 505, "(1)"
+       line 387, "pan.___", state 528, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 530, "(1)"
+       line 387, "pan.___", state 531, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 387, "pan.___", state 531, "else"
+       line 387, "pan.___", state 534, "(1)"
+       line 391, "pan.___", state 542, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 544, "(1)"
+       line 391, "pan.___", state 545, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 391, "pan.___", state 545, "else"
+       line 391, "pan.___", state 548, "(1)"
+       line 391, "pan.___", state 549, "(1)"
+       line 391, "pan.___", state 549, "(1)"
+       line 389, "pan.___", state 554, "((i<1))"
+       line 389, "pan.___", state 554, "((i>=1))"
+       line 396, "pan.___", state 560, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 562, "(1)"
+       line 396, "pan.___", state 563, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 563, "else"
+       line 396, "pan.___", state 566, "(1)"
+       line 396, "pan.___", state 567, "(1)"
+       line 396, "pan.___", state 567, "(1)"
+       line 400, "pan.___", state 574, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 576, "(1)"
+       line 400, "pan.___", state 577, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 577, "else"
+       line 400, "pan.___", state 580, "(1)"
+       line 400, "pan.___", state 581, "(1)"
+       line 400, "pan.___", state 581, "(1)"
+       line 398, "pan.___", state 586, "((i<2))"
+       line 398, "pan.___", state 586, "((i>=2))"
+       line 404, "pan.___", state 593, "(1)"
+       line 404, "pan.___", state 594, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 594, "else"
+       line 404, "pan.___", state 597, "(1)"
+       line 404, "pan.___", state 598, "(1)"
+       line 404, "pan.___", state 598, "(1)"
+       line 408, "pan.___", state 606, "(1)"
+       line 408, "pan.___", state 607, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 607, "else"
+       line 408, "pan.___", state 610, "(1)"
+       line 408, "pan.___", state 611, "(1)"
+       line 408, "pan.___", state 611, "(1)"
+       line 406, "pan.___", state 616, "((i<1))"
+       line 406, "pan.___", state 616, "((i>=1))"
+       line 413, "pan.___", state 623, "(1)"
+       line 413, "pan.___", state 624, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 624, "else"
+       line 413, "pan.___", state 627, "(1)"
+       line 413, "pan.___", state 628, "(1)"
+       line 413, "pan.___", state 628, "(1)"
+       line 417, "pan.___", state 636, "(1)"
+       line 417, "pan.___", state 637, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 637, "else"
+       line 417, "pan.___", state 640, "(1)"
+       line 417, "pan.___", state 641, "(1)"
+       line 417, "pan.___", state 641, "(1)"
+       line 415, "pan.___", state 646, "((i<2))"
+       line 415, "pan.___", state 646, "((i>=2))"
+       line 422, "pan.___", state 650, "(1)"
+       line 422, "pan.___", state 650, "(1)"
+       line 663, "pan.___", state 653, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 663, "pan.___", state 654, "_proc_urcu_reader = (_proc_urcu_reader|(1<<5))"
+       line 663, "pan.___", state 655, "(1)"
+       line 387, "pan.___", state 662, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 694, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 708, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 727, "(1)"
+       line 413, "pan.___", state 757, "(1)"
+       line 417, "pan.___", state 770, "(1)"
+       line 387, "pan.___", state 798, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 800, "(1)"
+       line 387, "pan.___", state 801, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 387, "pan.___", state 801, "else"
+       line 387, "pan.___", state 804, "(1)"
+       line 391, "pan.___", state 812, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 814, "(1)"
+       line 391, "pan.___", state 815, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 391, "pan.___", state 815, "else"
+       line 391, "pan.___", state 818, "(1)"
+       line 391, "pan.___", state 819, "(1)"
+       line 391, "pan.___", state 819, "(1)"
+       line 389, "pan.___", state 824, "((i<1))"
+       line 389, "pan.___", state 824, "((i>=1))"
+       line 396, "pan.___", state 830, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 832, "(1)"
+       line 396, "pan.___", state 833, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 833, "else"
+       line 396, "pan.___", state 836, "(1)"
+       line 396, "pan.___", state 837, "(1)"
+       line 396, "pan.___", state 837, "(1)"
+       line 400, "pan.___", state 844, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 846, "(1)"
+       line 400, "pan.___", state 847, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 847, "else"
+       line 400, "pan.___", state 850, "(1)"
+       line 400, "pan.___", state 851, "(1)"
+       line 400, "pan.___", state 851, "(1)"
+       line 398, "pan.___", state 856, "((i<2))"
+       line 398, "pan.___", state 856, "((i>=2))"
+       line 404, "pan.___", state 863, "(1)"
+       line 404, "pan.___", state 864, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 864, "else"
+       line 404, "pan.___", state 867, "(1)"
+       line 404, "pan.___", state 868, "(1)"
+       line 404, "pan.___", state 868, "(1)"
+       line 408, "pan.___", state 876, "(1)"
+       line 408, "pan.___", state 877, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 877, "else"
+       line 408, "pan.___", state 880, "(1)"
+       line 408, "pan.___", state 881, "(1)"
+       line 408, "pan.___", state 881, "(1)"
+       line 406, "pan.___", state 886, "((i<1))"
+       line 406, "pan.___", state 886, "((i>=1))"
+       line 413, "pan.___", state 893, "(1)"
+       line 413, "pan.___", state 894, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 894, "else"
+       line 413, "pan.___", state 897, "(1)"
+       line 413, "pan.___", state 898, "(1)"
+       line 413, "pan.___", state 898, "(1)"
+       line 417, "pan.___", state 906, "(1)"
+       line 417, "pan.___", state 907, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 907, "else"
+       line 417, "pan.___", state 910, "(1)"
+       line 417, "pan.___", state 911, "(1)"
+       line 417, "pan.___", state 911, "(1)"
+       line 422, "pan.___", state 920, "(1)"
+       line 422, "pan.___", state 920, "(1)"
+       line 387, "pan.___", state 927, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 929, "(1)"
+       line 387, "pan.___", state 930, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 387, "pan.___", state 930, "else"
+       line 387, "pan.___", state 933, "(1)"
+       line 391, "pan.___", state 941, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 943, "(1)"
+       line 391, "pan.___", state 944, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 391, "pan.___", state 944, "else"
+       line 391, "pan.___", state 947, "(1)"
+       line 391, "pan.___", state 948, "(1)"
+       line 391, "pan.___", state 948, "(1)"
+       line 389, "pan.___", state 953, "((i<1))"
+       line 389, "pan.___", state 953, "((i>=1))"
+       line 396, "pan.___", state 959, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 961, "(1)"
+       line 396, "pan.___", state 962, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 962, "else"
+       line 396, "pan.___", state 965, "(1)"
+       line 396, "pan.___", state 966, "(1)"
+       line 396, "pan.___", state 966, "(1)"
+       line 400, "pan.___", state 973, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 975, "(1)"
+       line 400, "pan.___", state 976, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 976, "else"
+       line 400, "pan.___", state 979, "(1)"
+       line 400, "pan.___", state 980, "(1)"
+       line 400, "pan.___", state 980, "(1)"
+       line 398, "pan.___", state 985, "((i<2))"
+       line 398, "pan.___", state 985, "((i>=2))"
+       line 404, "pan.___", state 992, "(1)"
+       line 404, "pan.___", state 993, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 993, "else"
+       line 404, "pan.___", state 996, "(1)"
+       line 404, "pan.___", state 997, "(1)"
+       line 404, "pan.___", state 997, "(1)"
+       line 408, "pan.___", state 1005, "(1)"
+       line 408, "pan.___", state 1006, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 1006, "else"
+       line 408, "pan.___", state 1009, "(1)"
+       line 408, "pan.___", state 1010, "(1)"
+       line 408, "pan.___", state 1010, "(1)"
+       line 406, "pan.___", state 1015, "((i<1))"
+       line 406, "pan.___", state 1015, "((i>=1))"
+       line 413, "pan.___", state 1022, "(1)"
+       line 413, "pan.___", state 1023, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 1023, "else"
+       line 413, "pan.___", state 1026, "(1)"
+       line 413, "pan.___", state 1027, "(1)"
+       line 413, "pan.___", state 1027, "(1)"
+       line 417, "pan.___", state 1035, "(1)"
+       line 417, "pan.___", state 1036, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 1036, "else"
+       line 417, "pan.___", state 1039, "(1)"
+       line 417, "pan.___", state 1040, "(1)"
+       line 417, "pan.___", state 1040, "(1)"
+       line 415, "pan.___", state 1045, "((i<2))"
+       line 415, "pan.___", state 1045, "((i>=2))"
+       line 422, "pan.___", state 1049, "(1)"
+       line 422, "pan.___", state 1049, "(1)"
+       line 671, "pan.___", state 1053, "_proc_urcu_reader = (_proc_urcu_reader|(1<<11))"
+       line 387, "pan.___", state 1058, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1090, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1104, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1123, "(1)"
+       line 413, "pan.___", state 1153, "(1)"
+       line 417, "pan.___", state 1166, "(1)"
+       line 387, "pan.___", state 1190, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1222, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1236, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1255, "(1)"
+       line 413, "pan.___", state 1285, "(1)"
+       line 417, "pan.___", state 1298, "(1)"
+       line 387, "pan.___", state 1323, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1355, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1369, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1388, "(1)"
+       line 413, "pan.___", state 1418, "(1)"
+       line 417, "pan.___", state 1431, "(1)"
+       line 387, "pan.___", state 1452, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1484, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1498, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1517, "(1)"
+       line 413, "pan.___", state 1547, "(1)"
+       line 417, "pan.___", state 1560, "(1)"
+       line 387, "pan.___", state 1586, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1618, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1632, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1651, "(1)"
+       line 413, "pan.___", state 1681, "(1)"
+       line 417, "pan.___", state 1694, "(1)"
+       line 387, "pan.___", state 1715, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1747, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1761, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1780, "(1)"
+       line 413, "pan.___", state 1810, "(1)"
+       line 417, "pan.___", state 1823, "(1)"
+       line 387, "pan.___", state 1847, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1879, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1893, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1912, "(1)"
+       line 413, "pan.___", state 1942, "(1)"
+       line 417, "pan.___", state 1955, "(1)"
+       line 710, "pan.___", state 1976, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<19))"
+       line 387, "pan.___", state 1983, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2015, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2029, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2048, "(1)"
+       line 413, "pan.___", state 2078, "(1)"
+       line 417, "pan.___", state 2091, "(1)"
+       line 387, "pan.___", state 2112, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2144, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2158, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2177, "(1)"
+       line 413, "pan.___", state 2207, "(1)"
+       line 417, "pan.___", state 2220, "(1)"
+       line 387, "pan.___", state 2243, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 2245, "(1)"
+       line 387, "pan.___", state 2246, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 387, "pan.___", state 2246, "else"
+       line 387, "pan.___", state 2249, "(1)"
+       line 391, "pan.___", state 2257, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 2259, "(1)"
+       line 391, "pan.___", state 2260, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 391, "pan.___", state 2260, "else"
+       line 391, "pan.___", state 2263, "(1)"
+       line 391, "pan.___", state 2264, "(1)"
+       line 391, "pan.___", state 2264, "(1)"
+       line 389, "pan.___", state 2269, "((i<1))"
+       line 389, "pan.___", state 2269, "((i>=1))"
+       line 396, "pan.___", state 2275, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2277, "(1)"
+       line 396, "pan.___", state 2278, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 2278, "else"
+       line 396, "pan.___", state 2281, "(1)"
+       line 396, "pan.___", state 2282, "(1)"
+       line 396, "pan.___", state 2282, "(1)"
+       line 400, "pan.___", state 2289, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2291, "(1)"
+       line 400, "pan.___", state 2292, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 2292, "else"
+       line 400, "pan.___", state 2295, "(1)"
+       line 400, "pan.___", state 2296, "(1)"
+       line 400, "pan.___", state 2296, "(1)"
+       line 398, "pan.___", state 2301, "((i<2))"
+       line 398, "pan.___", state 2301, "((i>=2))"
+       line 404, "pan.___", state 2308, "(1)"
+       line 404, "pan.___", state 2309, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 2309, "else"
+       line 404, "pan.___", state 2312, "(1)"
+       line 404, "pan.___", state 2313, "(1)"
+       line 404, "pan.___", state 2313, "(1)"
+       line 408, "pan.___", state 2321, "(1)"
+       line 408, "pan.___", state 2322, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 2322, "else"
+       line 408, "pan.___", state 2325, "(1)"
+       line 408, "pan.___", state 2326, "(1)"
+       line 408, "pan.___", state 2326, "(1)"
+       line 406, "pan.___", state 2331, "((i<1))"
+       line 406, "pan.___", state 2331, "((i>=1))"
+       line 413, "pan.___", state 2338, "(1)"
+       line 413, "pan.___", state 2339, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 2339, "else"
+       line 413, "pan.___", state 2342, "(1)"
+       line 413, "pan.___", state 2343, "(1)"
+       line 413, "pan.___", state 2343, "(1)"
+       line 417, "pan.___", state 2351, "(1)"
+       line 417, "pan.___", state 2352, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 2352, "else"
+       line 417, "pan.___", state 2355, "(1)"
+       line 417, "pan.___", state 2356, "(1)"
+       line 417, "pan.___", state 2356, "(1)"
+       line 415, "pan.___", state 2361, "((i<2))"
+       line 415, "pan.___", state 2361, "((i>=2))"
+       line 422, "pan.___", state 2365, "(1)"
+       line 422, "pan.___", state 2365, "(1)"
+       line 710, "pan.___", state 2368, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 710, "pan.___", state 2369, "_proc_urcu_reader = (_proc_urcu_reader|(1<<23))"
+       line 710, "pan.___", state 2370, "(1)"
+       line 387, "pan.___", state 2377, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2409, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2423, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2442, "(1)"
+       line 413, "pan.___", state 2472, "(1)"
+       line 417, "pan.___", state 2485, "(1)"
+       line 387, "pan.___", state 2512, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2544, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2558, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2577, "(1)"
+       line 413, "pan.___", state 2607, "(1)"
+       line 417, "pan.___", state 2620, "(1)"
+       line 387, "pan.___", state 2641, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2673, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2687, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2706, "(1)"
+       line 413, "pan.___", state 2736, "(1)"
+       line 417, "pan.___", state 2749, "(1)"
+       line 227, "pan.___", state 2782, "(1)"
+       line 235, "pan.___", state 2802, "(1)"
+       line 239, "pan.___", state 2810, "(1)"
+       line 227, "pan.___", state 2825, "(1)"
+       line 235, "pan.___", state 2845, "(1)"
+       line 239, "pan.___", state 2853, "(1)"
+       line 870, "pan.___", state 2870, "-end-"
+       (278 of 2870 states)
+unreached in proctype urcu_writer
+       line 387, "pan.___", state 22, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 36, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 54, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 87, "(1)"
+       line 408, "pan.___", state 100, "(1)"
+       line 413, "pan.___", state 117, "(1)"
+       line 250, "pan.___", state 153, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 162, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 175, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 215, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 229, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 247, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 261, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 280, "(1)"
+       line 408, "pan.___", state 293, "(1)"
+       line 413, "pan.___", state 310, "(1)"
+       line 417, "pan.___", state 323, "(1)"
+       line 391, "pan.___", state 360, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 378, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 392, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 424, "(1)"
+       line 413, "pan.___", state 441, "(1)"
+       line 417, "pan.___", state 454, "(1)"
+       line 387, "pan.___", state 483, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 485, "(1)"
+       line 387, "pan.___", state 486, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 387, "pan.___", state 486, "else"
+       line 387, "pan.___", state 489, "(1)"
+       line 391, "pan.___", state 497, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 499, "(1)"
+       line 391, "pan.___", state 500, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 391, "pan.___", state 500, "else"
+       line 391, "pan.___", state 503, "(1)"
+       line 391, "pan.___", state 504, "(1)"
+       line 391, "pan.___", state 504, "(1)"
+       line 389, "pan.___", state 509, "((i<1))"
+       line 389, "pan.___", state 509, "((i>=1))"
+       line 396, "pan.___", state 515, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 517, "(1)"
+       line 396, "pan.___", state 518, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 518, "else"
+       line 396, "pan.___", state 521, "(1)"
+       line 396, "pan.___", state 522, "(1)"
+       line 396, "pan.___", state 522, "(1)"
+       line 400, "pan.___", state 529, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 531, "(1)"
+       line 400, "pan.___", state 532, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 532, "else"
+       line 400, "pan.___", state 535, "(1)"
+       line 400, "pan.___", state 536, "(1)"
+       line 400, "pan.___", state 536, "(1)"
+       line 398, "pan.___", state 541, "((i<2))"
+       line 398, "pan.___", state 541, "((i>=2))"
+       line 404, "pan.___", state 548, "(1)"
+       line 404, "pan.___", state 549, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 549, "else"
+       line 404, "pan.___", state 552, "(1)"
+       line 404, "pan.___", state 553, "(1)"
+       line 404, "pan.___", state 553, "(1)"
+       line 408, "pan.___", state 561, "(1)"
+       line 408, "pan.___", state 562, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 562, "else"
+       line 408, "pan.___", state 565, "(1)"
+       line 408, "pan.___", state 566, "(1)"
+       line 408, "pan.___", state 566, "(1)"
+       line 406, "pan.___", state 571, "((i<1))"
+       line 406, "pan.___", state 571, "((i>=1))"
+       line 413, "pan.___", state 578, "(1)"
+       line 413, "pan.___", state 579, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 579, "else"
+       line 413, "pan.___", state 582, "(1)"
+       line 413, "pan.___", state 583, "(1)"
+       line 413, "pan.___", state 583, "(1)"
+       line 417, "pan.___", state 591, "(1)"
+       line 417, "pan.___", state 592, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 592, "else"
+       line 417, "pan.___", state 595, "(1)"
+       line 417, "pan.___", state 596, "(1)"
+       line 417, "pan.___", state 596, "(1)"
+       line 422, "pan.___", state 605, "(1)"
+       line 422, "pan.___", state 605, "(1)"
+       line 387, "pan.___", state 612, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 614, "(1)"
+       line 387, "pan.___", state 615, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 387, "pan.___", state 615, "else"
+       line 387, "pan.___", state 618, "(1)"
+       line 391, "pan.___", state 626, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 628, "(1)"
+       line 391, "pan.___", state 629, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 391, "pan.___", state 629, "else"
+       line 391, "pan.___", state 632, "(1)"
+       line 391, "pan.___", state 633, "(1)"
+       line 391, "pan.___", state 633, "(1)"
+       line 389, "pan.___", state 638, "((i<1))"
+       line 389, "pan.___", state 638, "((i>=1))"
+       line 396, "pan.___", state 644, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 646, "(1)"
+       line 396, "pan.___", state 647, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 647, "else"
+       line 396, "pan.___", state 650, "(1)"
+       line 396, "pan.___", state 651, "(1)"
+       line 396, "pan.___", state 651, "(1)"
+       line 400, "pan.___", state 658, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 660, "(1)"
+       line 400, "pan.___", state 661, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 661, "else"
+       line 400, "pan.___", state 664, "(1)"
+       line 400, "pan.___", state 665, "(1)"
+       line 400, "pan.___", state 665, "(1)"
+       line 398, "pan.___", state 670, "((i<2))"
+       line 398, "pan.___", state 670, "((i>=2))"
+       line 404, "pan.___", state 677, "(1)"
+       line 404, "pan.___", state 678, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 678, "else"
+       line 404, "pan.___", state 681, "(1)"
+       line 404, "pan.___", state 682, "(1)"
+       line 404, "pan.___", state 682, "(1)"
+       line 408, "pan.___", state 690, "(1)"
+       line 408, "pan.___", state 691, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 691, "else"
+       line 408, "pan.___", state 694, "(1)"
+       line 408, "pan.___", state 695, "(1)"
+       line 408, "pan.___", state 695, "(1)"
+       line 406, "pan.___", state 700, "((i<1))"
+       line 406, "pan.___", state 700, "((i>=1))"
+       line 413, "pan.___", state 707, "(1)"
+       line 413, "pan.___", state 708, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 708, "else"
+       line 413, "pan.___", state 711, "(1)"
+       line 413, "pan.___", state 712, "(1)"
+       line 413, "pan.___", state 712, "(1)"
+       line 417, "pan.___", state 720, "(1)"
+       line 417, "pan.___", state 721, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 721, "else"
+       line 417, "pan.___", state 724, "(1)"
+       line 417, "pan.___", state 725, "(1)"
+       line 417, "pan.___", state 725, "(1)"
+       line 415, "pan.___", state 730, "((i<2))"
+       line 415, "pan.___", state 730, "((i>=2))"
+       line 422, "pan.___", state 734, "(1)"
+       line 422, "pan.___", state 734, "(1)"
+       line 1078, "pan.___", state 738, "_proc_urcu_writer = (_proc_urcu_writer|(1<<10))"
+       line 387, "pan.___", state 743, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 745, "(1)"
+       line 387, "pan.___", state 746, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 387, "pan.___", state 746, "else"
+       line 387, "pan.___", state 749, "(1)"
+       line 391, "pan.___", state 757, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 759, "(1)"
+       line 391, "pan.___", state 760, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 391, "pan.___", state 760, "else"
+       line 391, "pan.___", state 763, "(1)"
+       line 391, "pan.___", state 764, "(1)"
+       line 391, "pan.___", state 764, "(1)"
+       line 389, "pan.___", state 769, "((i<1))"
+       line 389, "pan.___", state 769, "((i>=1))"
+       line 396, "pan.___", state 775, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 777, "(1)"
+       line 396, "pan.___", state 778, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 778, "else"
+       line 396, "pan.___", state 781, "(1)"
+       line 396, "pan.___", state 782, "(1)"
+       line 396, "pan.___", state 782, "(1)"
+       line 400, "pan.___", state 789, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 791, "(1)"
+       line 400, "pan.___", state 792, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 792, "else"
+       line 400, "pan.___", state 795, "(1)"
+       line 400, "pan.___", state 796, "(1)"
+       line 400, "pan.___", state 796, "(1)"
+       line 398, "pan.___", state 801, "((i<2))"
+       line 398, "pan.___", state 801, "((i>=2))"
+       line 404, "pan.___", state 808, "(1)"
+       line 404, "pan.___", state 809, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 809, "else"
+       line 404, "pan.___", state 812, "(1)"
+       line 404, "pan.___", state 813, "(1)"
+       line 404, "pan.___", state 813, "(1)"
+       line 408, "pan.___", state 821, "(1)"
+       line 408, "pan.___", state 822, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 822, "else"
+       line 408, "pan.___", state 825, "(1)"
+       line 408, "pan.___", state 826, "(1)"
+       line 408, "pan.___", state 826, "(1)"
+       line 406, "pan.___", state 831, "((i<1))"
+       line 406, "pan.___", state 831, "((i>=1))"
+       line 413, "pan.___", state 838, "(1)"
+       line 413, "pan.___", state 839, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 839, "else"
+       line 413, "pan.___", state 842, "(1)"
+       line 413, "pan.___", state 843, "(1)"
+       line 413, "pan.___", state 843, "(1)"
+       line 417, "pan.___", state 851, "(1)"
+       line 417, "pan.___", state 852, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 852, "else"
+       line 417, "pan.___", state 855, "(1)"
+       line 417, "pan.___", state 856, "(1)"
+       line 417, "pan.___", state 856, "(1)"
+       line 415, "pan.___", state 861, "((i<2))"
+       line 415, "pan.___", state 861, "((i>=2))"
+       line 422, "pan.___", state 865, "(1)"
+       line 422, "pan.___", state 865, "(1)"
+       line 1093, "pan.___", state 870, "_proc_urcu_writer = (_proc_urcu_writer|(1<<11))"
+       line 1088, "pan.___", state 871, "(((tmp2&((1<<7)-1))&&((tmp2^0)&(1<<7))))"
+       line 1088, "pan.___", state 871, "else"
+       line 1113, "pan.___", state 875, "_proc_urcu_writer = (_proc_urcu_writer&~(((1<<12)|(1<<11))))"
+       line 250, "pan.___", state 906, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 915, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 930, "(1)"
+       line 262, "pan.___", state 937, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 953, "(1)"
+       line 231, "pan.___", state 961, "(1)"
+       line 235, "pan.___", state 973, "(1)"
+       line 239, "pan.___", state 981, "(1)"
+       line 250, "pan.___", state 1012, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1021, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1034, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1043, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1059, "(1)"
+       line 231, "pan.___", state 1067, "(1)"
+       line 235, "pan.___", state 1079, "(1)"
+       line 239, "pan.___", state 1087, "(1)"
+       line 254, "pan.___", state 1113, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1126, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1135, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1151, "(1)"
+       line 231, "pan.___", state 1159, "(1)"
+       line 235, "pan.___", state 1171, "(1)"
+       line 239, "pan.___", state 1179, "(1)"
+       line 250, "pan.___", state 1210, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1219, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1232, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1241, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1257, "(1)"
+       line 231, "pan.___", state 1265, "(1)"
+       line 235, "pan.___", state 1277, "(1)"
+       line 239, "pan.___", state 1285, "(1)"
+       line 250, "pan.___", state 1302, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 250, "pan.___", state 1304, "(1)"
+       line 254, "pan.___", state 1311, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1313, "(1)"
+       line 254, "pan.___", state 1314, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 254, "pan.___", state 1314, "else"
+       line 252, "pan.___", state 1319, "((i<1))"
+       line 252, "pan.___", state 1319, "((i>=1))"
+       line 258, "pan.___", state 1324, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1326, "(1)"
+       line 258, "pan.___", state 1327, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 1327, "else"
+       line 262, "pan.___", state 1333, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1335, "(1)"
+       line 262, "pan.___", state 1336, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 262, "pan.___", state 1336, "else"
+       line 260, "pan.___", state 1341, "((i<2))"
+       line 260, "pan.___", state 1341, "((i>=2))"
+       line 227, "pan.___", state 1349, "(1)"
+       line 231, "pan.___", state 1357, "(1)"
+       line 231, "pan.___", state 1358, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 1358, "else"
+       line 229, "pan.___", state 1363, "((i<1))"
+       line 229, "pan.___", state 1363, "((i>=1))"
+       line 235, "pan.___", state 1369, "(1)"
+       line 235, "pan.___", state 1370, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 1370, "else"
+       line 239, "pan.___", state 1377, "(1)"
+       line 239, "pan.___", state 1378, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 1378, "else"
+       line 244, "pan.___", state 1387, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 1387, "else"
+       line 1183, "pan.___", state 1390, "i = 0"
+       line 1183, "pan.___", state 1392, "reader_barrier = 1"
+       line 1183, "pan.___", state 1403, "((i<1))"
+       line 1183, "pan.___", state 1403, "((i>=1))"
+       line 250, "pan.___", state 1408, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 250, "pan.___", state 1410, "(1)"
+       line 254, "pan.___", state 1417, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1419, "(1)"
+       line 254, "pan.___", state 1420, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 254, "pan.___", state 1420, "else"
+       line 252, "pan.___", state 1425, "((i<1))"
+       line 252, "pan.___", state 1425, "((i>=1))"
+       line 258, "pan.___", state 1430, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1432, "(1)"
+       line 258, "pan.___", state 1433, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 1433, "else"
+       line 262, "pan.___", state 1439, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1441, "(1)"
+       line 262, "pan.___", state 1442, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 262, "pan.___", state 1442, "else"
+       line 260, "pan.___", state 1447, "((i<2))"
+       line 260, "pan.___", state 1447, "((i>=2))"
+       line 227, "pan.___", state 1455, "(1)"
+       line 231, "pan.___", state 1463, "(1)"
+       line 231, "pan.___", state 1464, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 1464, "else"
+       line 229, "pan.___", state 1469, "((i<1))"
+       line 229, "pan.___", state 1469, "((i>=1))"
+       line 235, "pan.___", state 1475, "(1)"
+       line 235, "pan.___", state 1476, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 1476, "else"
+       line 239, "pan.___", state 1483, "(1)"
+       line 239, "pan.___", state 1484, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 1484, "else"
+       line 244, "pan.___", state 1493, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 1493, "else"
+       line 277, "pan.___", state 1495, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 277, "pan.___", state 1495, "else"
+       line 1183, "pan.___", state 1496, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 1183, "pan.___", state 1496, "else"
+       line 254, "pan.___", state 1509, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1522, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1531, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1547, "(1)"
+       line 231, "pan.___", state 1555, "(1)"
+       line 235, "pan.___", state 1567, "(1)"
+       line 239, "pan.___", state 1575, "(1)"
+       line 250, "pan.___", state 1606, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1615, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1628, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1637, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1653, "(1)"
+       line 231, "pan.___", state 1661, "(1)"
+       line 235, "pan.___", state 1673, "(1)"
+       line 239, "pan.___", state 1681, "(1)"
+       line 1191, "pan.___", state 1697, "-end-"
+       (242 of 1697 states)
+unreached in proctype :init:
+       line 1202, "pan.___", state 9, "((j<2))"
+       line 1202, "pan.___", state 9, "((j>=2))"
+       line 1203, "pan.___", state 20, "((j<2))"
+       line 1203, "pan.___", state 20, "((j>=2))"
+       line 1208, "pan.___", state 33, "((j<2))"
+       line 1208, "pan.___", state 33, "((j>=2))"
+       line 1206, "pan.___", state 43, "((i<1))"
+       line 1206, "pan.___", state 43, "((i>=1))"
+       line 1216, "pan.___", state 54, "((j<2))"
+       line 1216, "pan.___", state 54, "((j>=2))"
+       line 1220, "pan.___", state 67, "((j<2))"
+       line 1220, "pan.___", state 67, "((j>=2))"
+       (6 of 78 states)
+unreached in proctype :never:
+       line 1250, "pan.___", state 8, "-end-"
+       (1 of 8 states)
+
+pan: elapsed time 7.32e+03 seconds
+pan: rate 3363.2894 states/second
+pan: avg transition delay 1.288e-06 usec
+cp .input.spin urcu_free_single_flip.spin.input
+cp .input.spin.trail urcu_free_single_flip.spin.input.trail
+make[1]: Leaving directory `/home/compudj/doc/userspace-rcu/formal-model/urcu-controldataflow'
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_single_flip.spin.input b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_single_flip.spin.input
new file mode 100644 (file)
index 0000000..4877d95
--- /dev/null
@@ -0,0 +1,1227 @@
+#define SINGLE_FLIP
+
+// Poison value for freed memory
+#define POISON 1
+// Memory with correct data
+#define WINE 0
+#define SLAB_SIZE 2
+
+#define read_poison    (data_read_first[0] == POISON || data_read_second[0] == POISON)
+
+#define RCU_GP_CTR_BIT (1 << 7)
+#define RCU_GP_CTR_NEST_MASK (RCU_GP_CTR_BIT - 1)
+
+//disabled
+#define REMOTE_BARRIERS
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+typedef per_proc_bit {
+       bit val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bitfield {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bitfield cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               smp_mb(i, j);
+               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
+               break;
+       od;
+}
+
+#ifdef WRITER_PROGRESS
+//#define PROGRESS_LABEL(progressid)   progress_writer_progid_##progressid:
+#define PROGRESS_LABEL(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;                                          \
+               /*                                                              \
+                * 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)                                                     \
+               do                                                              \
+               :: (reader_barrier[i] == 1) -> skip;                            \
+               :: (reader_barrier[i] == 0) -> break;                           \
+               od;                                                             \
+               i++;                                                            \
+       :: i >= NR_READERS ->                                                   \
+               break                                                           \
+       od;                                                                     \
+       smp_mb(i, j);                                                           \
+}
+
+#else
+
+#define smp_mb_send(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, smp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only one reader */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* RCU data */
+DECLARE_CACHED_VAR(bit, rcu_data[SLAB_SIZE]);
+
+/* RCU pointer */
+#if (SLAB_SIZE == 2)
+DECLARE_CACHED_VAR(bit, rcu_ptr);
+bit ptr_read_first[NR_READERS];
+bit ptr_read_second[NR_READERS];
+#else
+DECLARE_CACHED_VAR(byte, rcu_ptr);
+byte ptr_read_first[NR_READERS];
+byte ptr_read_second[NR_READERS];
+#endif
+
+bit data_read_first[NR_READERS];
+bit data_read_second[NR_READERS];
+
+bit init_done = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               :: 1 -> skip;
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               ptr_read_first[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb1;
+rmb1_end:
+                               data_read_first[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_first[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               ptr_read_second[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb2;
+rmb2_end:
+                               data_read_second[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_second[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+rmb1:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb1_end;
+rmb2:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_DATA                     (1 << 1)
+#define WRITE_PROC_WMB                 (1 << 2)
+#define WRITE_XCHG_PTR                 (1 << 3)
+
+#define WRITE_PROC_FIRST_MB            (1 << 4)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 5)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 6)
+#define WRITE_PROC_FIRST_WAIT          (1 << 7)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 8)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 9)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 10)
+#define WRITE_PROC_SECOND_WAIT         (1 << 11)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 12)
+
+#define WRITE_PROC_SECOND_MB           (1 << 13)
+
+#define WRITE_FREE                     (1 << 14)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_DATA                    \
+                                       | WRITE_PROC_WMB                \
+                                       | WRITE_XCHG_PTR                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB          \
+                                       | WRITE_FREE)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 15) - 1)
+
+/*
+ * Mutexes are implied around writer execution. A single writer at a time.
+ */
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte cur_data = 0, old_data, loop_nr = 0;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (loop_nr < 3) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               loop_nr = loop_nr + 1;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_WMB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+#endif
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_DATA) ->
+                       ooo_mem(i);
+                       cur_data = (cur_data + 1) % SLAB_SIZE;
+                       WRITE_CACHED_VAR(rcu_data[cur_data], WINE);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_DATA);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA,
+                                 WRITE_PROC_WMB) ->
+                       smp_wmb(i, j);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_WMB,
+                                 WRITE_XCHG_PTR) ->
+                       /* rcu_xchg_pointer() */
+                       atomic {
+                               old_data = READ_CACHED_VAR(rcu_ptr);
+                               WRITE_CACHED_VAR(rcu_ptr, cur_data);
+                       }
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_XCHG_PTR);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_WMB      /* No dependency on
+                                                        * WRITE_DATA because we
+                                                        * write to a
+                                                        * different location. */
+                                 | WRITE_PROC_SECOND_MB
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_FREE) ->
+                       WRITE_CACHED_VAR(rcu_data[old_data], POISON);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_FREE);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+               /*
+                * Note : Promela model adds implicit serialization of the
+                * WRITE_FREE instruction. Normally, it would be permitted to
+                * spill on the next loop execution. Given the validation we do
+                * checks for the data entry read to be poisoned, it's ok if
+                * we do not check "late arriving" memory poisoning.
+                */
+       :: 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
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(rcu_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       ptr_read_first[i] = 1;
+                       ptr_read_second[i] = 1;
+                       data_read_first[i] = WINE;
+                       data_read_second[i] = WINE;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               INIT_CACHED_VAR(rcu_data[0], WINE, j);
+               i = 1;
+               do
+               :: i < SLAB_SIZE ->
+                       INIT_CACHED_VAR(rcu_data[i], POISON, j);
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_single_flip.spin.input.trail b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_free_single_flip.spin.input.trail
new file mode 100644 (file)
index 0000000..eaf1780
--- /dev/null
@@ -0,0 +1,1368 @@
+-2:3:-2
+-4:-4:-4
+1:0:4647
+2:3:4567
+3:3:4570
+4:3:4570
+5:3:4573
+6:3:4581
+7:3:4581
+8:3:4584
+9:3:4590
+10:3:4594
+11:3:4594
+12:3:4597
+13:3:4607
+14:3:4615
+15:3:4615
+16:3:4618
+17:3:4624
+18:3:4628
+19:3:4628
+20:3:4631
+21:3:4637
+22:3:4641
+23:3:4642
+24:0:4647
+25:3:4644
+26:0:4647
+27:2:2872
+28:0:4647
+29:2:2878
+30:0:4647
+31:2:2879
+32:0:4647
+33:2:2881
+34:0:4647
+35:2:2882
+36:0:4647
+37:2:2883
+38:0:4647
+39:2:2884
+40:0:4647
+41:2:2885
+42:0:4647
+43:2:2886
+44:0:4647
+45:2:2887
+46:2:2888
+47:2:2892
+48:2:2893
+49:2:2901
+50:2:2902
+51:2:2906
+52:2:2907
+53:2:2915
+54:2:2920
+55:2:2924
+56:2:2925
+57:2:2933
+58:2:2934
+59:2:2938
+60:2:2939
+61:2:2933
+62:2:2934
+63:2:2938
+64:2:2939
+65:2:2947
+66:2:2952
+67:2:2953
+68:2:2964
+69:2:2965
+70:2:2966
+71:2:2977
+72:2:2982
+73:2:2983
+74:2:2994
+75:2:2995
+76:2:2996
+77:2:2994
+78:2:2995
+79:2:2996
+80:2:3007
+81:2:3015
+82:0:4647
+83:2:2886
+84:0:4647
+85:2:3019
+86:2:3023
+87:2:3024
+88:2:3028
+89:2:3032
+90:2:3033
+91:2:3037
+92:2:3045
+93:2:3046
+94:2:3050
+95:2:3054
+96:2:3055
+97:2:3050
+98:2:3051
+99:2:3059
+100:0:4647
+101:2:2886
+102:0:4647
+103:2:3067
+104:2:3068
+105:2:3069
+106:0:4647
+107:2:2886
+108:0:4647
+109:2:3074
+110:0:4647
+111:2:3776
+112:2:3777
+113:2:3781
+114:2:3785
+115:2:3786
+116:2:3790
+117:2:3795
+118:2:3803
+119:2:3807
+120:2:3808
+121:2:3803
+122:2:3807
+123:2:3808
+124:2:3812
+125:2:3819
+126:2:3826
+127:2:3827
+128:2:3834
+129:2:3839
+130:2:3846
+131:2:3847
+132:2:3846
+133:2:3847
+134:2:3854
+135:2:3858
+136:0:4647
+137:2:3863
+138:0:4647
+139:2:3864
+140:0:4647
+141:2:3865
+142:0:4647
+143:2:3866
+144:0:4647
+145:1:2
+146:0:4647
+147:2:3867
+148:0:4647
+149:1:8
+150:0:4647
+151:1:9
+152:0:4647
+153:2:3866
+154:0:4647
+155:1:10
+156:0:4647
+157:2:3867
+158:0:4647
+159:1:11
+160:0:4647
+161:2:3866
+162:0:4647
+163:1:12
+164:0:4647
+165:2:3867
+166:0:4647
+167:1:13
+168:0:4647
+169:2:3866
+170:0:4647
+171:1:14
+172:0:4647
+173:2:3867
+174:0:4647
+175:1:15
+176:0:4647
+177:1:16
+178:0:4647
+179:2:3866
+180:0:4647
+181:1:17
+182:0:4647
+183:2:3867
+184:0:4647
+185:1:28
+186:0:4647
+187:2:3866
+188:0:4647
+189:1:32
+190:1:33
+191:1:37
+192:1:41
+193:1:42
+194:1:46
+195:1:54
+196:1:55
+197:1:59
+198:1:63
+199:1:64
+200:1:59
+201:1:63
+202:1:64
+203:1:68
+204:1:75
+205:1:82
+206:1:83
+207:1:90
+208:1:95
+209:1:102
+210:1:103
+211:1:102
+212:1:103
+213:1:110
+214:1:114
+215:0:4647
+216:2:3867
+217:0:4647
+218:1:119
+219:0:4647
+220:2:3868
+221:0:4647
+222:2:3873
+223:0:4647
+224:2:3874
+225:0:4647
+226:2:3882
+227:2:3883
+228:2:3887
+229:2:3891
+230:2:3892
+231:2:3896
+232:2:3904
+233:2:3905
+234:2:3909
+235:2:3913
+236:2:3914
+237:2:3909
+238:2:3913
+239:2:3914
+240:2:3918
+241:2:3925
+242:2:3932
+243:2:3933
+244:2:3940
+245:2:3945
+246:2:3952
+247:2:3953
+248:2:3952
+249:2:3953
+250:2:3960
+251:2:3964
+252:0:4647
+253:2:3076
+254:2:3757
+255:0:4647
+256:2:2886
+257:0:4647
+258:2:3077
+259:0:4647
+260:2:2886
+261:0:4647
+262:2:3080
+263:2:3081
+264:2:3085
+265:2:3086
+266:2:3094
+267:2:3095
+268:2:3099
+269:2:3100
+270:2:3108
+271:2:3113
+272:2:3117
+273:2:3118
+274:2:3126
+275:2:3127
+276:2:3131
+277:2:3132
+278:2:3126
+279:2:3127
+280:2:3131
+281:2:3132
+282:2:3140
+283:2:3145
+284:2:3146
+285:2:3157
+286:2:3158
+287:2:3159
+288:2:3170
+289:2:3175
+290:2:3176
+291:2:3187
+292:2:3188
+293:2:3189
+294:2:3187
+295:2:3188
+296:2:3189
+297:2:3200
+298:2:3207
+299:0:4647
+300:2:2886
+301:0:4647
+302:2:3211
+303:2:3212
+304:2:3213
+305:2:3225
+306:2:3226
+307:2:3230
+308:2:3231
+309:2:3239
+310:2:3244
+311:2:3248
+312:2:3249
+313:2:3257
+314:2:3258
+315:2:3262
+316:2:3263
+317:2:3257
+318:2:3258
+319:2:3262
+320:2:3263
+321:2:3271
+322:2:3276
+323:2:3277
+324:2:3288
+325:2:3289
+326:2:3290
+327:2:3301
+328:2:3306
+329:2:3307
+330:2:3318
+331:2:3319
+332:2:3320
+333:2:3318
+334:2:3319
+335:2:3320
+336:2:3331
+337:2:3341
+338:2:3342
+339:0:4647
+340:2:2886
+341:0:4647
+342:2:3745
+343:0:4647
+344:2:4370
+345:2:4371
+346:2:4375
+347:2:4379
+348:2:4380
+349:2:4384
+350:2:4392
+351:2:4393
+352:2:4397
+353:2:4401
+354:2:4402
+355:2:4397
+356:2:4401
+357:2:4402
+358:2:4406
+359:2:4413
+360:2:4420
+361:2:4421
+362:2:4428
+363:2:4433
+364:2:4440
+365:2:4441
+366:2:4440
+367:2:4441
+368:2:4448
+369:2:4452
+370:0:4647
+371:2:4457
+372:0:4647
+373:2:4458
+374:0:4647
+375:2:4459
+376:0:4647
+377:2:4460
+378:0:4647
+379:1:120
+380:0:4647
+381:2:4461
+382:0:4647
+383:1:19
+384:0:4647
+385:2:4460
+386:0:4647
+387:1:127
+388:1:128
+389:1:132
+390:1:133
+391:1:141
+392:1:142
+393:1:146
+394:1:147
+395:1:155
+396:1:160
+397:1:164
+398:1:165
+399:1:173
+400:1:174
+401:1:178
+402:1:179
+403:1:173
+404:1:174
+405:1:178
+406:1:179
+407:1:187
+408:1:199
+409:1:200
+410:1:204
+411:1:205
+412:1:206
+413:1:217
+414:1:222
+415:1:223
+416:1:234
+417:1:235
+418:1:236
+419:1:234
+420:1:235
+421:1:236
+422:1:247
+423:0:4647
+424:2:4461
+425:0:4647
+426:1:15
+427:0:4647
+428:1:16
+429:0:4647
+430:2:4460
+431:0:4647
+432:1:17
+433:0:4647
+434:2:4461
+435:0:4647
+436:1:120
+437:0:4647
+438:2:4460
+439:0:4647
+440:1:19
+441:0:4647
+442:2:4461
+443:0:4647
+444:1:256
+445:1:257
+446:0:4647
+447:1:15
+448:0:4647
+449:1:16
+450:0:4647
+451:2:4460
+452:0:4647
+453:1:17
+454:0:4647
+455:2:4461
+456:0:4647
+457:1:120
+458:0:4647
+459:2:4460
+460:0:4647
+461:1:19
+462:0:4647
+463:2:4461
+464:0:4647
+465:1:263
+466:1:264
+467:1:268
+468:1:269
+469:1:277
+470:1:278
+471:1:282
+472:1:283
+473:1:291
+474:1:296
+475:1:300
+476:1:301
+477:1:309
+478:1:310
+479:1:314
+480:1:315
+481:1:309
+482:1:310
+483:1:314
+484:1:315
+485:1:323
+486:1:335
+487:1:336
+488:1:340
+489:1:341
+490:1:342
+491:1:353
+492:1:358
+493:1:359
+494:1:370
+495:1:371
+496:1:372
+497:1:370
+498:1:371
+499:1:372
+500:1:383
+501:0:4647
+502:1:15
+503:0:4647
+504:1:16
+505:0:4647
+506:2:4460
+507:0:4647
+508:1:17
+509:0:4647
+510:2:4461
+511:0:4647
+512:1:28
+513:0:4647
+514:2:4460
+515:0:4647
+516:1:32
+517:1:33
+518:1:37
+519:1:41
+520:1:42
+521:1:46
+522:1:54
+523:1:55
+524:1:59
+525:1:63
+526:1:64
+527:1:59
+528:1:63
+529:1:64
+530:1:68
+531:1:75
+532:1:82
+533:1:83
+534:1:90
+535:1:95
+536:1:102
+537:1:103
+538:1:102
+539:1:103
+540:1:110
+541:1:114
+542:0:4647
+543:2:4461
+544:0:4647
+545:1:119
+546:0:4647
+547:2:4462
+548:0:4647
+549:2:4467
+550:0:4647
+551:2:4468
+552:0:4647
+553:2:4476
+554:2:4477
+555:2:4481
+556:2:4485
+557:2:4486
+558:2:4490
+559:2:4498
+560:2:4499
+561:2:4503
+562:2:4507
+563:2:4508
+564:2:4503
+565:2:4507
+566:2:4508
+567:2:4512
+568:2:4519
+569:2:4526
+570:2:4527
+571:2:4534
+572:2:4539
+573:2:4546
+574:2:4547
+575:2:4546
+576:2:4547
+577:2:4554
+578:2:4558
+579:0:4647
+580:2:3747
+581:2:3757
+582:0:4647
+583:2:2886
+584:0:4647
+585:2:3748
+586:2:3749
+587:0:4647
+588:2:2886
+589:0:4647
+590:2:3753
+591:0:4647
+592:2:3761
+593:0:4647
+594:2:2879
+595:0:4647
+596:2:2881
+597:0:4647
+598:2:2882
+599:0:4647
+600:2:2883
+601:0:4647
+602:2:2884
+603:0:4647
+604:2:2885
+605:0:4647
+606:2:2886
+607:0:4647
+608:2:2887
+609:2:2888
+610:2:2892
+611:2:2893
+612:2:2901
+613:2:2902
+614:2:2906
+615:2:2907
+616:2:2915
+617:2:2920
+618:2:2924
+619:2:2925
+620:2:2933
+621:2:2934
+622:2:2935
+623:2:2933
+624:2:2934
+625:2:2938
+626:2:2939
+627:2:2947
+628:2:2952
+629:2:2953
+630:2:2964
+631:2:2965
+632:2:2966
+633:2:2977
+634:2:2982
+635:2:2983
+636:2:2994
+637:2:2995
+638:2:2996
+639:2:2994
+640:2:2995
+641:2:2996
+642:2:3007
+643:2:3015
+644:0:4647
+645:2:2886
+646:0:4647
+647:2:3019
+648:2:3023
+649:2:3024
+650:2:3028
+651:2:3032
+652:2:3033
+653:2:3037
+654:2:3045
+655:2:3046
+656:2:3050
+657:2:3051
+658:2:3050
+659:2:3054
+660:2:3055
+661:2:3059
+662:0:4647
+663:2:2886
+664:0:4647
+665:2:3067
+666:2:3068
+667:2:3069
+668:0:4647
+669:2:2886
+670:0:4647
+671:2:3074
+672:0:4647
+673:2:3776
+674:2:3777
+675:2:3781
+676:2:3785
+677:2:3786
+678:2:3790
+679:2:3795
+680:2:3803
+681:2:3807
+682:2:3808
+683:2:3803
+684:2:3807
+685:2:3808
+686:2:3812
+687:2:3819
+688:2:3826
+689:2:3827
+690:2:3834
+691:2:3839
+692:2:3846
+693:2:3847
+694:2:3846
+695:2:3847
+696:2:3854
+697:2:3858
+698:0:4647
+699:2:3863
+700:0:4647
+701:2:3864
+702:0:4647
+703:2:3865
+704:0:4647
+705:2:3866
+706:0:4647
+707:1:120
+708:0:4647
+709:2:3867
+710:0:4647
+711:1:19
+712:0:4647
+713:2:3866
+714:0:4647
+715:1:392
+716:1:393
+717:1:397
+718:1:398
+719:1:406
+720:1:407
+721:1:411
+722:1:412
+723:1:420
+724:1:425
+725:1:429
+726:1:430
+727:1:438
+728:1:439
+729:1:443
+730:1:444
+731:1:438
+732:1:439
+733:1:443
+734:1:444
+735:1:452
+736:1:457
+737:1:458
+738:1:469
+739:1:470
+740:1:471
+741:1:482
+742:1:494
+743:1:495
+744:1:499
+745:1:500
+746:1:501
+747:1:499
+748:1:500
+749:1:501
+750:1:512
+751:1:519
+752:0:4647
+753:2:3867
+754:0:4647
+755:1:15
+756:0:4647
+757:1:16
+758:0:4647
+759:2:3866
+760:0:4647
+761:1:17
+762:0:4647
+763:2:3867
+764:0:4647
+765:1:120
+766:0:4647
+767:2:3866
+768:0:4647
+769:1:19
+770:0:4647
+771:2:3867
+772:0:4647
+773:1:657
+774:1:658
+775:1:662
+776:1:663
+777:1:671
+778:1:672
+779:1:673
+780:1:685
+781:1:690
+782:1:694
+783:1:695
+784:1:703
+785:1:704
+786:1:708
+787:1:709
+788:1:703
+789:1:704
+790:1:708
+791:1:709
+792:1:717
+793:1:722
+794:1:723
+795:1:734
+796:1:735
+797:1:736
+798:1:747
+799:1:759
+800:1:760
+801:1:764
+802:1:765
+803:1:766
+804:1:764
+805:1:765
+806:1:766
+807:1:777
+808:0:4647
+809:1:15
+810:0:4647
+811:1:16
+812:0:4647
+813:2:3866
+814:0:4647
+815:1:17
+816:0:4647
+817:2:3867
+818:0:4647
+819:1:120
+820:0:4647
+821:2:3866
+822:0:4647
+823:1:19
+824:0:4647
+825:2:3867
+826:0:4647
+827:1:786
+828:1:789
+829:1:790
+830:0:4647
+831:1:15
+832:0:4647
+833:1:16
+834:0:4647
+835:2:3866
+836:0:4647
+837:1:17
+838:0:4647
+839:2:3867
+840:0:4647
+841:1:120
+842:0:4647
+843:2:3866
+844:0:4647
+845:1:19
+846:0:4647
+847:2:3867
+848:0:4647
+849:1:1053
+850:1:1054
+851:1:1058
+852:1:1059
+853:1:1067
+854:1:1068
+855:1:1072
+856:1:1073
+857:1:1081
+858:1:1086
+859:1:1090
+860:1:1091
+861:1:1099
+862:1:1100
+863:1:1104
+864:1:1105
+865:1:1099
+866:1:1100
+867:1:1104
+868:1:1105
+869:1:1113
+870:1:1118
+871:1:1119
+872:1:1130
+873:1:1131
+874:1:1132
+875:1:1143
+876:1:1155
+877:1:1156
+878:1:1160
+879:1:1161
+880:1:1162
+881:1:1160
+882:1:1161
+883:1:1162
+884:1:1173
+885:1:1180
+886:1:1184
+887:0:4647
+888:1:15
+889:0:4647
+890:1:16
+891:0:4647
+892:2:3866
+893:0:4647
+894:1:17
+895:0:4647
+896:2:3867
+897:0:4647
+898:1:120
+899:0:4647
+900:2:3866
+901:0:4647
+902:1:19
+903:0:4647
+904:2:3867
+905:0:4647
+906:1:1185
+907:1:1186
+908:1:1190
+909:1:1191
+910:1:1199
+911:1:1200
+912:1:1201
+913:1:1213
+914:1:1218
+915:1:1222
+916:1:1223
+917:1:1231
+918:1:1232
+919:1:1236
+920:1:1237
+921:1:1231
+922:1:1232
+923:1:1236
+924:1:1237
+925:1:1245
+926:1:1250
+927:1:1251
+928:1:1262
+929:1:1263
+930:1:1264
+931:1:1275
+932:1:1287
+933:1:1288
+934:1:1292
+935:1:1293
+936:1:1294
+937:1:1292
+938:1:1293
+939:1:1294
+940:1:1305
+941:0:4647
+942:1:15
+943:0:4647
+944:1:16
+945:0:4647
+946:2:3866
+947:0:4647
+948:1:17
+949:0:4647
+950:2:3867
+951:0:4647
+952:1:28
+953:0:4647
+954:2:3866
+955:0:4647
+956:1:32
+957:1:33
+958:1:37
+959:1:41
+960:1:42
+961:1:46
+962:1:54
+963:1:55
+964:1:59
+965:1:63
+966:1:64
+967:1:59
+968:1:63
+969:1:64
+970:1:68
+971:1:75
+972:1:82
+973:1:83
+974:1:90
+975:1:95
+976:1:102
+977:1:103
+978:1:102
+979:1:103
+980:1:110
+981:1:114
+982:0:4647
+983:2:3867
+984:0:4647
+985:1:119
+986:0:4647
+987:2:3868
+988:0:4647
+989:2:3873
+990:0:4647
+991:2:3874
+992:0:4647
+993:2:3882
+994:2:3883
+995:2:3887
+996:2:3891
+997:2:3892
+998:2:3896
+999:2:3904
+1000:2:3905
+1001:2:3909
+1002:2:3913
+1003:2:3914
+1004:2:3909
+1005:2:3913
+1006:2:3914
+1007:2:3918
+1008:2:3925
+1009:2:3932
+1010:2:3933
+1011:2:3940
+1012:2:3945
+1013:2:3952
+1014:2:3953
+1015:2:3952
+1016:2:3953
+1017:2:3960
+1018:2:3964
+1019:0:4647
+1020:2:3076
+1021:2:3757
+1022:0:4647
+1023:2:2886
+1024:0:4647
+1025:2:3077
+1026:0:4647
+1027:2:2886
+1028:0:4647
+1029:2:3080
+1030:2:3081
+1031:2:3085
+1032:2:3086
+1033:2:3094
+1034:2:3095
+1035:2:3099
+1036:2:3100
+1037:2:3108
+1038:2:3113
+1039:2:3117
+1040:2:3118
+1041:2:3126
+1042:2:3127
+1043:2:3131
+1044:2:3132
+1045:2:3126
+1046:2:3127
+1047:2:3131
+1048:2:3132
+1049:2:3140
+1050:2:3145
+1051:2:3146
+1052:2:3157
+1053:2:3158
+1054:2:3159
+1055:2:3170
+1056:2:3175
+1057:2:3176
+1058:2:3187
+1059:2:3188
+1060:2:3189
+1061:2:3187
+1062:2:3188
+1063:2:3189
+1064:2:3200
+1065:2:3207
+1066:0:4647
+1067:2:2886
+1068:0:4647
+1069:2:3211
+1070:2:3212
+1071:2:3213
+1072:2:3225
+1073:2:3226
+1074:2:3230
+1075:2:3231
+1076:2:3239
+1077:2:3244
+1078:2:3248
+1079:2:3249
+1080:2:3257
+1081:2:3258
+1082:2:3262
+1083:2:3263
+1084:2:3257
+1085:2:3258
+1086:2:3262
+1087:2:3263
+1088:2:3271
+1089:2:3276
+1090:2:3277
+1091:2:3288
+1092:2:3289
+1093:2:3290
+1094:2:3301
+1095:2:3306
+1096:2:3307
+1097:2:3318
+1098:2:3319
+1099:2:3320
+1100:2:3318
+1101:2:3319
+1102:2:3320
+1103:2:3331
+1104:2:3341
+1105:2:3342
+1106:0:4647
+1107:2:2886
+1108:0:4647
+1109:2:3745
+1110:0:4647
+1111:2:4370
+1112:2:4371
+1113:2:4375
+1114:2:4379
+1115:2:4380
+1116:2:4384
+1117:2:4392
+1118:2:4393
+1119:2:4397
+1120:2:4401
+1121:2:4402
+1122:2:4397
+1123:2:4401
+1124:2:4402
+1125:2:4406
+1126:2:4413
+1127:2:4420
+1128:2:4421
+1129:2:4428
+1130:2:4433
+1131:2:4440
+1132:2:4441
+1133:2:4440
+1134:2:4441
+1135:2:4448
+1136:2:4452
+1137:0:4647
+1138:2:4457
+1139:0:4647
+1140:2:4458
+1141:0:4647
+1142:2:4459
+1143:0:4647
+1144:2:4460
+1145:0:4647
+1146:1:28
+1147:0:4647
+1148:2:4461
+1149:0:4647
+1150:1:32
+1151:1:33
+1152:1:37
+1153:1:41
+1154:1:42
+1155:1:46
+1156:1:54
+1157:1:55
+1158:1:59
+1159:1:63
+1160:1:64
+1161:1:59
+1162:1:63
+1163:1:64
+1164:1:68
+1165:1:75
+1166:1:82
+1167:1:83
+1168:1:90
+1169:1:95
+1170:1:102
+1171:1:103
+1172:1:102
+1173:1:103
+1174:1:110
+1175:1:114
+1176:0:4647
+1177:2:4460
+1178:0:4647
+1179:1:119
+1180:0:4647
+1181:2:4461
+1182:0:4647
+1183:2:4462
+1184:0:4647
+1185:2:4467
+1186:0:4647
+1187:2:4468
+1188:0:4647
+1189:2:4476
+1190:2:4477
+1191:2:4481
+1192:2:4485
+1193:2:4486
+1194:2:4490
+1195:2:4498
+1196:2:4499
+1197:2:4503
+1198:2:4507
+1199:2:4508
+1200:2:4503
+1201:2:4507
+1202:2:4508
+1203:2:4512
+1204:2:4519
+1205:2:4526
+1206:2:4527
+1207:2:4534
+1208:2:4539
+1209:2:4546
+1210:2:4547
+1211:2:4546
+1212:2:4547
+1213:2:4554
+1214:2:4558
+1215:0:4647
+1216:2:3747
+1217:2:3757
+1218:0:4647
+1219:2:2886
+1220:0:4647
+1221:2:3748
+1222:2:3749
+1223:0:4647
+1224:2:2886
+1225:0:4647
+1226:2:3753
+1227:0:4647
+1228:2:3761
+1229:0:4647
+1230:2:2879
+1231:0:4647
+1232:2:2881
+1233:0:4647
+1234:2:2882
+1235:0:4647
+1236:2:2883
+1237:0:4647
+1238:2:2884
+1239:0:4647
+1240:2:2885
+1241:0:4647
+1242:2:2886
+1243:0:4647
+1244:2:2887
+1245:2:2888
+1246:2:2892
+1247:2:2893
+1248:2:2901
+1249:2:2902
+1250:2:2906
+1251:2:2907
+1252:2:2915
+1253:2:2920
+1254:2:2924
+1255:2:2925
+1256:2:2933
+1257:2:2934
+1258:2:2938
+1259:2:2939
+1260:2:2933
+1261:2:2934
+1262:2:2935
+1263:2:2947
+1264:2:2952
+1265:2:2953
+1266:2:2964
+1267:2:2965
+1268:2:2966
+1269:2:2977
+1270:2:2982
+1271:2:2983
+1272:2:2994
+1273:2:2995
+1274:2:2996
+1275:2:2994
+1276:2:2995
+1277:2:2996
+1278:2:3007
+1279:2:3015
+1280:0:4647
+1281:2:2886
+1282:0:4647
+1283:1:120
+1284:0:4647
+1285:1:19
+1286:0:4647
+1287:1:1314
+1288:0:4647
+1289:1:2778
+1290:1:2785
+1291:1:2786
+1292:1:2793
+1293:1:2798
+1294:1:2805
+1295:1:2806
+1296:1:2805
+1297:1:2806
+1298:1:2813
+1299:1:2817
+1300:0:4647
+1301:2:3019
+1302:2:3023
+1303:2:3024
+1304:2:3028
+1305:2:3032
+1306:2:3033
+1307:2:3037
+1308:2:3045
+1309:2:3046
+1310:2:3050
+1311:2:3054
+1312:2:3055
+1313:2:3050
+1314:2:3051
+1315:2:3059
+1316:0:4647
+1317:2:2886
+1318:0:4647
+1319:2:3067
+1320:2:3068
+1321:2:3069
+1322:0:4647
+1323:2:2886
+1324:0:4647
+1325:2:3074
+1326:0:4647
+1327:2:3776
+1328:2:3777
+1329:2:3781
+1330:2:3785
+1331:2:3786
+1332:2:3790
+1333:2:3795
+1334:2:3803
+1335:2:3807
+1336:2:3808
+1337:2:3803
+1338:2:3807
+1339:2:3808
+1340:2:3812
+1341:2:3819
+1342:2:3826
+1343:2:3827
+1344:2:3834
+1345:2:3839
+1346:2:3846
+1347:2:3847
+1348:2:3846
+1349:2:3847
+1350:2:3854
+1351:2:3858
+1352:0:4647
+1353:2:3863
+1354:0:4647
+1355:2:3864
+1356:0:4647
+1357:2:3865
+1358:0:4647
+1359:2:3866
+1360:0:4647
+1361:1:1316
+1362:1:1317
+1363:0:4645
+1364:2:3867
+1365:0:4651
+1366:0:4647
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress.ltl b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress.ltl
new file mode 100644 (file)
index 0000000..8718641
--- /dev/null
@@ -0,0 +1 @@
+([] <> !np_)
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_reader.define b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_reader.define
new file mode 100644 (file)
index 0000000..ff3f783
--- /dev/null
@@ -0,0 +1 @@
+#define READER_PROGRESS
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_reader.log b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_reader.log
new file mode 100644 (file)
index 0000000..c7614b5
--- /dev/null
@@ -0,0 +1,1513 @@
+make[1]: Entering directory `/home/compudj/doc/userspace-rcu/formal-model/urcu-controldataflow'
+rm -f pan* trail.out .input.spin* *.spin.trail .input.define
+touch .input.define
+cat .input.define > pan.ltl
+cat DEFINES >> pan.ltl
+spin -f "!(`cat urcu_progress.ltl | grep -v ^//`)" >> pan.ltl
+cp urcu_progress_reader.define .input.define
+cat .input.define > .input.spin
+cat DEFINES >> .input.spin
+cat urcu.spin >> .input.spin
+rm -f .input.spin.trail
+spin -a -X -N pan.ltl .input.spin
+Exit-Status 0
+gcc -O2 -w -DHASH64 -o pan pan.c
+./pan -a -f -v -c1 -X -m10000000 -w20
+warning: for p.o. reduction to be valid the never claim must be stutter-invariant
+(never claims generated from LTL formulae are stutter-invariant)
+depth 0: Claim reached state 5 (line 1245)
+depth 23: Claim reached state 9 (line 1250)
+depth 145: Claim reached state 9 (line 1249)
+pan: acceptance cycle (at depth 2922)
+pan: wrote .input.spin.trail
+
+(Spin Version 5.1.7 -- 23 December 2008)
+Warning: Search not completed
+       + Partial Order Reduction
+
+Full statespace search for:
+       never claim             +
+       assertion violations    + (if within scope of claim)
+       acceptance   cycles     + (fairness enabled)
+       invalid end states      - (disabled by never claim)
+
+State-vector 88 byte, depth reached 3023, errors: 1
+      604 states, stored (989 visited)
+    16933 states, matched
+    17922 transitions (= visited+matched)
+   100982 atomic steps
+hash conflicts:         1 (resolved)
+
+Stats on memory usage (in Megabytes):
+    0.067      equivalent memory usage for states (stored*(State-vector + overhead))
+    0.718      actual memory usage for states (unsuccessful compression: 1075.20%)
+               state-vector as stored = 1219 byte + 28 byte overhead
+    8.000      memory used for hash table (-w20)
+  457.764      memory used for DFS stack (-m10000000)
+  466.447      total actual memory usage
+
+unreached in proctype urcu_reader
+       line 250, "pan.___", state 32, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 41, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 252, "pan.___", state 49, "((i<1))"
+       line 252, "pan.___", state 49, "((i>=1))"
+       line 258, "pan.___", state 54, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 63, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 260, "pan.___", state 71, "((i<2))"
+       line 260, "pan.___", state 71, "((i>=2))"
+       line 227, "pan.___", state 79, "(1)"
+       line 231, "pan.___", state 87, "(1)"
+       line 231, "pan.___", state 88, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 88, "else"
+       line 229, "pan.___", state 93, "((i<1))"
+       line 229, "pan.___", state 93, "((i>=1))"
+       line 235, "pan.___", state 99, "(1)"
+       line 235, "pan.___", state 100, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 100, "else"
+       line 239, "pan.___", state 107, "(1)"
+       line 239, "pan.___", state 108, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 108, "else"
+       line 244, "pan.___", state 117, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 117, "else"
+       line 387, "pan.___", state 132, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 138, "(1)"
+       line 391, "pan.___", state 146, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 152, "(1)"
+       line 391, "pan.___", state 153, "(1)"
+       line 391, "pan.___", state 153, "(1)"
+       line 389, "pan.___", state 158, "((i<1))"
+       line 389, "pan.___", state 158, "((i>=1))"
+       line 396, "pan.___", state 164, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 170, "(1)"
+       line 396, "pan.___", state 171, "(1)"
+       line 396, "pan.___", state 171, "(1)"
+       line 400, "pan.___", state 178, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 184, "(1)"
+       line 400, "pan.___", state 185, "(1)"
+       line 400, "pan.___", state 185, "(1)"
+       line 398, "pan.___", state 190, "((i<2))"
+       line 398, "pan.___", state 190, "((i>=2))"
+       line 404, "pan.___", state 197, "(1)"
+       line 404, "pan.___", state 198, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 198, "else"
+       line 404, "pan.___", state 201, "(1)"
+       line 404, "pan.___", state 202, "(1)"
+       line 404, "pan.___", state 202, "(1)"
+       line 408, "pan.___", state 210, "(1)"
+       line 408, "pan.___", state 211, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 211, "else"
+       line 408, "pan.___", state 214, "(1)"
+       line 408, "pan.___", state 215, "(1)"
+       line 408, "pan.___", state 215, "(1)"
+       line 406, "pan.___", state 220, "((i<1))"
+       line 406, "pan.___", state 220, "((i>=1))"
+       line 413, "pan.___", state 227, "(1)"
+       line 413, "pan.___", state 228, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 228, "else"
+       line 413, "pan.___", state 231, "(1)"
+       line 413, "pan.___", state 232, "(1)"
+       line 413, "pan.___", state 232, "(1)"
+       line 417, "pan.___", state 240, "(1)"
+       line 417, "pan.___", state 241, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 241, "else"
+       line 417, "pan.___", state 244, "(1)"
+       line 417, "pan.___", state 245, "(1)"
+       line 417, "pan.___", state 245, "(1)"
+       line 422, "pan.___", state 254, "(1)"
+       line 422, "pan.___", state 254, "(1)"
+       line 663, "pan.___", state 261, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<1))"
+       line 663, "pan.___", state 262, "(!((tmp&((1<<7)-1))))"
+       line 663, "pan.___", state 262, "else"
+       line 387, "pan.___", state 268, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 274, "(1)"
+       line 391, "pan.___", state 282, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 288, "(1)"
+       line 391, "pan.___", state 289, "(1)"
+       line 391, "pan.___", state 289, "(1)"
+       line 389, "pan.___", state 294, "((i<1))"
+       line 389, "pan.___", state 294, "((i>=1))"
+       line 396, "pan.___", state 300, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 306, "(1)"
+       line 396, "pan.___", state 307, "(1)"
+       line 396, "pan.___", state 307, "(1)"
+       line 400, "pan.___", state 314, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 320, "(1)"
+       line 400, "pan.___", state 321, "(1)"
+       line 400, "pan.___", state 321, "(1)"
+       line 398, "pan.___", state 326, "((i<2))"
+       line 398, "pan.___", state 326, "((i>=2))"
+       line 404, "pan.___", state 333, "(1)"
+       line 404, "pan.___", state 334, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 334, "else"
+       line 404, "pan.___", state 337, "(1)"
+       line 404, "pan.___", state 338, "(1)"
+       line 404, "pan.___", state 338, "(1)"
+       line 408, "pan.___", state 346, "(1)"
+       line 408, "pan.___", state 347, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 347, "else"
+       line 408, "pan.___", state 350, "(1)"
+       line 408, "pan.___", state 351, "(1)"
+       line 408, "pan.___", state 351, "(1)"
+       line 406, "pan.___", state 356, "((i<1))"
+       line 406, "pan.___", state 356, "((i>=1))"
+       line 413, "pan.___", state 363, "(1)"
+       line 413, "pan.___", state 364, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 364, "else"
+       line 413, "pan.___", state 367, "(1)"
+       line 413, "pan.___", state 368, "(1)"
+       line 413, "pan.___", state 368, "(1)"
+       line 417, "pan.___", state 376, "(1)"
+       line 417, "pan.___", state 377, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 377, "else"
+       line 417, "pan.___", state 380, "(1)"
+       line 417, "pan.___", state 381, "(1)"
+       line 417, "pan.___", state 381, "(1)"
+       line 422, "pan.___", state 390, "(1)"
+       line 422, "pan.___", state 390, "(1)"
+       line 387, "pan.___", state 397, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 403, "(1)"
+       line 391, "pan.___", state 411, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 417, "(1)"
+       line 391, "pan.___", state 418, "(1)"
+       line 391, "pan.___", state 418, "(1)"
+       line 389, "pan.___", state 423, "((i<1))"
+       line 389, "pan.___", state 423, "((i>=1))"
+       line 396, "pan.___", state 429, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 435, "(1)"
+       line 396, "pan.___", state 436, "(1)"
+       line 396, "pan.___", state 436, "(1)"
+       line 400, "pan.___", state 443, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 449, "(1)"
+       line 400, "pan.___", state 450, "(1)"
+       line 400, "pan.___", state 450, "(1)"
+       line 398, "pan.___", state 455, "((i<2))"
+       line 398, "pan.___", state 455, "((i>=2))"
+       line 404, "pan.___", state 462, "(1)"
+       line 404, "pan.___", state 463, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 463, "else"
+       line 404, "pan.___", state 466, "(1)"
+       line 404, "pan.___", state 467, "(1)"
+       line 404, "pan.___", state 467, "(1)"
+       line 408, "pan.___", state 475, "(1)"
+       line 408, "pan.___", state 476, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 476, "else"
+       line 408, "pan.___", state 479, "(1)"
+       line 408, "pan.___", state 480, "(1)"
+       line 408, "pan.___", state 480, "(1)"
+       line 406, "pan.___", state 485, "((i<1))"
+       line 406, "pan.___", state 485, "((i>=1))"
+       line 413, "pan.___", state 492, "(1)"
+       line 413, "pan.___", state 493, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 493, "else"
+       line 413, "pan.___", state 496, "(1)"
+       line 413, "pan.___", state 497, "(1)"
+       line 413, "pan.___", state 497, "(1)"
+       line 417, "pan.___", state 505, "(1)"
+       line 417, "pan.___", state 506, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 506, "else"
+       line 417, "pan.___", state 509, "(1)"
+       line 417, "pan.___", state 510, "(1)"
+       line 417, "pan.___", state 510, "(1)"
+       line 415, "pan.___", state 515, "((i<2))"
+       line 415, "pan.___", state 515, "((i>=2))"
+       line 422, "pan.___", state 519, "(1)"
+       line 422, "pan.___", state 519, "(1)"
+       line 387, "pan.___", state 528, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 530, "(1)"
+       line 387, "pan.___", state 531, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 387, "pan.___", state 531, "else"
+       line 387, "pan.___", state 534, "(1)"
+       line 391, "pan.___", state 542, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 544, "(1)"
+       line 391, "pan.___", state 545, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 391, "pan.___", state 545, "else"
+       line 391, "pan.___", state 548, "(1)"
+       line 391, "pan.___", state 549, "(1)"
+       line 391, "pan.___", state 549, "(1)"
+       line 389, "pan.___", state 554, "((i<1))"
+       line 389, "pan.___", state 554, "((i>=1))"
+       line 396, "pan.___", state 560, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 562, "(1)"
+       line 396, "pan.___", state 563, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 563, "else"
+       line 396, "pan.___", state 566, "(1)"
+       line 396, "pan.___", state 567, "(1)"
+       line 396, "pan.___", state 567, "(1)"
+       line 400, "pan.___", state 574, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 576, "(1)"
+       line 400, "pan.___", state 577, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 577, "else"
+       line 400, "pan.___", state 580, "(1)"
+       line 400, "pan.___", state 581, "(1)"
+       line 400, "pan.___", state 581, "(1)"
+       line 398, "pan.___", state 586, "((i<2))"
+       line 398, "pan.___", state 586, "((i>=2))"
+       line 404, "pan.___", state 593, "(1)"
+       line 404, "pan.___", state 594, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 594, "else"
+       line 404, "pan.___", state 597, "(1)"
+       line 404, "pan.___", state 598, "(1)"
+       line 404, "pan.___", state 598, "(1)"
+       line 408, "pan.___", state 606, "(1)"
+       line 408, "pan.___", state 607, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 607, "else"
+       line 408, "pan.___", state 610, "(1)"
+       line 408, "pan.___", state 611, "(1)"
+       line 408, "pan.___", state 611, "(1)"
+       line 406, "pan.___", state 616, "((i<1))"
+       line 406, "pan.___", state 616, "((i>=1))"
+       line 413, "pan.___", state 623, "(1)"
+       line 413, "pan.___", state 624, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 624, "else"
+       line 413, "pan.___", state 627, "(1)"
+       line 413, "pan.___", state 628, "(1)"
+       line 413, "pan.___", state 628, "(1)"
+       line 417, "pan.___", state 636, "(1)"
+       line 417, "pan.___", state 637, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 637, "else"
+       line 417, "pan.___", state 640, "(1)"
+       line 417, "pan.___", state 641, "(1)"
+       line 417, "pan.___", state 641, "(1)"
+       line 415, "pan.___", state 646, "((i<2))"
+       line 415, "pan.___", state 646, "((i>=2))"
+       line 422, "pan.___", state 650, "(1)"
+       line 422, "pan.___", state 650, "(1)"
+       line 663, "pan.___", state 653, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 663, "pan.___", state 654, "_proc_urcu_reader = (_proc_urcu_reader|(1<<5))"
+       line 663, "pan.___", state 655, "(1)"
+       line 387, "pan.___", state 662, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 668, "(1)"
+       line 391, "pan.___", state 678, "(1)"
+       line 391, "pan.___", state 679, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 391, "pan.___", state 679, "else"
+       line 391, "pan.___", state 682, "(1)"
+       line 391, "pan.___", state 683, "(1)"
+       line 391, "pan.___", state 683, "(1)"
+       line 389, "pan.___", state 688, "((i<1))"
+       line 389, "pan.___", state 688, "((i>=1))"
+       line 396, "pan.___", state 694, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 700, "(1)"
+       line 396, "pan.___", state 701, "(1)"
+       line 396, "pan.___", state 701, "(1)"
+       line 400, "pan.___", state 708, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 714, "(1)"
+       line 400, "pan.___", state 715, "(1)"
+       line 400, "pan.___", state 715, "(1)"
+       line 398, "pan.___", state 720, "((i<2))"
+       line 398, "pan.___", state 720, "((i>=2))"
+       line 404, "pan.___", state 727, "(1)"
+       line 404, "pan.___", state 728, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 728, "else"
+       line 404, "pan.___", state 731, "(1)"
+       line 404, "pan.___", state 732, "(1)"
+       line 404, "pan.___", state 732, "(1)"
+       line 408, "pan.___", state 740, "(1)"
+       line 408, "pan.___", state 741, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 741, "else"
+       line 408, "pan.___", state 744, "(1)"
+       line 408, "pan.___", state 745, "(1)"
+       line 408, "pan.___", state 745, "(1)"
+       line 406, "pan.___", state 750, "((i<1))"
+       line 406, "pan.___", state 750, "((i>=1))"
+       line 413, "pan.___", state 757, "(1)"
+       line 413, "pan.___", state 758, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 758, "else"
+       line 413, "pan.___", state 761, "(1)"
+       line 413, "pan.___", state 762, "(1)"
+       line 413, "pan.___", state 762, "(1)"
+       line 417, "pan.___", state 770, "(1)"
+       line 417, "pan.___", state 771, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 771, "else"
+       line 417, "pan.___", state 774, "(1)"
+       line 417, "pan.___", state 775, "(1)"
+       line 417, "pan.___", state 775, "(1)"
+       line 422, "pan.___", state 784, "(1)"
+       line 422, "pan.___", state 784, "(1)"
+       line 387, "pan.___", state 798, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 800, "(1)"
+       line 387, "pan.___", state 801, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 387, "pan.___", state 801, "else"
+       line 387, "pan.___", state 804, "(1)"
+       line 391, "pan.___", state 812, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 814, "(1)"
+       line 391, "pan.___", state 815, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 391, "pan.___", state 815, "else"
+       line 391, "pan.___", state 818, "(1)"
+       line 391, "pan.___", state 819, "(1)"
+       line 391, "pan.___", state 819, "(1)"
+       line 389, "pan.___", state 824, "((i<1))"
+       line 389, "pan.___", state 824, "((i>=1))"
+       line 396, "pan.___", state 830, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 832, "(1)"
+       line 396, "pan.___", state 833, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 833, "else"
+       line 396, "pan.___", state 836, "(1)"
+       line 396, "pan.___", state 837, "(1)"
+       line 396, "pan.___", state 837, "(1)"
+       line 400, "pan.___", state 844, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 846, "(1)"
+       line 400, "pan.___", state 847, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 847, "else"
+       line 400, "pan.___", state 850, "(1)"
+       line 400, "pan.___", state 851, "(1)"
+       line 400, "pan.___", state 851, "(1)"
+       line 398, "pan.___", state 856, "((i<2))"
+       line 398, "pan.___", state 856, "((i>=2))"
+       line 404, "pan.___", state 863, "(1)"
+       line 404, "pan.___", state 864, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 864, "else"
+       line 404, "pan.___", state 867, "(1)"
+       line 404, "pan.___", state 868, "(1)"
+       line 404, "pan.___", state 868, "(1)"
+       line 408, "pan.___", state 876, "(1)"
+       line 408, "pan.___", state 877, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 877, "else"
+       line 408, "pan.___", state 880, "(1)"
+       line 408, "pan.___", state 881, "(1)"
+       line 408, "pan.___", state 881, "(1)"
+       line 406, "pan.___", state 886, "((i<1))"
+       line 406, "pan.___", state 886, "((i>=1))"
+       line 413, "pan.___", state 893, "(1)"
+       line 413, "pan.___", state 894, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 894, "else"
+       line 413, "pan.___", state 897, "(1)"
+       line 413, "pan.___", state 898, "(1)"
+       line 413, "pan.___", state 898, "(1)"
+       line 417, "pan.___", state 906, "(1)"
+       line 417, "pan.___", state 907, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 907, "else"
+       line 417, "pan.___", state 910, "(1)"
+       line 417, "pan.___", state 911, "(1)"
+       line 417, "pan.___", state 911, "(1)"
+       line 422, "pan.___", state 920, "(1)"
+       line 422, "pan.___", state 920, "(1)"
+       line 387, "pan.___", state 927, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 929, "(1)"
+       line 387, "pan.___", state 930, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 387, "pan.___", state 930, "else"
+       line 387, "pan.___", state 933, "(1)"
+       line 391, "pan.___", state 941, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 943, "(1)"
+       line 391, "pan.___", state 944, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 391, "pan.___", state 944, "else"
+       line 391, "pan.___", state 947, "(1)"
+       line 391, "pan.___", state 948, "(1)"
+       line 391, "pan.___", state 948, "(1)"
+       line 389, "pan.___", state 953, "((i<1))"
+       line 389, "pan.___", state 953, "((i>=1))"
+       line 396, "pan.___", state 959, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 961, "(1)"
+       line 396, "pan.___", state 962, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 962, "else"
+       line 396, "pan.___", state 965, "(1)"
+       line 396, "pan.___", state 966, "(1)"
+       line 396, "pan.___", state 966, "(1)"
+       line 400, "pan.___", state 973, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 975, "(1)"
+       line 400, "pan.___", state 976, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 976, "else"
+       line 400, "pan.___", state 979, "(1)"
+       line 400, "pan.___", state 980, "(1)"
+       line 400, "pan.___", state 980, "(1)"
+       line 398, "pan.___", state 985, "((i<2))"
+       line 398, "pan.___", state 985, "((i>=2))"
+       line 404, "pan.___", state 992, "(1)"
+       line 404, "pan.___", state 993, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 993, "else"
+       line 404, "pan.___", state 996, "(1)"
+       line 404, "pan.___", state 997, "(1)"
+       line 404, "pan.___", state 997, "(1)"
+       line 408, "pan.___", state 1005, "(1)"
+       line 408, "pan.___", state 1006, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 1006, "else"
+       line 408, "pan.___", state 1009, "(1)"
+       line 408, "pan.___", state 1010, "(1)"
+       line 408, "pan.___", state 1010, "(1)"
+       line 406, "pan.___", state 1015, "((i<1))"
+       line 406, "pan.___", state 1015, "((i>=1))"
+       line 413, "pan.___", state 1022, "(1)"
+       line 413, "pan.___", state 1023, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 1023, "else"
+       line 413, "pan.___", state 1026, "(1)"
+       line 413, "pan.___", state 1027, "(1)"
+       line 413, "pan.___", state 1027, "(1)"
+       line 417, "pan.___", state 1035, "(1)"
+       line 417, "pan.___", state 1036, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 1036, "else"
+       line 417, "pan.___", state 1039, "(1)"
+       line 417, "pan.___", state 1040, "(1)"
+       line 417, "pan.___", state 1040, "(1)"
+       line 415, "pan.___", state 1045, "((i<2))"
+       line 415, "pan.___", state 1045, "((i>=2))"
+       line 422, "pan.___", state 1049, "(1)"
+       line 422, "pan.___", state 1049, "(1)"
+       line 671, "pan.___", state 1053, "_proc_urcu_reader = (_proc_urcu_reader|(1<<11))"
+       line 387, "pan.___", state 1058, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 1064, "(1)"
+       line 391, "pan.___", state 1072, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 1078, "(1)"
+       line 391, "pan.___", state 1079, "(1)"
+       line 391, "pan.___", state 1079, "(1)"
+       line 389, "pan.___", state 1084, "((i<1))"
+       line 389, "pan.___", state 1084, "((i>=1))"
+       line 396, "pan.___", state 1090, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1096, "(1)"
+       line 396, "pan.___", state 1097, "(1)"
+       line 396, "pan.___", state 1097, "(1)"
+       line 400, "pan.___", state 1104, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1110, "(1)"
+       line 400, "pan.___", state 1111, "(1)"
+       line 400, "pan.___", state 1111, "(1)"
+       line 398, "pan.___", state 1116, "((i<2))"
+       line 398, "pan.___", state 1116, "((i>=2))"
+       line 404, "pan.___", state 1123, "(1)"
+       line 404, "pan.___", state 1124, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 1124, "else"
+       line 404, "pan.___", state 1127, "(1)"
+       line 404, "pan.___", state 1128, "(1)"
+       line 404, "pan.___", state 1128, "(1)"
+       line 408, "pan.___", state 1136, "(1)"
+       line 408, "pan.___", state 1137, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 1137, "else"
+       line 408, "pan.___", state 1140, "(1)"
+       line 408, "pan.___", state 1141, "(1)"
+       line 408, "pan.___", state 1141, "(1)"
+       line 406, "pan.___", state 1146, "((i<1))"
+       line 406, "pan.___", state 1146, "((i>=1))"
+       line 413, "pan.___", state 1153, "(1)"
+       line 413, "pan.___", state 1154, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 1154, "else"
+       line 413, "pan.___", state 1157, "(1)"
+       line 413, "pan.___", state 1158, "(1)"
+       line 413, "pan.___", state 1158, "(1)"
+       line 417, "pan.___", state 1166, "(1)"
+       line 417, "pan.___", state 1167, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 1167, "else"
+       line 417, "pan.___", state 1170, "(1)"
+       line 417, "pan.___", state 1171, "(1)"
+       line 417, "pan.___", state 1171, "(1)"
+       line 415, "pan.___", state 1176, "((i<2))"
+       line 415, "pan.___", state 1176, "((i>=2))"
+       line 422, "pan.___", state 1180, "(1)"
+       line 422, "pan.___", state 1180, "(1)"
+       line 387, "pan.___", state 1190, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 1196, "(1)"
+       line 391, "pan.___", state 1206, "(1)"
+       line 391, "pan.___", state 1207, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 391, "pan.___", state 1207, "else"
+       line 391, "pan.___", state 1210, "(1)"
+       line 391, "pan.___", state 1211, "(1)"
+       line 391, "pan.___", state 1211, "(1)"
+       line 389, "pan.___", state 1216, "((i<1))"
+       line 389, "pan.___", state 1216, "((i>=1))"
+       line 396, "pan.___", state 1222, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1228, "(1)"
+       line 396, "pan.___", state 1229, "(1)"
+       line 396, "pan.___", state 1229, "(1)"
+       line 400, "pan.___", state 1236, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1242, "(1)"
+       line 400, "pan.___", state 1243, "(1)"
+       line 400, "pan.___", state 1243, "(1)"
+       line 398, "pan.___", state 1248, "((i<2))"
+       line 398, "pan.___", state 1248, "((i>=2))"
+       line 404, "pan.___", state 1255, "(1)"
+       line 404, "pan.___", state 1256, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 1256, "else"
+       line 404, "pan.___", state 1259, "(1)"
+       line 404, "pan.___", state 1260, "(1)"
+       line 404, "pan.___", state 1260, "(1)"
+       line 408, "pan.___", state 1268, "(1)"
+       line 408, "pan.___", state 1269, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 1269, "else"
+       line 408, "pan.___", state 1272, "(1)"
+       line 408, "pan.___", state 1273, "(1)"
+       line 408, "pan.___", state 1273, "(1)"
+       line 406, "pan.___", state 1278, "((i<1))"
+       line 406, "pan.___", state 1278, "((i>=1))"
+       line 413, "pan.___", state 1285, "(1)"
+       line 413, "pan.___", state 1286, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 1286, "else"
+       line 413, "pan.___", state 1289, "(1)"
+       line 413, "pan.___", state 1290, "(1)"
+       line 413, "pan.___", state 1290, "(1)"
+       line 417, "pan.___", state 1298, "(1)"
+       line 417, "pan.___", state 1299, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 1299, "else"
+       line 417, "pan.___", state 1302, "(1)"
+       line 417, "pan.___", state 1303, "(1)"
+       line 417, "pan.___", state 1303, "(1)"
+       line 422, "pan.___", state 1312, "(1)"
+       line 422, "pan.___", state 1312, "(1)"
+       line 387, "pan.___", state 1323, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 1329, "(1)"
+       line 391, "pan.___", state 1337, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 1343, "(1)"
+       line 391, "pan.___", state 1344, "(1)"
+       line 391, "pan.___", state 1344, "(1)"
+       line 389, "pan.___", state 1349, "((i<1))"
+       line 389, "pan.___", state 1349, "((i>=1))"
+       line 396, "pan.___", state 1355, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1361, "(1)"
+       line 396, "pan.___", state 1362, "(1)"
+       line 396, "pan.___", state 1362, "(1)"
+       line 400, "pan.___", state 1369, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1375, "(1)"
+       line 400, "pan.___", state 1376, "(1)"
+       line 400, "pan.___", state 1376, "(1)"
+       line 398, "pan.___", state 1381, "((i<2))"
+       line 398, "pan.___", state 1381, "((i>=2))"
+       line 404, "pan.___", state 1388, "(1)"
+       line 404, "pan.___", state 1389, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 1389, "else"
+       line 404, "pan.___", state 1392, "(1)"
+       line 404, "pan.___", state 1393, "(1)"
+       line 404, "pan.___", state 1393, "(1)"
+       line 408, "pan.___", state 1401, "(1)"
+       line 408, "pan.___", state 1402, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 1402, "else"
+       line 408, "pan.___", state 1405, "(1)"
+       line 408, "pan.___", state 1406, "(1)"
+       line 408, "pan.___", state 1406, "(1)"
+       line 406, "pan.___", state 1411, "((i<1))"
+       line 406, "pan.___", state 1411, "((i>=1))"
+       line 413, "pan.___", state 1418, "(1)"
+       line 413, "pan.___", state 1419, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 1419, "else"
+       line 413, "pan.___", state 1422, "(1)"
+       line 413, "pan.___", state 1423, "(1)"
+       line 413, "pan.___", state 1423, "(1)"
+       line 417, "pan.___", state 1431, "(1)"
+       line 417, "pan.___", state 1432, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 1432, "else"
+       line 417, "pan.___", state 1435, "(1)"
+       line 417, "pan.___", state 1436, "(1)"
+       line 417, "pan.___", state 1436, "(1)"
+       line 422, "pan.___", state 1445, "(1)"
+       line 422, "pan.___", state 1445, "(1)"
+       line 387, "pan.___", state 1452, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 1458, "(1)"
+       line 391, "pan.___", state 1466, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 1472, "(1)"
+       line 391, "pan.___", state 1473, "(1)"
+       line 391, "pan.___", state 1473, "(1)"
+       line 389, "pan.___", state 1478, "((i<1))"
+       line 389, "pan.___", state 1478, "((i>=1))"
+       line 396, "pan.___", state 1484, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1490, "(1)"
+       line 396, "pan.___", state 1491, "(1)"
+       line 396, "pan.___", state 1491, "(1)"
+       line 400, "pan.___", state 1498, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1504, "(1)"
+       line 400, "pan.___", state 1505, "(1)"
+       line 400, "pan.___", state 1505, "(1)"
+       line 398, "pan.___", state 1510, "((i<2))"
+       line 398, "pan.___", state 1510, "((i>=2))"
+       line 404, "pan.___", state 1517, "(1)"
+       line 404, "pan.___", state 1518, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 1518, "else"
+       line 404, "pan.___", state 1521, "(1)"
+       line 404, "pan.___", state 1522, "(1)"
+       line 404, "pan.___", state 1522, "(1)"
+       line 408, "pan.___", state 1530, "(1)"
+       line 408, "pan.___", state 1531, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 1531, "else"
+       line 408, "pan.___", state 1534, "(1)"
+       line 408, "pan.___", state 1535, "(1)"
+       line 408, "pan.___", state 1535, "(1)"
+       line 406, "pan.___", state 1540, "((i<1))"
+       line 406, "pan.___", state 1540, "((i>=1))"
+       line 413, "pan.___", state 1547, "(1)"
+       line 413, "pan.___", state 1548, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 1548, "else"
+       line 413, "pan.___", state 1551, "(1)"
+       line 413, "pan.___", state 1552, "(1)"
+       line 413, "pan.___", state 1552, "(1)"
+       line 417, "pan.___", state 1560, "(1)"
+       line 417, "pan.___", state 1561, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 1561, "else"
+       line 417, "pan.___", state 1564, "(1)"
+       line 417, "pan.___", state 1565, "(1)"
+       line 417, "pan.___", state 1565, "(1)"
+       line 415, "pan.___", state 1570, "((i<2))"
+       line 415, "pan.___", state 1570, "((i>=2))"
+       line 422, "pan.___", state 1574, "(1)"
+       line 422, "pan.___", state 1574, "(1)"
+       line 387, "pan.___", state 1586, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 1592, "(1)"
+       line 391, "pan.___", state 1602, "(1)"
+       line 391, "pan.___", state 1603, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 391, "pan.___", state 1603, "else"
+       line 391, "pan.___", state 1606, "(1)"
+       line 391, "pan.___", state 1607, "(1)"
+       line 391, "pan.___", state 1607, "(1)"
+       line 389, "pan.___", state 1612, "((i<1))"
+       line 389, "pan.___", state 1612, "((i>=1))"
+       line 396, "pan.___", state 1618, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1624, "(1)"
+       line 396, "pan.___", state 1625, "(1)"
+       line 396, "pan.___", state 1625, "(1)"
+       line 400, "pan.___", state 1632, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1638, "(1)"
+       line 400, "pan.___", state 1639, "(1)"
+       line 400, "pan.___", state 1639, "(1)"
+       line 398, "pan.___", state 1644, "((i<2))"
+       line 398, "pan.___", state 1644, "((i>=2))"
+       line 404, "pan.___", state 1651, "(1)"
+       line 404, "pan.___", state 1652, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 1652, "else"
+       line 404, "pan.___", state 1655, "(1)"
+       line 404, "pan.___", state 1656, "(1)"
+       line 404, "pan.___", state 1656, "(1)"
+       line 408, "pan.___", state 1664, "(1)"
+       line 408, "pan.___", state 1665, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 1665, "else"
+       line 408, "pan.___", state 1668, "(1)"
+       line 408, "pan.___", state 1669, "(1)"
+       line 408, "pan.___", state 1669, "(1)"
+       line 406, "pan.___", state 1674, "((i<1))"
+       line 406, "pan.___", state 1674, "((i>=1))"
+       line 413, "pan.___", state 1681, "(1)"
+       line 413, "pan.___", state 1682, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 1682, "else"
+       line 413, "pan.___", state 1685, "(1)"
+       line 413, "pan.___", state 1686, "(1)"
+       line 413, "pan.___", state 1686, "(1)"
+       line 417, "pan.___", state 1694, "(1)"
+       line 417, "pan.___", state 1695, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 1695, "else"
+       line 417, "pan.___", state 1698, "(1)"
+       line 417, "pan.___", state 1699, "(1)"
+       line 417, "pan.___", state 1699, "(1)"
+       line 422, "pan.___", state 1708, "(1)"
+       line 422, "pan.___", state 1708, "(1)"
+       line 387, "pan.___", state 1715, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 1721, "(1)"
+       line 391, "pan.___", state 1729, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 1735, "(1)"
+       line 391, "pan.___", state 1736, "(1)"
+       line 391, "pan.___", state 1736, "(1)"
+       line 389, "pan.___", state 1741, "((i<1))"
+       line 389, "pan.___", state 1741, "((i>=1))"
+       line 396, "pan.___", state 1747, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1753, "(1)"
+       line 396, "pan.___", state 1754, "(1)"
+       line 396, "pan.___", state 1754, "(1)"
+       line 400, "pan.___", state 1761, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1767, "(1)"
+       line 400, "pan.___", state 1768, "(1)"
+       line 400, "pan.___", state 1768, "(1)"
+       line 398, "pan.___", state 1773, "((i<2))"
+       line 398, "pan.___", state 1773, "((i>=2))"
+       line 404, "pan.___", state 1780, "(1)"
+       line 404, "pan.___", state 1781, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 1781, "else"
+       line 404, "pan.___", state 1784, "(1)"
+       line 404, "pan.___", state 1785, "(1)"
+       line 404, "pan.___", state 1785, "(1)"
+       line 408, "pan.___", state 1793, "(1)"
+       line 408, "pan.___", state 1794, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 1794, "else"
+       line 408, "pan.___", state 1797, "(1)"
+       line 408, "pan.___", state 1798, "(1)"
+       line 408, "pan.___", state 1798, "(1)"
+       line 406, "pan.___", state 1803, "((i<1))"
+       line 406, "pan.___", state 1803, "((i>=1))"
+       line 413, "pan.___", state 1810, "(1)"
+       line 413, "pan.___", state 1811, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 1811, "else"
+       line 413, "pan.___", state 1814, "(1)"
+       line 413, "pan.___", state 1815, "(1)"
+       line 413, "pan.___", state 1815, "(1)"
+       line 417, "pan.___", state 1823, "(1)"
+       line 417, "pan.___", state 1824, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 1824, "else"
+       line 417, "pan.___", state 1827, "(1)"
+       line 417, "pan.___", state 1828, "(1)"
+       line 417, "pan.___", state 1828, "(1)"
+       line 415, "pan.___", state 1833, "((i<2))"
+       line 415, "pan.___", state 1833, "((i>=2))"
+       line 422, "pan.___", state 1837, "(1)"
+       line 422, "pan.___", state 1837, "(1)"
+       line 387, "pan.___", state 1847, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 1853, "(1)"
+       line 391, "pan.___", state 1863, "(1)"
+       line 391, "pan.___", state 1864, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 391, "pan.___", state 1864, "else"
+       line 391, "pan.___", state 1867, "(1)"
+       line 391, "pan.___", state 1868, "(1)"
+       line 391, "pan.___", state 1868, "(1)"
+       line 389, "pan.___", state 1873, "((i<1))"
+       line 389, "pan.___", state 1873, "((i>=1))"
+       line 396, "pan.___", state 1879, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1885, "(1)"
+       line 396, "pan.___", state 1886, "(1)"
+       line 396, "pan.___", state 1886, "(1)"
+       line 400, "pan.___", state 1893, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1899, "(1)"
+       line 400, "pan.___", state 1900, "(1)"
+       line 400, "pan.___", state 1900, "(1)"
+       line 398, "pan.___", state 1905, "((i<2))"
+       line 398, "pan.___", state 1905, "((i>=2))"
+       line 404, "pan.___", state 1912, "(1)"
+       line 404, "pan.___", state 1913, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 1913, "else"
+       line 404, "pan.___", state 1916, "(1)"
+       line 404, "pan.___", state 1917, "(1)"
+       line 404, "pan.___", state 1917, "(1)"
+       line 408, "pan.___", state 1925, "(1)"
+       line 408, "pan.___", state 1926, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 1926, "else"
+       line 408, "pan.___", state 1929, "(1)"
+       line 408, "pan.___", state 1930, "(1)"
+       line 408, "pan.___", state 1930, "(1)"
+       line 406, "pan.___", state 1935, "((i<1))"
+       line 406, "pan.___", state 1935, "((i>=1))"
+       line 413, "pan.___", state 1942, "(1)"
+       line 413, "pan.___", state 1943, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 1943, "else"
+       line 413, "pan.___", state 1946, "(1)"
+       line 413, "pan.___", state 1947, "(1)"
+       line 413, "pan.___", state 1947, "(1)"
+       line 417, "pan.___", state 1955, "(1)"
+       line 417, "pan.___", state 1956, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 1956, "else"
+       line 417, "pan.___", state 1959, "(1)"
+       line 417, "pan.___", state 1960, "(1)"
+       line 417, "pan.___", state 1960, "(1)"
+       line 422, "pan.___", state 1969, "(1)"
+       line 422, "pan.___", state 1969, "(1)"
+       line 710, "pan.___", state 1976, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<19))"
+       line 710, "pan.___", state 1977, "(!((tmp&((1<<7)-1))))"
+       line 710, "pan.___", state 1977, "else"
+       line 387, "pan.___", state 1983, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 1989, "(1)"
+       line 391, "pan.___", state 1997, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 2003, "(1)"
+       line 391, "pan.___", state 2004, "(1)"
+       line 391, "pan.___", state 2004, "(1)"
+       line 389, "pan.___", state 2009, "((i<1))"
+       line 389, "pan.___", state 2009, "((i>=1))"
+       line 396, "pan.___", state 2015, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2021, "(1)"
+       line 396, "pan.___", state 2022, "(1)"
+       line 396, "pan.___", state 2022, "(1)"
+       line 400, "pan.___", state 2029, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2035, "(1)"
+       line 400, "pan.___", state 2036, "(1)"
+       line 400, "pan.___", state 2036, "(1)"
+       line 398, "pan.___", state 2041, "((i<2))"
+       line 398, "pan.___", state 2041, "((i>=2))"
+       line 404, "pan.___", state 2048, "(1)"
+       line 404, "pan.___", state 2049, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 2049, "else"
+       line 404, "pan.___", state 2052, "(1)"
+       line 404, "pan.___", state 2053, "(1)"
+       line 404, "pan.___", state 2053, "(1)"
+       line 408, "pan.___", state 2061, "(1)"
+       line 408, "pan.___", state 2062, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 2062, "else"
+       line 408, "pan.___", state 2065, "(1)"
+       line 408, "pan.___", state 2066, "(1)"
+       line 408, "pan.___", state 2066, "(1)"
+       line 406, "pan.___", state 2071, "((i<1))"
+       line 406, "pan.___", state 2071, "((i>=1))"
+       line 413, "pan.___", state 2078, "(1)"
+       line 413, "pan.___", state 2079, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 2079, "else"
+       line 413, "pan.___", state 2082, "(1)"
+       line 413, "pan.___", state 2083, "(1)"
+       line 413, "pan.___", state 2083, "(1)"
+       line 417, "pan.___", state 2091, "(1)"
+       line 417, "pan.___", state 2092, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 2092, "else"
+       line 417, "pan.___", state 2095, "(1)"
+       line 417, "pan.___", state 2096, "(1)"
+       line 417, "pan.___", state 2096, "(1)"
+       line 422, "pan.___", state 2105, "(1)"
+       line 422, "pan.___", state 2105, "(1)"
+       line 387, "pan.___", state 2112, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 2118, "(1)"
+       line 391, "pan.___", state 2126, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 2132, "(1)"
+       line 391, "pan.___", state 2133, "(1)"
+       line 391, "pan.___", state 2133, "(1)"
+       line 389, "pan.___", state 2138, "((i<1))"
+       line 389, "pan.___", state 2138, "((i>=1))"
+       line 396, "pan.___", state 2144, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2150, "(1)"
+       line 396, "pan.___", state 2151, "(1)"
+       line 396, "pan.___", state 2151, "(1)"
+       line 400, "pan.___", state 2158, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2164, "(1)"
+       line 400, "pan.___", state 2165, "(1)"
+       line 400, "pan.___", state 2165, "(1)"
+       line 398, "pan.___", state 2170, "((i<2))"
+       line 398, "pan.___", state 2170, "((i>=2))"
+       line 404, "pan.___", state 2177, "(1)"
+       line 404, "pan.___", state 2178, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 2178, "else"
+       line 404, "pan.___", state 2181, "(1)"
+       line 404, "pan.___", state 2182, "(1)"
+       line 404, "pan.___", state 2182, "(1)"
+       line 408, "pan.___", state 2190, "(1)"
+       line 408, "pan.___", state 2191, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 2191, "else"
+       line 408, "pan.___", state 2194, "(1)"
+       line 408, "pan.___", state 2195, "(1)"
+       line 408, "pan.___", state 2195, "(1)"
+       line 406, "pan.___", state 2200, "((i<1))"
+       line 406, "pan.___", state 2200, "((i>=1))"
+       line 413, "pan.___", state 2207, "(1)"
+       line 413, "pan.___", state 2208, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 2208, "else"
+       line 413, "pan.___", state 2211, "(1)"
+       line 413, "pan.___", state 2212, "(1)"
+       line 413, "pan.___", state 2212, "(1)"
+       line 417, "pan.___", state 2220, "(1)"
+       line 417, "pan.___", state 2221, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 2221, "else"
+       line 417, "pan.___", state 2224, "(1)"
+       line 417, "pan.___", state 2225, "(1)"
+       line 417, "pan.___", state 2225, "(1)"
+       line 415, "pan.___", state 2230, "((i<2))"
+       line 415, "pan.___", state 2230, "((i>=2))"
+       line 422, "pan.___", state 2234, "(1)"
+       line 422, "pan.___", state 2234, "(1)"
+       line 387, "pan.___", state 2243, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 2245, "(1)"
+       line 387, "pan.___", state 2246, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 387, "pan.___", state 2246, "else"
+       line 387, "pan.___", state 2249, "(1)"
+       line 391, "pan.___", state 2257, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 2259, "(1)"
+       line 391, "pan.___", state 2260, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 391, "pan.___", state 2260, "else"
+       line 391, "pan.___", state 2263, "(1)"
+       line 391, "pan.___", state 2264, "(1)"
+       line 391, "pan.___", state 2264, "(1)"
+       line 389, "pan.___", state 2269, "((i<1))"
+       line 389, "pan.___", state 2269, "((i>=1))"
+       line 396, "pan.___", state 2275, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2277, "(1)"
+       line 396, "pan.___", state 2278, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 2278, "else"
+       line 396, "pan.___", state 2281, "(1)"
+       line 396, "pan.___", state 2282, "(1)"
+       line 396, "pan.___", state 2282, "(1)"
+       line 400, "pan.___", state 2289, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2291, "(1)"
+       line 400, "pan.___", state 2292, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 2292, "else"
+       line 400, "pan.___", state 2295, "(1)"
+       line 400, "pan.___", state 2296, "(1)"
+       line 400, "pan.___", state 2296, "(1)"
+       line 398, "pan.___", state 2301, "((i<2))"
+       line 398, "pan.___", state 2301, "((i>=2))"
+       line 404, "pan.___", state 2308, "(1)"
+       line 404, "pan.___", state 2309, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 2309, "else"
+       line 404, "pan.___", state 2312, "(1)"
+       line 404, "pan.___", state 2313, "(1)"
+       line 404, "pan.___", state 2313, "(1)"
+       line 408, "pan.___", state 2321, "(1)"
+       line 408, "pan.___", state 2322, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 2322, "else"
+       line 408, "pan.___", state 2325, "(1)"
+       line 408, "pan.___", state 2326, "(1)"
+       line 408, "pan.___", state 2326, "(1)"
+       line 406, "pan.___", state 2331, "((i<1))"
+       line 406, "pan.___", state 2331, "((i>=1))"
+       line 413, "pan.___", state 2338, "(1)"
+       line 413, "pan.___", state 2339, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 2339, "else"
+       line 413, "pan.___", state 2342, "(1)"
+       line 413, "pan.___", state 2343, "(1)"
+       line 413, "pan.___", state 2343, "(1)"
+       line 417, "pan.___", state 2351, "(1)"
+       line 417, "pan.___", state 2352, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 2352, "else"
+       line 417, "pan.___", state 2355, "(1)"
+       line 417, "pan.___", state 2356, "(1)"
+       line 417, "pan.___", state 2356, "(1)"
+       line 415, "pan.___", state 2361, "((i<2))"
+       line 415, "pan.___", state 2361, "((i>=2))"
+       line 422, "pan.___", state 2365, "(1)"
+       line 422, "pan.___", state 2365, "(1)"
+       line 710, "pan.___", state 2368, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 710, "pan.___", state 2369, "_proc_urcu_reader = (_proc_urcu_reader|(1<<23))"
+       line 710, "pan.___", state 2370, "(1)"
+       line 387, "pan.___", state 2377, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 2383, "(1)"
+       line 391, "pan.___", state 2393, "(1)"
+       line 391, "pan.___", state 2394, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 391, "pan.___", state 2394, "else"
+       line 391, "pan.___", state 2397, "(1)"
+       line 391, "pan.___", state 2398, "(1)"
+       line 391, "pan.___", state 2398, "(1)"
+       line 389, "pan.___", state 2403, "((i<1))"
+       line 389, "pan.___", state 2403, "((i>=1))"
+       line 396, "pan.___", state 2409, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2415, "(1)"
+       line 396, "pan.___", state 2416, "(1)"
+       line 396, "pan.___", state 2416, "(1)"
+       line 400, "pan.___", state 2423, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2429, "(1)"
+       line 400, "pan.___", state 2430, "(1)"
+       line 400, "pan.___", state 2430, "(1)"
+       line 398, "pan.___", state 2435, "((i<2))"
+       line 398, "pan.___", state 2435, "((i>=2))"
+       line 404, "pan.___", state 2442, "(1)"
+       line 404, "pan.___", state 2443, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 2443, "else"
+       line 404, "pan.___", state 2446, "(1)"
+       line 404, "pan.___", state 2447, "(1)"
+       line 404, "pan.___", state 2447, "(1)"
+       line 408, "pan.___", state 2455, "(1)"
+       line 408, "pan.___", state 2456, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 2456, "else"
+       line 408, "pan.___", state 2459, "(1)"
+       line 408, "pan.___", state 2460, "(1)"
+       line 408, "pan.___", state 2460, "(1)"
+       line 406, "pan.___", state 2465, "((i<1))"
+       line 406, "pan.___", state 2465, "((i>=1))"
+       line 413, "pan.___", state 2472, "(1)"
+       line 413, "pan.___", state 2473, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 2473, "else"
+       line 413, "pan.___", state 2476, "(1)"
+       line 413, "pan.___", state 2477, "(1)"
+       line 413, "pan.___", state 2477, "(1)"
+       line 417, "pan.___", state 2485, "(1)"
+       line 417, "pan.___", state 2486, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 2486, "else"
+       line 417, "pan.___", state 2489, "(1)"
+       line 417, "pan.___", state 2490, "(1)"
+       line 417, "pan.___", state 2490, "(1)"
+       line 422, "pan.___", state 2499, "(1)"
+       line 422, "pan.___", state 2499, "(1)"
+       line 387, "pan.___", state 2512, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 2526, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2544, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2558, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2577, "(1)"
+       line 408, "pan.___", state 2590, "(1)"
+       line 413, "pan.___", state 2607, "(1)"
+       line 417, "pan.___", state 2620, "(1)"
+       line 387, "pan.___", state 2641, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 2655, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2673, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2687, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2706, "(1)"
+       line 408, "pan.___", state 2719, "(1)"
+       line 413, "pan.___", state 2736, "(1)"
+       line 417, "pan.___", state 2749, "(1)"
+       line 227, "pan.___", state 2782, "(1)"
+       line 231, "pan.___", state 2790, "(1)"
+       line 231, "pan.___", state 2791, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 2791, "else"
+       line 229, "pan.___", state 2796, "((i<1))"
+       line 229, "pan.___", state 2796, "((i>=1))"
+       line 235, "pan.___", state 2802, "(1)"
+       line 235, "pan.___", state 2803, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 2803, "else"
+       line 239, "pan.___", state 2810, "(1)"
+       line 239, "pan.___", state 2811, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 2811, "else"
+       line 244, "pan.___", state 2820, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 2820, "else"
+       line 227, "pan.___", state 2825, "(1)"
+       line 231, "pan.___", state 2833, "(1)"
+       line 235, "pan.___", state 2845, "(1)"
+       line 239, "pan.___", state 2853, "(1)"
+       line 870, "pan.___", state 2870, "-end-"
+       (659 of 2870 states)
+unreached in proctype urcu_writer
+       line 387, "pan.___", state 18, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 32, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 50, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 83, "(1)"
+       line 408, "pan.___", state 96, "(1)"
+       line 413, "pan.___", state 113, "(1)"
+       line 417, "pan.___", state 126, "(1)"
+       line 250, "pan.___", state 149, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 158, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 171, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 211, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 217, "(1)"
+       line 391, "pan.___", state 225, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 231, "(1)"
+       line 391, "pan.___", state 232, "(1)"
+       line 391, "pan.___", state 232, "(1)"
+       line 389, "pan.___", state 237, "((i<1))"
+       line 389, "pan.___", state 237, "((i>=1))"
+       line 396, "pan.___", state 243, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 249, "(1)"
+       line 396, "pan.___", state 250, "(1)"
+       line 396, "pan.___", state 250, "(1)"
+       line 400, "pan.___", state 257, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 263, "(1)"
+       line 400, "pan.___", state 264, "(1)"
+       line 400, "pan.___", state 264, "(1)"
+       line 398, "pan.___", state 269, "((i<2))"
+       line 398, "pan.___", state 269, "((i>=2))"
+       line 404, "pan.___", state 276, "(1)"
+       line 404, "pan.___", state 277, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 277, "else"
+       line 404, "pan.___", state 280, "(1)"
+       line 404, "pan.___", state 281, "(1)"
+       line 404, "pan.___", state 281, "(1)"
+       line 408, "pan.___", state 289, "(1)"
+       line 408, "pan.___", state 290, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 290, "else"
+       line 408, "pan.___", state 293, "(1)"
+       line 408, "pan.___", state 294, "(1)"
+       line 408, "pan.___", state 294, "(1)"
+       line 406, "pan.___", state 299, "((i<1))"
+       line 406, "pan.___", state 299, "((i>=1))"
+       line 413, "pan.___", state 306, "(1)"
+       line 413, "pan.___", state 307, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 307, "else"
+       line 413, "pan.___", state 310, "(1)"
+       line 413, "pan.___", state 311, "(1)"
+       line 413, "pan.___", state 311, "(1)"
+       line 417, "pan.___", state 319, "(1)"
+       line 417, "pan.___", state 320, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 320, "else"
+       line 417, "pan.___", state 323, "(1)"
+       line 417, "pan.___", state 324, "(1)"
+       line 417, "pan.___", state 324, "(1)"
+       line 415, "pan.___", state 329, "((i<2))"
+       line 415, "pan.___", state 329, "((i>=2))"
+       line 422, "pan.___", state 333, "(1)"
+       line 422, "pan.___", state 333, "(1)"
+       line 387, "pan.___", state 344, "(1)"
+       line 387, "pan.___", state 345, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 387, "pan.___", state 345, "else"
+       line 387, "pan.___", state 348, "(1)"
+       line 391, "pan.___", state 356, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 362, "(1)"
+       line 391, "pan.___", state 363, "(1)"
+       line 391, "pan.___", state 363, "(1)"
+       line 389, "pan.___", state 368, "((i<1))"
+       line 389, "pan.___", state 368, "((i>=1))"
+       line 396, "pan.___", state 374, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 380, "(1)"
+       line 396, "pan.___", state 381, "(1)"
+       line 396, "pan.___", state 381, "(1)"
+       line 400, "pan.___", state 388, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 394, "(1)"
+       line 400, "pan.___", state 395, "(1)"
+       line 400, "pan.___", state 395, "(1)"
+       line 398, "pan.___", state 400, "((i<2))"
+       line 398, "pan.___", state 400, "((i>=2))"
+       line 404, "pan.___", state 407, "(1)"
+       line 404, "pan.___", state 408, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 408, "else"
+       line 404, "pan.___", state 411, "(1)"
+       line 404, "pan.___", state 412, "(1)"
+       line 404, "pan.___", state 412, "(1)"
+       line 408, "pan.___", state 420, "(1)"
+       line 408, "pan.___", state 421, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 421, "else"
+       line 408, "pan.___", state 424, "(1)"
+       line 408, "pan.___", state 425, "(1)"
+       line 408, "pan.___", state 425, "(1)"
+       line 406, "pan.___", state 430, "((i<1))"
+       line 406, "pan.___", state 430, "((i>=1))"
+       line 413, "pan.___", state 437, "(1)"
+       line 413, "pan.___", state 438, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 438, "else"
+       line 413, "pan.___", state 441, "(1)"
+       line 413, "pan.___", state 442, "(1)"
+       line 413, "pan.___", state 442, "(1)"
+       line 417, "pan.___", state 450, "(1)"
+       line 417, "pan.___", state 451, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 451, "else"
+       line 417, "pan.___", state 454, "(1)"
+       line 417, "pan.___", state 455, "(1)"
+       line 417, "pan.___", state 455, "(1)"
+       line 415, "pan.___", state 460, "((i<2))"
+       line 415, "pan.___", state 460, "((i>=2))"
+       line 422, "pan.___", state 464, "(1)"
+       line 422, "pan.___", state 464, "(1)"
+       line 1056, "pan.___", state 475, "_proc_urcu_writer = (_proc_urcu_writer&~(((1<<8)|(1<<7))))"
+       line 387, "pan.___", state 480, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 486, "(1)"
+       line 391, "pan.___", state 494, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 500, "(1)"
+       line 391, "pan.___", state 501, "(1)"
+       line 391, "pan.___", state 501, "(1)"
+       line 389, "pan.___", state 506, "((i<1))"
+       line 389, "pan.___", state 506, "((i>=1))"
+       line 396, "pan.___", state 512, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 518, "(1)"
+       line 396, "pan.___", state 519, "(1)"
+       line 396, "pan.___", state 519, "(1)"
+       line 400, "pan.___", state 526, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 532, "(1)"
+       line 400, "pan.___", state 533, "(1)"
+       line 400, "pan.___", state 533, "(1)"
+       line 398, "pan.___", state 538, "((i<2))"
+       line 398, "pan.___", state 538, "((i>=2))"
+       line 404, "pan.___", state 545, "(1)"
+       line 404, "pan.___", state 546, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 546, "else"
+       line 404, "pan.___", state 549, "(1)"
+       line 404, "pan.___", state 550, "(1)"
+       line 404, "pan.___", state 550, "(1)"
+       line 408, "pan.___", state 558, "(1)"
+       line 408, "pan.___", state 559, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 559, "else"
+       line 408, "pan.___", state 562, "(1)"
+       line 408, "pan.___", state 563, "(1)"
+       line 408, "pan.___", state 563, "(1)"
+       line 406, "pan.___", state 568, "((i<1))"
+       line 406, "pan.___", state 568, "((i>=1))"
+       line 413, "pan.___", state 575, "(1)"
+       line 413, "pan.___", state 576, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 576, "else"
+       line 413, "pan.___", state 579, "(1)"
+       line 413, "pan.___", state 580, "(1)"
+       line 413, "pan.___", state 580, "(1)"
+       line 417, "pan.___", state 588, "(1)"
+       line 417, "pan.___", state 589, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 589, "else"
+       line 417, "pan.___", state 592, "(1)"
+       line 417, "pan.___", state 593, "(1)"
+       line 417, "pan.___", state 593, "(1)"
+       line 422, "pan.___", state 602, "(1)"
+       line 422, "pan.___", state 602, "(1)"
+       line 387, "pan.___", state 609, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 615, "(1)"
+       line 391, "pan.___", state 623, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 629, "(1)"
+       line 391, "pan.___", state 630, "(1)"
+       line 391, "pan.___", state 630, "(1)"
+       line 389, "pan.___", state 635, "((i<1))"
+       line 389, "pan.___", state 635, "((i>=1))"
+       line 396, "pan.___", state 641, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 647, "(1)"
+       line 396, "pan.___", state 648, "(1)"
+       line 396, "pan.___", state 648, "(1)"
+       line 400, "pan.___", state 655, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 661, "(1)"
+       line 400, "pan.___", state 662, "(1)"
+       line 400, "pan.___", state 662, "(1)"
+       line 398, "pan.___", state 667, "((i<2))"
+       line 398, "pan.___", state 667, "((i>=2))"
+       line 404, "pan.___", state 674, "(1)"
+       line 404, "pan.___", state 675, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 675, "else"
+       line 404, "pan.___", state 678, "(1)"
+       line 404, "pan.___", state 679, "(1)"
+       line 404, "pan.___", state 679, "(1)"
+       line 408, "pan.___", state 687, "(1)"
+       line 408, "pan.___", state 688, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 688, "else"
+       line 408, "pan.___", state 691, "(1)"
+       line 408, "pan.___", state 692, "(1)"
+       line 408, "pan.___", state 692, "(1)"
+       line 406, "pan.___", state 697, "((i<1))"
+       line 406, "pan.___", state 697, "((i>=1))"
+       line 413, "pan.___", state 704, "(1)"
+       line 413, "pan.___", state 705, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 705, "else"
+       line 413, "pan.___", state 708, "(1)"
+       line 413, "pan.___", state 709, "(1)"
+       line 413, "pan.___", state 709, "(1)"
+       line 417, "pan.___", state 717, "(1)"
+       line 417, "pan.___", state 718, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 718, "else"
+       line 417, "pan.___", state 721, "(1)"
+       line 417, "pan.___", state 722, "(1)"
+       line 417, "pan.___", state 722, "(1)"
+       line 415, "pan.___", state 727, "((i<2))"
+       line 415, "pan.___", state 727, "((i>=2))"
+       line 422, "pan.___", state 731, "(1)"
+       line 422, "pan.___", state 731, "(1)"
+       line 387, "pan.___", state 742, "(1)"
+       line 387, "pan.___", state 743, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 387, "pan.___", state 743, "else"
+       line 387, "pan.___", state 746, "(1)"
+       line 391, "pan.___", state 754, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 760, "(1)"
+       line 391, "pan.___", state 761, "(1)"
+       line 391, "pan.___", state 761, "(1)"
+       line 389, "pan.___", state 766, "((i<1))"
+       line 389, "pan.___", state 766, "((i>=1))"
+       line 396, "pan.___", state 772, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 778, "(1)"
+       line 396, "pan.___", state 779, "(1)"
+       line 396, "pan.___", state 779, "(1)"
+       line 400, "pan.___", state 786, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 792, "(1)"
+       line 400, "pan.___", state 793, "(1)"
+       line 400, "pan.___", state 793, "(1)"
+       line 398, "pan.___", state 798, "((i<2))"
+       line 398, "pan.___", state 798, "((i>=2))"
+       line 404, "pan.___", state 805, "(1)"
+       line 404, "pan.___", state 806, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 806, "else"
+       line 404, "pan.___", state 809, "(1)"
+       line 404, "pan.___", state 810, "(1)"
+       line 404, "pan.___", state 810, "(1)"
+       line 408, "pan.___", state 818, "(1)"
+       line 408, "pan.___", state 819, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 819, "else"
+       line 408, "pan.___", state 822, "(1)"
+       line 408, "pan.___", state 823, "(1)"
+       line 408, "pan.___", state 823, "(1)"
+       line 406, "pan.___", state 828, "((i<1))"
+       line 406, "pan.___", state 828, "((i>=1))"
+       line 413, "pan.___", state 835, "(1)"
+       line 413, "pan.___", state 836, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 836, "else"
+       line 413, "pan.___", state 839, "(1)"
+       line 413, "pan.___", state 840, "(1)"
+       line 413, "pan.___", state 840, "(1)"
+       line 417, "pan.___", state 848, "(1)"
+       line 417, "pan.___", state 849, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 849, "else"
+       line 417, "pan.___", state 852, "(1)"
+       line 417, "pan.___", state 853, "(1)"
+       line 417, "pan.___", state 853, "(1)"
+       line 415, "pan.___", state 858, "((i<2))"
+       line 415, "pan.___", state 858, "((i>=2))"
+       line 422, "pan.___", state 862, "(1)"
+       line 422, "pan.___", state 862, "(1)"
+       line 1113, "pan.___", state 872, "_proc_urcu_writer = (_proc_urcu_writer&~(((1<<12)|(1<<11))))"
+       line 250, "pan.___", state 903, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 912, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 927, "(1)"
+       line 262, "pan.___", state 934, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 950, "(1)"
+       line 231, "pan.___", state 958, "(1)"
+       line 235, "pan.___", state 970, "(1)"
+       line 239, "pan.___", state 978, "(1)"
+       line 250, "pan.___", state 1009, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1018, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 252, "pan.___", state 1026, "((i<1))"
+       line 252, "pan.___", state 1026, "((i>=1))"
+       line 258, "pan.___", state 1031, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1040, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 260, "pan.___", state 1048, "((i<2))"
+       line 260, "pan.___", state 1048, "((i>=2))"
+       line 227, "pan.___", state 1056, "(1)"
+       line 231, "pan.___", state 1064, "(1)"
+       line 231, "pan.___", state 1065, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 1065, "else"
+       line 229, "pan.___", state 1070, "((i<1))"
+       line 229, "pan.___", state 1070, "((i>=1))"
+       line 235, "pan.___", state 1076, "(1)"
+       line 235, "pan.___", state 1077, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 1077, "else"
+       line 239, "pan.___", state 1084, "(1)"
+       line 239, "pan.___", state 1085, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 1085, "else"
+       line 244, "pan.___", state 1094, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 1094, "else"
+       line 250, "pan.___", state 1101, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 250, "pan.___", state 1103, "(1)"
+       line 254, "pan.___", state 1110, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1112, "(1)"
+       line 254, "pan.___", state 1113, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 254, "pan.___", state 1113, "else"
+       line 252, "pan.___", state 1118, "((i<1))"
+       line 252, "pan.___", state 1118, "((i>=1))"
+       line 258, "pan.___", state 1123, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1125, "(1)"
+       line 258, "pan.___", state 1126, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 1126, "else"
+       line 262, "pan.___", state 1132, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1134, "(1)"
+       line 262, "pan.___", state 1135, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 262, "pan.___", state 1135, "else"
+       line 260, "pan.___", state 1140, "((i<2))"
+       line 260, "pan.___", state 1140, "((i>=2))"
+       line 227, "pan.___", state 1148, "(1)"
+       line 231, "pan.___", state 1156, "(1)"
+       line 231, "pan.___", state 1157, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 1157, "else"
+       line 229, "pan.___", state 1162, "((i<1))"
+       line 229, "pan.___", state 1162, "((i>=1))"
+       line 235, "pan.___", state 1168, "(1)"
+       line 235, "pan.___", state 1169, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 1169, "else"
+       line 239, "pan.___", state 1176, "(1)"
+       line 239, "pan.___", state 1177, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 1177, "else"
+       line 244, "pan.___", state 1186, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 1186, "else"
+       line 1180, "pan.___", state 1189, "i = 0"
+       line 1180, "pan.___", state 1191, "reader_barrier = 1"
+       line 1180, "pan.___", state 1202, "((i<1))"
+       line 1180, "pan.___", state 1202, "((i>=1))"
+       line 250, "pan.___", state 1207, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 250, "pan.___", state 1209, "(1)"
+       line 254, "pan.___", state 1216, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1218, "(1)"
+       line 254, "pan.___", state 1219, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 254, "pan.___", state 1219, "else"
+       line 252, "pan.___", state 1224, "((i<1))"
+       line 252, "pan.___", state 1224, "((i>=1))"
+       line 258, "pan.___", state 1229, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1231, "(1)"
+       line 258, "pan.___", state 1232, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 1232, "else"
+       line 262, "pan.___", state 1238, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1240, "(1)"
+       line 262, "pan.___", state 1241, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 262, "pan.___", state 1241, "else"
+       line 260, "pan.___", state 1246, "((i<2))"
+       line 260, "pan.___", state 1246, "((i>=2))"
+       line 227, "pan.___", state 1254, "(1)"
+       line 231, "pan.___", state 1262, "(1)"
+       line 231, "pan.___", state 1263, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 1263, "else"
+       line 229, "pan.___", state 1268, "((i<1))"
+       line 229, "pan.___", state 1268, "((i>=1))"
+       line 235, "pan.___", state 1274, "(1)"
+       line 235, "pan.___", state 1275, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 1275, "else"
+       line 239, "pan.___", state 1282, "(1)"
+       line 239, "pan.___", state 1283, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 1283, "else"
+       line 244, "pan.___", state 1292, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 1292, "else"
+       line 277, "pan.___", state 1294, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 277, "pan.___", state 1294, "else"
+       line 1180, "pan.___", state 1295, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 1180, "pan.___", state 1295, "else"
+       line 250, "pan.___", state 1299, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 250, "pan.___", state 1301, "(1)"
+       line 254, "pan.___", state 1308, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1310, "(1)"
+       line 254, "pan.___", state 1311, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 254, "pan.___", state 1311, "else"
+       line 252, "pan.___", state 1316, "((i<1))"
+       line 252, "pan.___", state 1316, "((i>=1))"
+       line 258, "pan.___", state 1321, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1323, "(1)"
+       line 258, "pan.___", state 1324, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 1324, "else"
+       line 262, "pan.___", state 1330, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1332, "(1)"
+       line 262, "pan.___", state 1333, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 262, "pan.___", state 1333, "else"
+       line 260, "pan.___", state 1338, "((i<2))"
+       line 260, "pan.___", state 1338, "((i>=2))"
+       line 227, "pan.___", state 1346, "(1)"
+       line 231, "pan.___", state 1354, "(1)"
+       line 231, "pan.___", state 1355, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 1355, "else"
+       line 229, "pan.___", state 1360, "((i<1))"
+       line 229, "pan.___", state 1360, "((i>=1))"
+       line 235, "pan.___", state 1366, "(1)"
+       line 235, "pan.___", state 1367, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 1367, "else"
+       line 239, "pan.___", state 1374, "(1)"
+       line 239, "pan.___", state 1375, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 1375, "else"
+       line 244, "pan.___", state 1384, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 1384, "else"
+       line 1183, "pan.___", state 1387, "i = 0"
+       line 1183, "pan.___", state 1389, "reader_barrier = 1"
+       line 1183, "pan.___", state 1400, "((i<1))"
+       line 1183, "pan.___", state 1400, "((i>=1))"
+       line 250, "pan.___", state 1405, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 250, "pan.___", state 1407, "(1)"
+       line 254, "pan.___", state 1414, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1416, "(1)"
+       line 254, "pan.___", state 1417, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 254, "pan.___", state 1417, "else"
+       line 252, "pan.___", state 1422, "((i<1))"
+       line 252, "pan.___", state 1422, "((i>=1))"
+       line 258, "pan.___", state 1427, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1429, "(1)"
+       line 258, "pan.___", state 1430, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 1430, "else"
+       line 262, "pan.___", state 1436, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1438, "(1)"
+       line 262, "pan.___", state 1439, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 262, "pan.___", state 1439, "else"
+       line 260, "pan.___", state 1444, "((i<2))"
+       line 260, "pan.___", state 1444, "((i>=2))"
+       line 227, "pan.___", state 1452, "(1)"
+       line 231, "pan.___", state 1460, "(1)"
+       line 231, "pan.___", state 1461, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 1461, "else"
+       line 229, "pan.___", state 1466, "((i<1))"
+       line 229, "pan.___", state 1466, "((i>=1))"
+       line 235, "pan.___", state 1472, "(1)"
+       line 235, "pan.___", state 1473, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 1473, "else"
+       line 239, "pan.___", state 1480, "(1)"
+       line 239, "pan.___", state 1481, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 1481, "else"
+       line 244, "pan.___", state 1490, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 1490, "else"
+       line 277, "pan.___", state 1492, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 277, "pan.___", state 1492, "else"
+       line 1183, "pan.___", state 1493, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 1183, "pan.___", state 1493, "else"
+       line 250, "pan.___", state 1497, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1506, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 252, "pan.___", state 1514, "((i<1))"
+       line 252, "pan.___", state 1514, "((i>=1))"
+       line 258, "pan.___", state 1519, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1528, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 260, "pan.___", state 1536, "((i<2))"
+       line 260, "pan.___", state 1536, "((i>=2))"
+       line 227, "pan.___", state 1544, "(1)"
+       line 231, "pan.___", state 1552, "(1)"
+       line 231, "pan.___", state 1553, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 1553, "else"
+       line 229, "pan.___", state 1558, "((i<1))"
+       line 229, "pan.___", state 1558, "((i>=1))"
+       line 235, "pan.___", state 1564, "(1)"
+       line 235, "pan.___", state 1565, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 1565, "else"
+       line 239, "pan.___", state 1572, "(1)"
+       line 239, "pan.___", state 1573, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 1573, "else"
+       line 244, "pan.___", state 1582, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 1582, "else"
+       line 1187, "pan.___", state 1585, "i = 0"
+       line 1187, "pan.___", state 1587, "reader_barrier = 1"
+       line 1187, "pan.___", state 1598, "((i<1))"
+       line 1187, "pan.___", state 1598, "((i>=1))"
+       line 250, "pan.___", state 1603, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1612, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 252, "pan.___", state 1620, "((i<1))"
+       line 252, "pan.___", state 1620, "((i>=1))"
+       line 258, "pan.___", state 1625, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1634, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 260, "pan.___", state 1642, "((i<2))"
+       line 260, "pan.___", state 1642, "((i>=2))"
+       line 227, "pan.___", state 1650, "(1)"
+       line 231, "pan.___", state 1658, "(1)"
+       line 231, "pan.___", state 1659, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 1659, "else"
+       line 229, "pan.___", state 1664, "((i<1))"
+       line 229, "pan.___", state 1664, "((i>=1))"
+       line 235, "pan.___", state 1670, "(1)"
+       line 235, "pan.___", state 1671, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 1671, "else"
+       line 239, "pan.___", state 1678, "(1)"
+       line 239, "pan.___", state 1679, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 1679, "else"
+       line 244, "pan.___", state 1688, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 1688, "else"
+       line 1191, "pan.___", state 1694, "-end-"
+       (328 of 1694 states)
+unreached in proctype :init:
+       (0 of 78 states)
+unreached in proctype :never:
+       line 1252, "pan.___", state 11, "-end-"
+       (1 of 11 states)
+
+pan: elapsed time 0.03 seconds
+pan: rate 32966.667 states/second
+pan: avg transition delay 1.6739e-06 usec
+cp .input.spin urcu_progress_reader.spin.input
+cp .input.spin.trail urcu_progress_reader.spin.input.trail
+make[1]: Leaving directory `/home/compudj/doc/userspace-rcu/formal-model/urcu-controldataflow'
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_reader.spin.input b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_reader.spin.input
new file mode 100644 (file)
index 0000000..9f350f2
--- /dev/null
@@ -0,0 +1,1227 @@
+#define READER_PROGRESS
+
+// Poison value for freed memory
+#define POISON 1
+// Memory with correct data
+#define WINE 0
+#define SLAB_SIZE 2
+
+#define read_poison    (data_read_first[0] == POISON || data_read_second[0] == POISON)
+
+#define RCU_GP_CTR_BIT (1 << 7)
+#define RCU_GP_CTR_NEST_MASK (RCU_GP_CTR_BIT - 1)
+
+//disabled
+#define REMOTE_BARRIERS
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+typedef per_proc_bit {
+       bit val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bitfield {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bitfield cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               smp_mb(i, j);
+               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
+               break;
+       od;
+}
+
+#ifdef WRITER_PROGRESS
+//#define PROGRESS_LABEL(progressid)   progress_writer_progid_##progressid:
+#define PROGRESS_LABEL(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;                                          \
+               /*                                                              \
+                * 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)                                                     \
+               do                                                              \
+               :: (reader_barrier[i] == 1) -> skip;                            \
+               :: (reader_barrier[i] == 0) -> break;                           \
+               od;                                                             \
+               i++;                                                            \
+       :: i >= NR_READERS ->                                                   \
+               break                                                           \
+       od;                                                                     \
+       smp_mb(i, j);                                                           \
+}
+
+#else
+
+#define smp_mb_send(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, smp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only one reader */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* RCU data */
+DECLARE_CACHED_VAR(bit, rcu_data[SLAB_SIZE]);
+
+/* RCU pointer */
+#if (SLAB_SIZE == 2)
+DECLARE_CACHED_VAR(bit, rcu_ptr);
+bit ptr_read_first[NR_READERS];
+bit ptr_read_second[NR_READERS];
+#else
+DECLARE_CACHED_VAR(byte, rcu_ptr);
+byte ptr_read_first[NR_READERS];
+byte ptr_read_second[NR_READERS];
+#endif
+
+bit data_read_first[NR_READERS];
+bit data_read_second[NR_READERS];
+
+bit init_done = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               :: 1 -> skip;
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               ptr_read_first[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb1;
+rmb1_end:
+                               data_read_first[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_first[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               ptr_read_second[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb2;
+rmb2_end:
+                               data_read_second[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_second[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+rmb1:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb1_end;
+rmb2:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_DATA                     (1 << 1)
+#define WRITE_PROC_WMB                 (1 << 2)
+#define WRITE_XCHG_PTR                 (1 << 3)
+
+#define WRITE_PROC_FIRST_MB            (1 << 4)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 5)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 6)
+#define WRITE_PROC_FIRST_WAIT          (1 << 7)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 8)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 9)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 10)
+#define WRITE_PROC_SECOND_WAIT         (1 << 11)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 12)
+
+#define WRITE_PROC_SECOND_MB           (1 << 13)
+
+#define WRITE_FREE                     (1 << 14)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_DATA                    \
+                                       | WRITE_PROC_WMB                \
+                                       | WRITE_XCHG_PTR                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB          \
+                                       | WRITE_FREE)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 15) - 1)
+
+/*
+ * Mutexes are implied around writer execution. A single writer at a time.
+ */
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte cur_data = 0, old_data, loop_nr = 0;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (loop_nr < 3) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               loop_nr = loop_nr + 1;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_WMB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+#endif
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_DATA) ->
+                       ooo_mem(i);
+                       cur_data = (cur_data + 1) % SLAB_SIZE;
+                       WRITE_CACHED_VAR(rcu_data[cur_data], WINE);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_DATA);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA,
+                                 WRITE_PROC_WMB) ->
+                       smp_wmb(i, j);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_WMB,
+                                 WRITE_XCHG_PTR) ->
+                       /* rcu_xchg_pointer() */
+                       atomic {
+                               old_data = READ_CACHED_VAR(rcu_ptr);
+                               WRITE_CACHED_VAR(rcu_ptr, cur_data);
+                       }
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_XCHG_PTR);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_WMB      /* No dependency on
+                                                        * WRITE_DATA because we
+                                                        * write to a
+                                                        * different location. */
+                                 | WRITE_PROC_SECOND_MB
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_FREE) ->
+                       WRITE_CACHED_VAR(rcu_data[old_data], POISON);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_FREE);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+               /*
+                * Note : Promela model adds implicit serialization of the
+                * WRITE_FREE instruction. Normally, it would be permitted to
+                * spill on the next loop execution. Given the validation we do
+                * checks for the data entry read to be poisoned, it's ok if
+                * we do not check "late arriving" memory poisoning.
+                */
+       :: 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
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(rcu_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       ptr_read_first[i] = 1;
+                       ptr_read_second[i] = 1;
+                       data_read_first[i] = WINE;
+                       data_read_second[i] = WINE;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               INIT_CACHED_VAR(rcu_data[0], WINE, j);
+               i = 1;
+               do
+               :: i < SLAB_SIZE ->
+                       INIT_CACHED_VAR(rcu_data[i], POISON, j);
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_reader.spin.input.trail b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_reader.spin.input.trail
new file mode 100644 (file)
index 0000000..46f9f69
--- /dev/null
@@ -0,0 +1,2937 @@
+-2:3:-2
+-4:-4:-4
+1:0:4644
+2:3:4564
+3:3:4567
+4:3:4567
+5:3:4570
+6:3:4578
+7:3:4578
+8:3:4581
+9:3:4587
+10:3:4591
+11:3:4591
+12:3:4594
+13:3:4604
+14:3:4612
+15:3:4612
+16:3:4615
+17:3:4621
+18:3:4625
+19:3:4625
+20:3:4628
+21:3:4634
+22:3:4638
+23:3:4639
+24:0:4644
+25:3:4641
+26:0:4644
+27:2:2872
+28:0:4644
+29:2:2878
+30:0:4644
+31:2:2879
+32:0:4644
+33:2:2881
+34:0:4644
+35:2:2882
+36:0:4644
+37:2:2883
+38:2:2884
+39:2:2888
+40:2:2889
+41:2:2897
+42:2:2898
+43:2:2902
+44:2:2903
+45:2:2911
+46:2:2916
+47:2:2920
+48:2:2921
+49:2:2929
+50:2:2930
+51:2:2934
+52:2:2935
+53:2:2929
+54:2:2930
+55:2:2934
+56:2:2935
+57:2:2943
+58:2:2948
+59:2:2949
+60:2:2960
+61:2:2961
+62:2:2962
+63:2:2973
+64:2:2978
+65:2:2979
+66:2:2990
+67:2:2991
+68:2:2992
+69:2:2990
+70:2:2991
+71:2:2992
+72:2:3003
+73:2:3011
+74:0:4644
+75:2:2882
+76:0:4644
+77:2:3015
+78:2:3019
+79:2:3020
+80:2:3024
+81:2:3028
+82:2:3029
+83:2:3033
+84:2:3041
+85:2:3042
+86:2:3046
+87:2:3050
+88:2:3051
+89:2:3046
+90:2:3047
+91:2:3055
+92:0:4644
+93:2:2882
+94:0:4644
+95:2:3063
+96:2:3064
+97:2:3065
+98:0:4644
+99:2:2882
+100:0:4644
+101:2:3070
+102:0:4644
+103:2:3773
+104:2:3774
+105:2:3778
+106:2:3782
+107:2:3783
+108:2:3787
+109:2:3792
+110:2:3800
+111:2:3804
+112:2:3805
+113:2:3800
+114:2:3804
+115:2:3805
+116:2:3809
+117:2:3816
+118:2:3823
+119:2:3824
+120:2:3831
+121:2:3836
+122:2:3843
+123:2:3844
+124:2:3843
+125:2:3844
+126:2:3851
+127:2:3855
+128:0:4644
+129:2:3860
+130:0:4644
+131:2:3861
+132:0:4644
+133:2:3862
+134:0:4644
+135:2:3863
+136:0:4644
+137:1:2
+138:0:4644
+139:2:3864
+140:0:4644
+141:1:8
+142:0:4644
+143:2:3863
+144:0:4644
+145:1:9
+146:0:4644
+147:2:3864
+148:0:4644
+149:1:10
+150:0:4642
+151:2:3863
+152:0:4648
+153:2:3864
+154:0:4648
+155:1:11
+156:0:4648
+157:2:3863
+158:0:4648
+159:2:3864
+160:0:4648
+161:1:12
+162:0:4648
+163:2:3863
+164:0:4648
+165:2:3864
+166:0:4648
+167:1:13
+168:0:4648
+169:2:3863
+170:0:4648
+171:2:3864
+172:0:4648
+173:1:14
+174:0:4648
+175:1:15
+176:0:4648
+177:1:16
+178:0:4648
+179:2:3863
+180:0:4648
+181:2:3864
+182:0:4648
+183:1:17
+184:0:4648
+185:2:3863
+186:0:4648
+187:2:3864
+188:0:4648
+189:1:28
+190:0:4648
+191:2:3863
+192:0:4648
+193:2:3864
+194:0:4648
+195:1:32
+196:1:33
+197:1:37
+198:1:41
+199:1:42
+200:1:46
+201:1:54
+202:1:55
+203:1:59
+204:1:63
+205:1:64
+206:1:59
+207:1:63
+208:1:64
+209:1:68
+210:1:75
+211:1:82
+212:1:83
+213:1:90
+214:1:95
+215:1:102
+216:1:103
+217:1:102
+218:1:103
+219:1:110
+220:1:114
+221:0:4648
+222:2:3863
+223:0:4648
+224:2:3864
+225:0:4648
+226:1:119
+227:0:4648
+228:2:3865
+229:0:4648
+230:2:3870
+231:0:4648
+232:2:3871
+233:0:4648
+234:2:3879
+235:2:3880
+236:2:3884
+237:2:3888
+238:2:3889
+239:2:3893
+240:2:3901
+241:2:3902
+242:2:3906
+243:2:3910
+244:2:3911
+245:2:3906
+246:2:3910
+247:2:3911
+248:2:3915
+249:2:3922
+250:2:3929
+251:2:3930
+252:2:3937
+253:2:3942
+254:2:3949
+255:2:3950
+256:2:3949
+257:2:3950
+258:2:3957
+259:2:3961
+260:0:4648
+261:2:3072
+262:2:3754
+263:0:4648
+264:2:2882
+265:0:4648
+266:2:3073
+267:0:4648
+268:2:2882
+269:0:4648
+270:2:3076
+271:2:3077
+272:2:3081
+273:2:3082
+274:2:3090
+275:2:3091
+276:2:3095
+277:2:3096
+278:2:3104
+279:2:3109
+280:2:3113
+281:2:3114
+282:2:3122
+283:2:3123
+284:2:3127
+285:2:3128
+286:2:3122
+287:2:3123
+288:2:3127
+289:2:3128
+290:2:3136
+291:2:3141
+292:2:3142
+293:2:3153
+294:2:3154
+295:2:3155
+296:2:3166
+297:2:3171
+298:2:3172
+299:2:3183
+300:2:3184
+301:2:3185
+302:2:3183
+303:2:3184
+304:2:3185
+305:2:3196
+306:2:3203
+307:0:4648
+308:2:2882
+309:0:4648
+310:2:3207
+311:2:3208
+312:2:3209
+313:2:3221
+314:2:3222
+315:2:3226
+316:2:3227
+317:2:3235
+318:2:3240
+319:2:3244
+320:2:3245
+321:2:3253
+322:2:3254
+323:2:3258
+324:2:3259
+325:2:3253
+326:2:3254
+327:2:3258
+328:2:3259
+329:2:3267
+330:2:3272
+331:2:3273
+332:2:3284
+333:2:3285
+334:2:3286
+335:2:3297
+336:2:3302
+337:2:3303
+338:2:3314
+339:2:3315
+340:2:3316
+341:2:3314
+342:2:3315
+343:2:3316
+344:2:3327
+345:2:3338
+346:2:3339
+347:0:4648
+348:2:2882
+349:0:4648
+350:2:3345
+351:2:3346
+352:2:3350
+353:2:3351
+354:2:3359
+355:2:3360
+356:2:3364
+357:2:3365
+358:2:3373
+359:2:3378
+360:2:3382
+361:2:3383
+362:2:3391
+363:2:3392
+364:2:3396
+365:2:3397
+366:2:3391
+367:2:3392
+368:2:3396
+369:2:3397
+370:2:3405
+371:2:3410
+372:2:3411
+373:2:3422
+374:2:3423
+375:2:3424
+376:2:3435
+377:2:3440
+378:2:3441
+379:2:3452
+380:2:3453
+381:2:3454
+382:2:3452
+383:2:3453
+384:2:3454
+385:2:3465
+386:0:4648
+387:2:2882
+388:0:4648
+389:2:3474
+390:2:3475
+391:2:3479
+392:2:3480
+393:2:3488
+394:2:3489
+395:2:3493
+396:2:3494
+397:2:3502
+398:2:3507
+399:2:3511
+400:2:3512
+401:2:3520
+402:2:3521
+403:2:3525
+404:2:3526
+405:2:3520
+406:2:3521
+407:2:3525
+408:2:3526
+409:2:3534
+410:2:3539
+411:2:3540
+412:2:3551
+413:2:3552
+414:2:3553
+415:2:3564
+416:2:3569
+417:2:3570
+418:2:3581
+419:2:3582
+420:2:3583
+421:2:3581
+422:2:3582
+423:2:3583
+424:2:3594
+425:2:3601
+426:0:4648
+427:2:2882
+428:0:4648
+429:2:3605
+430:2:3606
+431:2:3607
+432:2:3619
+433:2:3620
+434:2:3624
+435:2:3625
+436:2:3633
+437:2:3638
+438:2:3642
+439:2:3643
+440:2:3651
+441:2:3652
+442:2:3656
+443:2:3657
+444:2:3651
+445:2:3652
+446:2:3656
+447:2:3657
+448:2:3665
+449:2:3670
+450:2:3671
+451:2:3682
+452:2:3683
+453:2:3684
+454:2:3695
+455:2:3700
+456:2:3701
+457:2:3712
+458:2:3713
+459:2:3714
+460:2:3712
+461:2:3713
+462:2:3714
+463:2:3725
+464:2:3735
+465:2:3736
+466:0:4648
+467:2:2882
+468:0:4648
+469:2:3742
+470:0:4648
+471:2:4367
+472:2:4368
+473:2:4372
+474:2:4376
+475:2:4377
+476:2:4381
+477:2:4389
+478:2:4390
+479:2:4394
+480:2:4398
+481:2:4399
+482:2:4394
+483:2:4398
+484:2:4399
+485:2:4403
+486:2:4410
+487:2:4417
+488:2:4418
+489:2:4425
+490:2:4430
+491:2:4437
+492:2:4438
+493:2:4437
+494:2:4438
+495:2:4445
+496:2:4449
+497:0:4648
+498:2:4454
+499:0:4648
+500:2:4455
+501:0:4648
+502:2:4456
+503:0:4648
+504:2:4457
+505:0:4648
+506:1:28
+507:0:4648
+508:2:4458
+509:0:4648
+510:2:4457
+511:0:4648
+512:1:32
+513:1:33
+514:1:37
+515:1:41
+516:1:42
+517:1:46
+518:1:54
+519:1:55
+520:1:59
+521:1:63
+522:1:64
+523:1:59
+524:1:63
+525:1:64
+526:1:68
+527:1:75
+528:1:82
+529:1:83
+530:1:90
+531:1:95
+532:1:102
+533:1:103
+534:1:102
+535:1:103
+536:1:110
+537:1:114
+538:0:4648
+539:2:4458
+540:0:4648
+541:2:4457
+542:0:4648
+543:1:119
+544:0:4648
+545:2:4458
+546:0:4648
+547:2:4459
+548:0:4648
+549:2:4464
+550:0:4648
+551:2:4465
+552:0:4648
+553:2:4473
+554:2:4474
+555:2:4478
+556:2:4482
+557:2:4483
+558:2:4487
+559:2:4495
+560:2:4496
+561:2:4500
+562:2:4504
+563:2:4505
+564:2:4500
+565:2:4504
+566:2:4505
+567:2:4509
+568:2:4516
+569:2:4523
+570:2:4524
+571:2:4531
+572:2:4536
+573:2:4543
+574:2:4544
+575:2:4543
+576:2:4544
+577:2:4551
+578:2:4555
+579:0:4648
+580:2:3744
+581:2:3754
+582:0:4648
+583:2:2882
+584:0:4648
+585:2:3745
+586:2:3746
+587:0:4648
+588:2:2882
+589:0:4648
+590:2:3750
+591:0:4648
+592:2:3758
+593:0:4648
+594:2:2879
+595:0:4648
+596:2:2881
+597:0:4648
+598:2:2882
+599:0:4648
+600:2:2883
+601:2:2884
+602:2:2888
+603:2:2889
+604:2:2897
+605:2:2898
+606:2:2902
+607:2:2903
+608:2:2911
+609:2:2916
+610:2:2920
+611:2:2921
+612:2:2929
+613:2:2930
+614:2:2931
+615:2:2929
+616:2:2930
+617:2:2934
+618:2:2935
+619:2:2943
+620:2:2948
+621:2:2949
+622:2:2960
+623:2:2961
+624:2:2962
+625:2:2973
+626:2:2978
+627:2:2979
+628:2:2990
+629:2:2991
+630:2:2992
+631:2:2990
+632:2:2991
+633:2:2992
+634:2:3003
+635:2:3011
+636:0:4648
+637:2:2882
+638:0:4648
+639:2:3015
+640:2:3019
+641:2:3020
+642:2:3024
+643:2:3028
+644:2:3029
+645:2:3033
+646:2:3041
+647:2:3042
+648:2:3046
+649:2:3047
+650:2:3046
+651:2:3050
+652:2:3051
+653:2:3055
+654:0:4648
+655:2:2882
+656:0:4648
+657:2:3063
+658:2:3064
+659:2:3065
+660:0:4648
+661:2:2882
+662:0:4648
+663:2:3070
+664:0:4648
+665:2:3773
+666:2:3774
+667:2:3778
+668:2:3782
+669:2:3783
+670:2:3787
+671:2:3792
+672:2:3800
+673:2:3804
+674:2:3805
+675:2:3800
+676:2:3804
+677:2:3805
+678:2:3809
+679:2:3816
+680:2:3823
+681:2:3824
+682:2:3831
+683:2:3836
+684:2:3843
+685:2:3844
+686:2:3843
+687:2:3844
+688:2:3851
+689:2:3855
+690:0:4648
+691:2:3860
+692:0:4648
+693:2:3861
+694:0:4648
+695:2:3862
+696:0:4648
+697:2:3863
+698:0:4648
+699:1:28
+700:0:4648
+701:2:3864
+702:0:4648
+703:2:3863
+704:0:4648
+705:1:32
+706:1:33
+707:1:37
+708:1:41
+709:1:42
+710:1:46
+711:1:54
+712:1:55
+713:1:59
+714:1:63
+715:1:64
+716:1:59
+717:1:63
+718:1:64
+719:1:68
+720:1:75
+721:1:82
+722:1:83
+723:1:90
+724:1:95
+725:1:102
+726:1:103
+727:1:102
+728:1:103
+729:1:110
+730:1:114
+731:0:4648
+732:2:3864
+733:0:4648
+734:2:3863
+735:0:4648
+736:1:119
+737:0:4648
+738:2:3864
+739:0:4648
+740:2:3865
+741:0:4648
+742:2:3870
+743:0:4648
+744:2:3871
+745:0:4648
+746:2:3879
+747:2:3880
+748:2:3884
+749:2:3888
+750:2:3889
+751:2:3893
+752:2:3901
+753:2:3902
+754:2:3906
+755:2:3910
+756:2:3911
+757:2:3906
+758:2:3910
+759:2:3911
+760:2:3915
+761:2:3922
+762:2:3929
+763:2:3930
+764:2:3937
+765:2:3942
+766:2:3949
+767:2:3950
+768:2:3949
+769:2:3950
+770:2:3957
+771:2:3961
+772:0:4648
+773:2:3072
+774:2:3754
+775:0:4648
+776:2:2882
+777:0:4648
+778:2:3073
+779:0:4648
+780:2:2882
+781:0:4648
+782:2:3076
+783:2:3077
+784:2:3081
+785:2:3082
+786:2:3090
+787:2:3091
+788:2:3095
+789:2:3096
+790:2:3104
+791:2:3109
+792:2:3113
+793:2:3114
+794:2:3122
+795:2:3123
+796:2:3127
+797:2:3128
+798:2:3122
+799:2:3123
+800:2:3127
+801:2:3128
+802:2:3136
+803:2:3141
+804:2:3142
+805:2:3153
+806:2:3154
+807:2:3155
+808:2:3166
+809:2:3171
+810:2:3172
+811:2:3183
+812:2:3184
+813:2:3185
+814:2:3183
+815:2:3184
+816:2:3185
+817:2:3196
+818:2:3203
+819:0:4648
+820:2:2882
+821:0:4648
+822:2:3207
+823:2:3208
+824:2:3209
+825:2:3221
+826:2:3222
+827:2:3226
+828:2:3227
+829:2:3235
+830:2:3240
+831:2:3244
+832:2:3245
+833:2:3253
+834:2:3254
+835:2:3258
+836:2:3259
+837:2:3253
+838:2:3254
+839:2:3258
+840:2:3259
+841:2:3267
+842:2:3272
+843:2:3273
+844:2:3284
+845:2:3285
+846:2:3286
+847:2:3297
+848:2:3302
+849:2:3303
+850:2:3314
+851:2:3315
+852:2:3316
+853:2:3314
+854:2:3315
+855:2:3316
+856:2:3327
+857:2:3338
+858:2:3339
+859:0:4648
+860:2:2882
+861:0:4648
+862:2:3345
+863:2:3346
+864:2:3350
+865:2:3351
+866:2:3359
+867:2:3360
+868:2:3364
+869:2:3365
+870:2:3373
+871:2:3378
+872:2:3382
+873:2:3383
+874:2:3391
+875:2:3392
+876:2:3396
+877:2:3397
+878:2:3391
+879:2:3392
+880:2:3396
+881:2:3397
+882:2:3405
+883:2:3410
+884:2:3411
+885:2:3422
+886:2:3423
+887:2:3424
+888:2:3435
+889:2:3440
+890:2:3441
+891:2:3452
+892:2:3453
+893:2:3454
+894:2:3452
+895:2:3453
+896:2:3454
+897:2:3465
+898:0:4648
+899:2:2882
+900:0:4648
+901:2:3474
+902:2:3475
+903:2:3479
+904:2:3480
+905:2:3488
+906:2:3489
+907:2:3493
+908:2:3494
+909:2:3502
+910:2:3507
+911:2:3511
+912:2:3512
+913:2:3520
+914:2:3521
+915:2:3525
+916:2:3526
+917:2:3520
+918:2:3521
+919:2:3525
+920:2:3526
+921:2:3534
+922:2:3539
+923:2:3540
+924:2:3551
+925:2:3552
+926:2:3553
+927:2:3564
+928:2:3569
+929:2:3570
+930:2:3581
+931:2:3582
+932:2:3583
+933:2:3581
+934:2:3582
+935:2:3583
+936:2:3594
+937:2:3601
+938:0:4648
+939:2:2882
+940:0:4648
+941:2:3605
+942:2:3606
+943:2:3607
+944:2:3619
+945:2:3620
+946:2:3624
+947:2:3625
+948:2:3633
+949:2:3638
+950:2:3642
+951:2:3643
+952:2:3651
+953:2:3652
+954:2:3656
+955:2:3657
+956:2:3651
+957:2:3652
+958:2:3656
+959:2:3657
+960:2:3665
+961:2:3670
+962:2:3671
+963:2:3682
+964:2:3683
+965:2:3684
+966:2:3695
+967:2:3700
+968:2:3701
+969:2:3712
+970:2:3713
+971:2:3714
+972:2:3712
+973:2:3713
+974:2:3714
+975:2:3725
+976:2:3735
+977:2:3736
+978:0:4648
+979:2:2882
+980:0:4648
+981:2:3742
+982:0:4648
+983:2:4367
+984:2:4368
+985:2:4372
+986:2:4376
+987:2:4377
+988:2:4381
+989:2:4389
+990:2:4390
+991:2:4394
+992:2:4398
+993:2:4399
+994:2:4394
+995:2:4398
+996:2:4399
+997:2:4403
+998:2:4410
+999:2:4417
+1000:2:4418
+1001:2:4425
+1002:2:4430
+1003:2:4437
+1004:2:4438
+1005:2:4437
+1006:2:4438
+1007:2:4445
+1008:2:4449
+1009:0:4648
+1010:2:4454
+1011:0:4648
+1012:2:4455
+1013:0:4648
+1014:2:4456
+1015:0:4648
+1016:2:4457
+1017:0:4648
+1018:1:28
+1019:0:4648
+1020:2:4458
+1021:0:4648
+1022:2:4457
+1023:0:4648
+1024:1:32
+1025:1:33
+1026:1:37
+1027:1:41
+1028:1:42
+1029:1:46
+1030:1:54
+1031:1:55
+1032:1:59
+1033:1:63
+1034:1:64
+1035:1:59
+1036:1:63
+1037:1:64
+1038:1:68
+1039:1:75
+1040:1:82
+1041:1:83
+1042:1:90
+1043:1:95
+1044:1:102
+1045:1:103
+1046:1:102
+1047:1:103
+1048:1:110
+1049:1:114
+1050:0:4648
+1051:2:4458
+1052:0:4648
+1053:2:4457
+1054:0:4648
+1055:1:119
+1056:0:4648
+1057:2:4458
+1058:0:4648
+1059:2:4459
+1060:0:4648
+1061:2:4464
+1062:0:4648
+1063:2:4465
+1064:0:4648
+1065:2:4473
+1066:2:4474
+1067:2:4478
+1068:2:4482
+1069:2:4483
+1070:2:4487
+1071:2:4495
+1072:2:4496
+1073:2:4500
+1074:2:4504
+1075:2:4505
+1076:2:4500
+1077:2:4504
+1078:2:4505
+1079:2:4509
+1080:2:4516
+1081:2:4523
+1082:2:4524
+1083:2:4531
+1084:2:4536
+1085:2:4543
+1086:2:4544
+1087:2:4543
+1088:2:4544
+1089:2:4551
+1090:2:4555
+1091:0:4648
+1092:2:3744
+1093:2:3754
+1094:0:4648
+1095:2:2882
+1096:0:4648
+1097:2:3745
+1098:2:3746
+1099:0:4648
+1100:2:2882
+1101:0:4648
+1102:2:3750
+1103:0:4648
+1104:2:3758
+1105:0:4648
+1106:2:2879
+1107:0:4648
+1108:2:2881
+1109:0:4648
+1110:2:2882
+1111:0:4648
+1112:2:2883
+1113:2:2884
+1114:2:2888
+1115:2:2889
+1116:2:2897
+1117:2:2898
+1118:2:2902
+1119:2:2903
+1120:2:2911
+1121:2:2916
+1122:2:2920
+1123:2:2921
+1124:2:2929
+1125:2:2930
+1126:2:2934
+1127:2:2935
+1128:2:2929
+1129:2:2930
+1130:2:2931
+1131:2:2943
+1132:2:2948
+1133:2:2949
+1134:2:2960
+1135:2:2961
+1136:2:2962
+1137:2:2973
+1138:2:2978
+1139:2:2979
+1140:2:2990
+1141:2:2991
+1142:2:2992
+1143:2:2990
+1144:2:2991
+1145:2:2992
+1146:2:3003
+1147:2:3011
+1148:0:4648
+1149:2:2882
+1150:0:4648
+1151:2:3015
+1152:2:3019
+1153:2:3020
+1154:2:3024
+1155:2:3028
+1156:2:3029
+1157:2:3033
+1158:2:3041
+1159:2:3042
+1160:2:3046
+1161:2:3050
+1162:2:3051
+1163:2:3046
+1164:2:3047
+1165:2:3055
+1166:0:4648
+1167:2:2882
+1168:0:4648
+1169:2:3063
+1170:2:3064
+1171:2:3065
+1172:0:4648
+1173:2:2882
+1174:0:4648
+1175:2:3070
+1176:0:4648
+1177:2:3773
+1178:2:3774
+1179:2:3778
+1180:2:3782
+1181:2:3783
+1182:2:3787
+1183:2:3792
+1184:2:3800
+1185:2:3804
+1186:2:3805
+1187:2:3800
+1188:2:3804
+1189:2:3805
+1190:2:3809
+1191:2:3816
+1192:2:3823
+1193:2:3824
+1194:2:3831
+1195:2:3836
+1196:2:3843
+1197:2:3844
+1198:2:3843
+1199:2:3844
+1200:2:3851
+1201:2:3855
+1202:0:4648
+1203:2:3860
+1204:0:4648
+1205:2:3861
+1206:0:4648
+1207:2:3862
+1208:0:4648
+1209:2:3863
+1210:0:4648
+1211:1:28
+1212:0:4648
+1213:2:3864
+1214:0:4648
+1215:2:3863
+1216:0:4648
+1217:1:32
+1218:1:33
+1219:1:37
+1220:1:41
+1221:1:42
+1222:1:46
+1223:1:54
+1224:1:55
+1225:1:59
+1226:1:63
+1227:1:64
+1228:1:59
+1229:1:63
+1230:1:64
+1231:1:68
+1232:1:75
+1233:1:82
+1234:1:83
+1235:1:90
+1236:1:95
+1237:1:102
+1238:1:103
+1239:1:102
+1240:1:103
+1241:1:110
+1242:1:114
+1243:0:4648
+1244:2:3864
+1245:0:4648
+1246:2:3863
+1247:0:4648
+1248:1:119
+1249:0:4648
+1250:2:3864
+1251:0:4648
+1252:2:3865
+1253:0:4648
+1254:2:3870
+1255:0:4648
+1256:2:3871
+1257:0:4648
+1258:2:3879
+1259:2:3880
+1260:2:3884
+1261:2:3888
+1262:2:3889
+1263:2:3893
+1264:2:3901
+1265:2:3902
+1266:2:3906
+1267:2:3910
+1268:2:3911
+1269:2:3906
+1270:2:3910
+1271:2:3911
+1272:2:3915
+1273:2:3922
+1274:2:3929
+1275:2:3930
+1276:2:3937
+1277:2:3942
+1278:2:3949
+1279:2:3950
+1280:2:3949
+1281:2:3950
+1282:2:3957
+1283:2:3961
+1284:0:4648
+1285:2:3072
+1286:2:3754
+1287:0:4648
+1288:2:2882
+1289:0:4648
+1290:2:3073
+1291:0:4648
+1292:2:2882
+1293:0:4648
+1294:2:3076
+1295:2:3077
+1296:2:3081
+1297:2:3082
+1298:2:3090
+1299:2:3091
+1300:2:3095
+1301:2:3096
+1302:2:3104
+1303:2:3109
+1304:2:3113
+1305:2:3114
+1306:2:3122
+1307:2:3123
+1308:2:3127
+1309:2:3128
+1310:2:3122
+1311:2:3123
+1312:2:3127
+1313:2:3128
+1314:2:3136
+1315:2:3141
+1316:2:3142
+1317:2:3153
+1318:2:3154
+1319:2:3155
+1320:2:3166
+1321:2:3171
+1322:2:3172
+1323:2:3183
+1324:2:3184
+1325:2:3185
+1326:2:3183
+1327:2:3184
+1328:2:3185
+1329:2:3196
+1330:2:3203
+1331:0:4648
+1332:2:2882
+1333:0:4648
+1334:2:3207
+1335:2:3208
+1336:2:3209
+1337:2:3221
+1338:2:3222
+1339:2:3226
+1340:2:3227
+1341:2:3235
+1342:2:3240
+1343:2:3244
+1344:2:3245
+1345:2:3253
+1346:2:3254
+1347:2:3258
+1348:2:3259
+1349:2:3253
+1350:2:3254
+1351:2:3258
+1352:2:3259
+1353:2:3267
+1354:2:3272
+1355:2:3273
+1356:2:3284
+1357:2:3285
+1358:2:3286
+1359:2:3297
+1360:2:3302
+1361:2:3303
+1362:2:3314
+1363:2:3315
+1364:2:3316
+1365:2:3314
+1366:2:3315
+1367:2:3316
+1368:2:3327
+1369:2:3338
+1370:2:3339
+1371:0:4648
+1372:2:2882
+1373:0:4648
+1374:2:3345
+1375:2:3346
+1376:2:3350
+1377:2:3351
+1378:2:3359
+1379:2:3360
+1380:2:3364
+1381:2:3365
+1382:2:3373
+1383:2:3378
+1384:2:3382
+1385:2:3383
+1386:2:3391
+1387:2:3392
+1388:2:3396
+1389:2:3397
+1390:2:3391
+1391:2:3392
+1392:2:3396
+1393:2:3397
+1394:2:3405
+1395:2:3410
+1396:2:3411
+1397:2:3422
+1398:2:3423
+1399:2:3424
+1400:2:3435
+1401:2:3440
+1402:2:3441
+1403:2:3452
+1404:2:3453
+1405:2:3454
+1406:2:3452
+1407:2:3453
+1408:2:3454
+1409:2:3465
+1410:0:4648
+1411:2:2882
+1412:0:4648
+1413:2:3474
+1414:2:3475
+1415:2:3479
+1416:2:3480
+1417:2:3488
+1418:2:3489
+1419:2:3493
+1420:2:3494
+1421:2:3502
+1422:2:3507
+1423:2:3511
+1424:2:3512
+1425:2:3520
+1426:2:3521
+1427:2:3525
+1428:2:3526
+1429:2:3520
+1430:2:3521
+1431:2:3525
+1432:2:3526
+1433:2:3534
+1434:2:3539
+1435:2:3540
+1436:2:3551
+1437:2:3552
+1438:2:3553
+1439:2:3564
+1440:2:3569
+1441:2:3570
+1442:2:3581
+1443:2:3582
+1444:2:3583
+1445:2:3581
+1446:2:3582
+1447:2:3583
+1448:2:3594
+1449:2:3601
+1450:0:4648
+1451:2:2882
+1452:0:4648
+1453:2:3605
+1454:2:3606
+1455:2:3607
+1456:2:3619
+1457:2:3620
+1458:2:3624
+1459:2:3625
+1460:2:3633
+1461:2:3638
+1462:2:3642
+1463:2:3643
+1464:2:3651
+1465:2:3652
+1466:2:3656
+1467:2:3657
+1468:2:3651
+1469:2:3652
+1470:2:3656
+1471:2:3657
+1472:2:3665
+1473:2:3670
+1474:2:3671
+1475:2:3682
+1476:2:3683
+1477:2:3684
+1478:2:3695
+1479:2:3700
+1480:2:3701
+1481:2:3712
+1482:2:3713
+1483:2:3714
+1484:2:3712
+1485:2:3713
+1486:2:3714
+1487:2:3725
+1488:2:3735
+1489:2:3736
+1490:0:4648
+1491:2:2882
+1492:0:4648
+1493:2:3742
+1494:0:4648
+1495:2:4367
+1496:2:4368
+1497:2:4372
+1498:2:4376
+1499:2:4377
+1500:2:4381
+1501:2:4389
+1502:2:4390
+1503:2:4394
+1504:2:4398
+1505:2:4399
+1506:2:4394
+1507:2:4398
+1508:2:4399
+1509:2:4403
+1510:2:4410
+1511:2:4417
+1512:2:4418
+1513:2:4425
+1514:2:4430
+1515:2:4437
+1516:2:4438
+1517:2:4437
+1518:2:4438
+1519:2:4445
+1520:2:4449
+1521:0:4648
+1522:2:4454
+1523:0:4648
+1524:2:4455
+1525:0:4648
+1526:2:4456
+1527:0:4648
+1528:2:4457
+1529:0:4648
+1530:1:28
+1531:0:4648
+1532:2:4458
+1533:0:4648
+1534:2:4457
+1535:0:4648
+1536:1:32
+1537:1:33
+1538:1:37
+1539:1:41
+1540:1:42
+1541:1:46
+1542:1:54
+1543:1:55
+1544:1:59
+1545:1:63
+1546:1:64
+1547:1:59
+1548:1:63
+1549:1:64
+1550:1:68
+1551:1:75
+1552:1:82
+1553:1:83
+1554:1:90
+1555:1:95
+1556:1:102
+1557:1:103
+1558:1:102
+1559:1:103
+1560:1:110
+1561:1:114
+1562:0:4648
+1563:2:4458
+1564:0:4648
+1565:2:4457
+1566:0:4648
+1567:1:119
+1568:0:4648
+1569:2:4458
+1570:0:4648
+1571:2:4459
+1572:0:4648
+1573:2:4464
+1574:0:4648
+1575:2:4465
+1576:0:4648
+1577:2:4473
+1578:2:4474
+1579:2:4478
+1580:2:4482
+1581:2:4483
+1582:2:4487
+1583:2:4495
+1584:2:4496
+1585:2:4500
+1586:2:4504
+1587:2:4505
+1588:2:4500
+1589:2:4504
+1590:2:4505
+1591:2:4509
+1592:2:4516
+1593:2:4523
+1594:2:4524
+1595:2:4531
+1596:2:4536
+1597:2:4543
+1598:2:4544
+1599:2:4543
+1600:2:4544
+1601:2:4551
+1602:2:4555
+1603:0:4648
+1604:2:3744
+1605:2:3754
+1606:0:4648
+1607:2:2882
+1608:0:4648
+1609:2:3745
+1610:2:3746
+1611:0:4648
+1612:2:2882
+1613:0:4648
+1614:2:3750
+1615:0:4648
+1616:2:3758
+1617:0:4648
+1618:2:3759
+1619:0:4648
+1620:2:3764
+1621:0:4648
+1622:1:120
+1623:0:4648
+1624:2:3765
+1625:0:4648
+1626:2:3764
+1627:0:4648
+1628:1:19
+1629:0:4648
+1630:2:3765
+1631:0:4648
+1632:2:3764
+1633:0:4648
+1634:1:127
+1635:1:128
+1636:1:132
+1637:1:133
+1638:1:141
+1639:1:142
+1640:1:146
+1641:1:147
+1642:1:155
+1643:1:160
+1644:1:164
+1645:1:165
+1646:1:173
+1647:1:174
+1648:1:178
+1649:1:179
+1650:1:173
+1651:1:174
+1652:1:178
+1653:1:179
+1654:1:187
+1655:1:192
+1656:1:193
+1657:1:204
+1658:1:205
+1659:1:206
+1660:1:217
+1661:1:222
+1662:1:223
+1663:1:234
+1664:1:235
+1665:1:236
+1666:1:234
+1667:1:235
+1668:1:236
+1669:1:247
+1670:0:4648
+1671:2:3765
+1672:0:4648
+1673:2:3764
+1674:0:4648
+1675:1:15
+1676:0:4648
+1677:2:3765
+1678:0:4648
+1679:2:3764
+1680:0:4648
+1681:1:16
+1682:0:4648
+1683:2:3765
+1684:0:4648
+1685:2:3764
+1686:0:4648
+1687:1:17
+1688:0:4648
+1689:2:3765
+1690:0:4648
+1691:2:3764
+1692:0:4648
+1693:1:120
+1694:0:4648
+1695:2:3765
+1696:0:4648
+1697:2:3764
+1698:0:4648
+1699:1:19
+1700:0:4648
+1701:2:3765
+1702:0:4648
+1703:2:3764
+1704:0:4648
+1705:1:256
+1706:1:257
+1707:0:4648
+1708:2:3765
+1709:0:4648
+1710:2:3764
+1711:0:4648
+1712:1:15
+1713:0:4648
+1714:2:3765
+1715:0:4648
+1716:2:3764
+1717:0:4648
+1718:1:16
+1719:0:4648
+1720:2:3765
+1721:0:4648
+1722:2:3764
+1723:0:4648
+1724:1:17
+1725:0:4648
+1726:2:3765
+1727:0:4648
+1728:2:3764
+1729:0:4648
+1730:1:120
+1731:0:4648
+1732:2:3765
+1733:0:4648
+1734:2:3764
+1735:0:4648
+1736:1:19
+1737:0:4648
+1738:2:3765
+1739:0:4648
+1740:2:3764
+1741:0:4648
+1742:1:263
+1743:1:264
+1744:1:268
+1745:1:269
+1746:1:277
+1747:1:278
+1748:1:282
+1749:1:283
+1750:1:291
+1751:1:296
+1752:1:300
+1753:1:301
+1754:1:309
+1755:1:310
+1756:1:314
+1757:1:315
+1758:1:309
+1759:1:310
+1760:1:314
+1761:1:315
+1762:1:323
+1763:1:328
+1764:1:329
+1765:1:340
+1766:1:341
+1767:1:342
+1768:1:353
+1769:1:358
+1770:1:359
+1771:1:370
+1772:1:371
+1773:1:372
+1774:1:370
+1775:1:371
+1776:1:372
+1777:1:383
+1778:0:4648
+1779:2:3765
+1780:0:4648
+1781:2:3764
+1782:0:4648
+1783:1:15
+1784:0:4648
+1785:2:3765
+1786:0:4648
+1787:2:3764
+1788:0:4648
+1789:1:16
+1790:0:4648
+1791:2:3765
+1792:0:4648
+1793:2:3764
+1794:0:4648
+1795:1:17
+1796:0:4648
+1797:2:3765
+1798:0:4648
+1799:2:3764
+1800:0:4648
+1801:1:120
+1802:0:4648
+1803:2:3765
+1804:0:4648
+1805:2:3764
+1806:0:4648
+1807:1:19
+1808:0:4648
+1809:2:3765
+1810:0:4648
+1811:2:3764
+1812:0:4648
+1813:1:392
+1814:1:393
+1815:1:397
+1816:1:398
+1817:1:406
+1818:1:407
+1819:1:411
+1820:1:412
+1821:1:420
+1822:1:425
+1823:1:429
+1824:1:430
+1825:1:438
+1826:1:439
+1827:1:443
+1828:1:444
+1829:1:438
+1830:1:439
+1831:1:443
+1832:1:444
+1833:1:452
+1834:1:457
+1835:1:458
+1836:1:469
+1837:1:470
+1838:1:471
+1839:1:482
+1840:1:487
+1841:1:488
+1842:1:499
+1843:1:500
+1844:1:501
+1845:1:499
+1846:1:500
+1847:1:501
+1848:1:512
+1849:1:519
+1850:0:4648
+1851:2:3765
+1852:0:4648
+1853:2:3764
+1854:0:4648
+1855:1:15
+1856:0:4648
+1857:2:3765
+1858:0:4648
+1859:2:3764
+1860:0:4648
+1861:1:16
+1862:0:4648
+1863:2:3765
+1864:0:4648
+1865:2:3764
+1866:0:4648
+1867:1:17
+1868:0:4648
+1869:2:3765
+1870:0:4648
+1871:2:3764
+1872:0:4648
+1873:1:120
+1874:0:4648
+1875:2:3765
+1876:0:4648
+1877:2:3764
+1878:0:4648
+1879:1:19
+1880:0:4648
+1881:2:3765
+1882:0:4648
+1883:2:3764
+1884:0:4648
+1885:1:657
+1886:1:658
+1887:1:662
+1888:1:663
+1889:1:671
+1890:1:672
+1891:1:673
+1892:1:685
+1893:1:690
+1894:1:694
+1895:1:695
+1896:1:703
+1897:1:704
+1898:1:708
+1899:1:709
+1900:1:703
+1901:1:704
+1902:1:708
+1903:1:709
+1904:1:717
+1905:1:722
+1906:1:723
+1907:1:734
+1908:1:735
+1909:1:736
+1910:1:747
+1911:1:752
+1912:1:753
+1913:1:764
+1914:1:765
+1915:1:766
+1916:1:764
+1917:1:765
+1918:1:766
+1919:1:777
+1920:0:4648
+1921:2:3765
+1922:0:4648
+1923:2:3764
+1924:0:4648
+1925:1:15
+1926:0:4648
+1927:2:3765
+1928:0:4648
+1929:2:3764
+1930:0:4648
+1931:1:16
+1932:0:4648
+1933:2:3765
+1934:0:4648
+1935:2:3764
+1936:0:4648
+1937:1:17
+1938:0:4648
+1939:2:3765
+1940:0:4648
+1941:2:3764
+1942:0:4648
+1943:1:120
+1944:0:4648
+1945:2:3765
+1946:0:4648
+1947:2:3764
+1948:0:4648
+1949:1:19
+1950:0:4648
+1951:2:3765
+1952:0:4648
+1953:2:3764
+1954:0:4648
+1955:1:786
+1956:1:789
+1957:1:790
+1958:0:4648
+1959:2:3765
+1960:0:4648
+1961:2:3764
+1962:0:4648
+1963:1:15
+1964:0:4648
+1965:2:3765
+1966:0:4648
+1967:2:3764
+1968:0:4648
+1969:1:16
+1970:0:4648
+1971:2:3765
+1972:0:4648
+1973:2:3764
+1974:0:4648
+1975:1:17
+1976:0:4648
+1977:2:3765
+1978:0:4648
+1979:2:3764
+1980:0:4648
+1981:1:120
+1982:0:4648
+1983:2:3765
+1984:0:4648
+1985:2:3764
+1986:0:4648
+1987:1:19
+1988:0:4648
+1989:2:3765
+1990:0:4648
+1991:2:3764
+1992:0:4648
+1993:1:1053
+1994:1:1054
+1995:1:1058
+1996:1:1059
+1997:1:1067
+1998:1:1068
+1999:1:1072
+2000:1:1073
+2001:1:1081
+2002:1:1086
+2003:1:1090
+2004:1:1091
+2005:1:1099
+2006:1:1100
+2007:1:1104
+2008:1:1105
+2009:1:1099
+2010:1:1100
+2011:1:1104
+2012:1:1105
+2013:1:1113
+2014:1:1118
+2015:1:1119
+2016:1:1130
+2017:1:1131
+2018:1:1132
+2019:1:1143
+2020:1:1148
+2021:1:1149
+2022:1:1160
+2023:1:1161
+2024:1:1162
+2025:1:1160
+2026:1:1161
+2027:1:1162
+2028:1:1173
+2029:1:1180
+2030:1:1184
+2031:0:4648
+2032:2:3765
+2033:0:4648
+2034:2:3764
+2035:0:4648
+2036:1:15
+2037:0:4648
+2038:2:3765
+2039:0:4648
+2040:2:3764
+2041:0:4648
+2042:1:16
+2043:0:4648
+2044:2:3765
+2045:0:4648
+2046:2:3764
+2047:0:4648
+2048:1:17
+2049:0:4648
+2050:2:3765
+2051:0:4648
+2052:2:3764
+2053:0:4648
+2054:1:120
+2055:0:4648
+2056:2:3765
+2057:0:4648
+2058:2:3764
+2059:0:4648
+2060:1:19
+2061:0:4648
+2062:2:3765
+2063:0:4648
+2064:2:3764
+2065:0:4648
+2066:1:1185
+2067:1:1186
+2068:1:1190
+2069:1:1191
+2070:1:1199
+2071:1:1200
+2072:1:1201
+2073:1:1213
+2074:1:1218
+2075:1:1222
+2076:1:1223
+2077:1:1231
+2078:1:1232
+2079:1:1236
+2080:1:1237
+2081:1:1231
+2082:1:1232
+2083:1:1236
+2084:1:1237
+2085:1:1245
+2086:1:1250
+2087:1:1251
+2088:1:1262
+2089:1:1263
+2090:1:1264
+2091:1:1275
+2092:1:1280
+2093:1:1281
+2094:1:1292
+2095:1:1293
+2096:1:1294
+2097:1:1292
+2098:1:1293
+2099:1:1294
+2100:1:1305
+2101:0:4648
+2102:2:3765
+2103:0:4648
+2104:2:3764
+2105:0:4648
+2106:1:15
+2107:0:4648
+2108:2:3765
+2109:0:4648
+2110:2:3764
+2111:0:4648
+2112:1:16
+2113:0:4648
+2114:2:3765
+2115:0:4648
+2116:2:3764
+2117:0:4648
+2118:1:17
+2119:0:4648
+2120:2:3765
+2121:0:4648
+2122:2:3764
+2123:0:4648
+2124:1:120
+2125:0:4648
+2126:2:3765
+2127:0:4648
+2128:2:3764
+2129:0:4648
+2130:1:19
+2131:0:4648
+2132:2:3765
+2133:0:4648
+2134:2:3764
+2135:0:4648
+2136:1:1314
+2137:0:4648
+2138:2:3765
+2139:0:4648
+2140:2:3764
+2141:0:4648
+2142:1:2778
+2143:1:2785
+2144:1:2786
+2145:1:2793
+2146:1:2798
+2147:1:2805
+2148:1:2806
+2149:1:2805
+2150:1:2806
+2151:1:2813
+2152:1:2817
+2153:0:4648
+2154:2:3765
+2155:0:4648
+2156:2:3764
+2157:0:4648
+2158:1:1316
+2159:1:1317
+2160:0:4648
+2161:2:3765
+2162:0:4648
+2163:2:3764
+2164:0:4648
+2165:1:15
+2166:0:4648
+2167:2:3765
+2168:0:4648
+2169:2:3764
+2170:0:4648
+2171:1:16
+2172:0:4648
+2173:2:3765
+2174:0:4648
+2175:2:3764
+2176:0:4648
+2177:1:17
+2178:0:4648
+2179:2:3765
+2180:0:4648
+2181:2:3764
+2182:0:4648
+2183:1:120
+2184:0:4648
+2185:2:3765
+2186:0:4648
+2187:2:3764
+2188:0:4648
+2189:1:19
+2190:0:4648
+2191:2:3765
+2192:0:4648
+2193:2:3764
+2194:0:4648
+2195:1:1318
+2196:1:1319
+2197:1:1323
+2198:1:1324
+2199:1:1332
+2200:1:1333
+2201:1:1337
+2202:1:1338
+2203:1:1346
+2204:1:1351
+2205:1:1355
+2206:1:1356
+2207:1:1364
+2208:1:1365
+2209:1:1369
+2210:1:1370
+2211:1:1364
+2212:1:1365
+2213:1:1369
+2214:1:1370
+2215:1:1378
+2216:1:1383
+2217:1:1384
+2218:1:1395
+2219:1:1396
+2220:1:1397
+2221:1:1408
+2222:1:1413
+2223:1:1414
+2224:1:1425
+2225:1:1426
+2226:1:1427
+2227:1:1425
+2228:1:1426
+2229:1:1427
+2230:1:1438
+2231:0:4648
+2232:2:3765
+2233:0:4648
+2234:2:3764
+2235:0:4648
+2236:1:15
+2237:0:4648
+2238:2:3765
+2239:0:4648
+2240:2:3764
+2241:0:4648
+2242:1:16
+2243:0:4648
+2244:2:3765
+2245:0:4648
+2246:2:3764
+2247:0:4648
+2248:1:17
+2249:0:4648
+2250:2:3765
+2251:0:4648
+2252:2:3764
+2253:0:4648
+2254:1:120
+2255:0:4648
+2256:2:3765
+2257:0:4648
+2258:2:3764
+2259:0:4648
+2260:1:19
+2261:0:4648
+2262:2:3765
+2263:0:4648
+2264:2:3764
+2265:0:4648
+2266:1:1447
+2267:1:1448
+2268:1:1452
+2269:1:1453
+2270:1:1461
+2271:1:1462
+2272:1:1466
+2273:1:1467
+2274:1:1475
+2275:1:1480
+2276:1:1484
+2277:1:1485
+2278:1:1493
+2279:1:1494
+2280:1:1498
+2281:1:1499
+2282:1:1493
+2283:1:1494
+2284:1:1498
+2285:1:1499
+2286:1:1507
+2287:1:1512
+2288:1:1513
+2289:1:1524
+2290:1:1525
+2291:1:1526
+2292:1:1537
+2293:1:1542
+2294:1:1543
+2295:1:1554
+2296:1:1555
+2297:1:1556
+2298:1:1554
+2299:1:1555
+2300:1:1556
+2301:1:1567
+2302:1:1574
+2303:1:1578
+2304:0:4648
+2305:2:3765
+2306:0:4648
+2307:2:3764
+2308:0:4648
+2309:1:15
+2310:0:4648
+2311:2:3765
+2312:0:4648
+2313:2:3764
+2314:0:4648
+2315:1:16
+2316:0:4648
+2317:2:3765
+2318:0:4648
+2319:2:3764
+2320:0:4648
+2321:1:17
+2322:0:4648
+2323:2:3765
+2324:0:4648
+2325:2:3764
+2326:0:4648
+2327:1:120
+2328:0:4648
+2329:2:3765
+2330:0:4648
+2331:2:3764
+2332:0:4648
+2333:1:19
+2334:0:4648
+2335:2:3765
+2336:0:4648
+2337:2:3764
+2338:0:4648
+2339:1:1581
+2340:1:1582
+2341:1:1586
+2342:1:1587
+2343:1:1595
+2344:1:1596
+2345:1:1597
+2346:1:1609
+2347:1:1614
+2348:1:1618
+2349:1:1619
+2350:1:1627
+2351:1:1628
+2352:1:1632
+2353:1:1633
+2354:1:1627
+2355:1:1628
+2356:1:1632
+2357:1:1633
+2358:1:1641
+2359:1:1646
+2360:1:1647
+2361:1:1658
+2362:1:1659
+2363:1:1660
+2364:1:1671
+2365:1:1676
+2366:1:1677
+2367:1:1688
+2368:1:1689
+2369:1:1690
+2370:1:1688
+2371:1:1689
+2372:1:1690
+2373:1:1701
+2374:0:4648
+2375:2:3765
+2376:0:4648
+2377:2:3764
+2378:0:4648
+2379:1:15
+2380:0:4648
+2381:2:3765
+2382:0:4648
+2383:2:3764
+2384:0:4648
+2385:1:16
+2386:0:4648
+2387:2:3765
+2388:0:4648
+2389:2:3764
+2390:0:4648
+2391:1:17
+2392:0:4648
+2393:2:3765
+2394:0:4648
+2395:2:3764
+2396:0:4648
+2397:1:120
+2398:0:4648
+2399:2:3765
+2400:0:4648
+2401:2:3764
+2402:0:4648
+2403:1:19
+2404:0:4648
+2405:2:3765
+2406:0:4648
+2407:2:3764
+2408:0:4648
+2409:1:1710
+2410:1:1711
+2411:1:1715
+2412:1:1716
+2413:1:1724
+2414:1:1725
+2415:1:1729
+2416:1:1730
+2417:1:1738
+2418:1:1743
+2419:1:1747
+2420:1:1748
+2421:1:1756
+2422:1:1757
+2423:1:1761
+2424:1:1762
+2425:1:1756
+2426:1:1757
+2427:1:1761
+2428:1:1762
+2429:1:1770
+2430:1:1775
+2431:1:1776
+2432:1:1787
+2433:1:1788
+2434:1:1789
+2435:1:1800
+2436:1:1805
+2437:1:1806
+2438:1:1817
+2439:1:1818
+2440:1:1819
+2441:1:1817
+2442:1:1818
+2443:1:1819
+2444:1:1830
+2445:1:1837
+2446:1:1841
+2447:0:4648
+2448:2:3765
+2449:0:4648
+2450:2:3764
+2451:0:4648
+2452:1:15
+2453:0:4648
+2454:2:3765
+2455:0:4648
+2456:2:3764
+2457:0:4648
+2458:1:16
+2459:0:4648
+2460:2:3765
+2461:0:4648
+2462:2:3764
+2463:0:4648
+2464:1:17
+2465:0:4648
+2466:2:3765
+2467:0:4648
+2468:2:3764
+2469:0:4648
+2470:1:120
+2471:0:4648
+2472:2:3765
+2473:0:4648
+2474:2:3764
+2475:0:4648
+2476:1:19
+2477:0:4648
+2478:2:3765
+2479:0:4648
+2480:2:3764
+2481:0:4648
+2482:1:1842
+2483:1:1843
+2484:1:1847
+2485:1:1848
+2486:1:1856
+2487:1:1857
+2488:1:1858
+2489:1:1870
+2490:1:1875
+2491:1:1879
+2492:1:1880
+2493:1:1888
+2494:1:1889
+2495:1:1893
+2496:1:1894
+2497:1:1888
+2498:1:1889
+2499:1:1893
+2500:1:1894
+2501:1:1902
+2502:1:1907
+2503:1:1908
+2504:1:1919
+2505:1:1920
+2506:1:1921
+2507:1:1932
+2508:1:1937
+2509:1:1938
+2510:1:1949
+2511:1:1950
+2512:1:1951
+2513:1:1949
+2514:1:1950
+2515:1:1951
+2516:1:1962
+2517:0:4648
+2518:2:3765
+2519:0:4648
+2520:2:3764
+2521:0:4648
+2522:1:15
+2523:0:4648
+2524:2:3765
+2525:0:4648
+2526:2:3764
+2527:0:4648
+2528:1:16
+2529:0:4648
+2530:2:3765
+2531:0:4648
+2532:2:3764
+2533:0:4648
+2534:1:17
+2535:0:4648
+2536:2:3765
+2537:0:4648
+2538:2:3764
+2539:0:4648
+2540:1:120
+2541:0:4648
+2542:2:3765
+2543:0:4648
+2544:2:3764
+2545:0:4648
+2546:1:19
+2547:0:4648
+2548:2:3765
+2549:0:4648
+2550:2:3764
+2551:0:4648
+2552:1:1971
+2553:1:1972
+2554:0:4648
+2555:2:3765
+2556:0:4648
+2557:2:3764
+2558:0:4648
+2559:1:15
+2560:0:4648
+2561:2:3765
+2562:0:4648
+2563:2:3764
+2564:0:4648
+2565:1:16
+2566:0:4648
+2567:2:3765
+2568:0:4648
+2569:2:3764
+2570:0:4648
+2571:1:17
+2572:0:4648
+2573:2:3765
+2574:0:4648
+2575:2:3764
+2576:0:4648
+2577:1:120
+2578:0:4648
+2579:2:3765
+2580:0:4648
+2581:2:3764
+2582:0:4648
+2583:1:19
+2584:0:4648
+2585:2:3765
+2586:0:4648
+2587:2:3764
+2588:0:4648
+2589:1:1978
+2590:1:1979
+2591:1:1983
+2592:1:1984
+2593:1:1992
+2594:1:1993
+2595:1:1997
+2596:1:1998
+2597:1:2006
+2598:1:2011
+2599:1:2015
+2600:1:2016
+2601:1:2024
+2602:1:2025
+2603:1:2029
+2604:1:2030
+2605:1:2024
+2606:1:2025
+2607:1:2029
+2608:1:2030
+2609:1:2038
+2610:1:2043
+2611:1:2044
+2612:1:2055
+2613:1:2056
+2614:1:2057
+2615:1:2068
+2616:1:2073
+2617:1:2074
+2618:1:2085
+2619:1:2086
+2620:1:2087
+2621:1:2085
+2622:1:2086
+2623:1:2087
+2624:1:2098
+2625:0:4648
+2626:2:3765
+2627:0:4648
+2628:2:3764
+2629:0:4648
+2630:1:15
+2631:0:4648
+2632:2:3765
+2633:0:4648
+2634:2:3764
+2635:0:4648
+2636:1:16
+2637:0:4648
+2638:2:3765
+2639:0:4648
+2640:2:3764
+2641:0:4648
+2642:1:17
+2643:0:4648
+2644:2:3765
+2645:0:4648
+2646:2:3764
+2647:0:4648
+2648:1:120
+2649:0:4648
+2650:2:3765
+2651:0:4648
+2652:2:3764
+2653:0:4648
+2654:1:19
+2655:0:4648
+2656:2:3765
+2657:0:4648
+2658:2:3764
+2659:0:4648
+2660:1:2107
+2661:1:2108
+2662:1:2112
+2663:1:2113
+2664:1:2121
+2665:1:2122
+2666:1:2126
+2667:1:2127
+2668:1:2135
+2669:1:2140
+2670:1:2144
+2671:1:2145
+2672:1:2153
+2673:1:2154
+2674:1:2158
+2675:1:2159
+2676:1:2153
+2677:1:2154
+2678:1:2158
+2679:1:2159
+2680:1:2167
+2681:1:2172
+2682:1:2173
+2683:1:2184
+2684:1:2185
+2685:1:2186
+2686:1:2197
+2687:1:2202
+2688:1:2203
+2689:1:2214
+2690:1:2215
+2691:1:2216
+2692:1:2214
+2693:1:2215
+2694:1:2216
+2695:1:2227
+2696:1:2234
+2697:0:4648
+2698:2:3765
+2699:0:4648
+2700:2:3764
+2701:0:4648
+2702:1:15
+2703:0:4648
+2704:2:3765
+2705:0:4648
+2706:2:3764
+2707:0:4648
+2708:1:16
+2709:0:4648
+2710:2:3765
+2711:0:4648
+2712:2:3764
+2713:0:4648
+2714:1:17
+2715:0:4648
+2716:2:3765
+2717:0:4648
+2718:2:3764
+2719:0:4648
+2720:1:120
+2721:0:4648
+2722:2:3765
+2723:0:4648
+2724:2:3764
+2725:0:4648
+2726:1:19
+2727:0:4648
+2728:2:3765
+2729:0:4648
+2730:2:3764
+2731:0:4648
+2732:1:2372
+2733:1:2373
+2734:1:2377
+2735:1:2378
+2736:1:2386
+2737:1:2387
+2738:1:2388
+2739:1:2400
+2740:1:2405
+2741:1:2409
+2742:1:2410
+2743:1:2418
+2744:1:2419
+2745:1:2423
+2746:1:2424
+2747:1:2418
+2748:1:2419
+2749:1:2423
+2750:1:2424
+2751:1:2432
+2752:1:2437
+2753:1:2438
+2754:1:2449
+2755:1:2450
+2756:1:2451
+2757:1:2462
+2758:1:2467
+2759:1:2468
+2760:1:2479
+2761:1:2480
+2762:1:2481
+2763:1:2479
+2764:1:2480
+2765:1:2481
+2766:1:2492
+2767:0:4648
+2768:2:3765
+2769:0:4648
+2770:2:3764
+2771:0:4648
+2772:1:15
+2773:0:4648
+2774:2:3765
+2775:0:4648
+2776:2:3764
+2777:0:4648
+2778:1:16
+2779:0:4648
+2780:2:3765
+2781:0:4648
+2782:2:3764
+2783:0:4648
+2784:1:17
+2785:0:4648
+2786:2:3765
+2787:0:4648
+2788:2:3764
+2789:0:4648
+2790:1:120
+2791:0:4648
+2792:2:3765
+2793:0:4648
+2794:2:3764
+2795:0:4648
+2796:1:19
+2797:0:4648
+2798:2:3765
+2799:0:4648
+2800:2:3764
+2801:0:4648
+2802:1:2507
+2803:1:2508
+2804:1:2512
+2805:1:2513
+2806:1:2521
+2807:1:2522
+2808:1:2526
+2809:1:2527
+2810:1:2535
+2811:1:2540
+2812:1:2544
+2813:1:2545
+2814:1:2553
+2815:1:2554
+2816:1:2558
+2817:1:2559
+2818:1:2553
+2819:1:2554
+2820:1:2558
+2821:1:2559
+2822:1:2567
+2823:1:2572
+2824:1:2573
+2825:1:2584
+2826:1:2585
+2827:1:2586
+2828:1:2597
+2829:1:2602
+2830:1:2603
+2831:1:2614
+2832:1:2615
+2833:1:2616
+2834:1:2614
+2835:1:2615
+2836:1:2616
+2837:1:2627
+2838:0:4648
+2839:2:3765
+2840:0:4648
+2841:2:3764
+2842:0:4648
+2843:1:15
+2844:0:4648
+2845:2:3765
+2846:0:4648
+2847:2:3764
+2848:0:4648
+2849:1:16
+2850:0:4648
+2851:2:3765
+2852:0:4648
+2853:2:3764
+2854:0:4648
+2855:1:17
+2856:0:4648
+2857:2:3765
+2858:0:4648
+2859:2:3764
+2860:0:4648
+2861:1:120
+2862:0:4648
+2863:2:3765
+2864:0:4648
+2865:2:3764
+2866:0:4648
+2867:1:19
+2868:0:4648
+2869:2:3765
+2870:0:4648
+2871:2:3764
+2872:0:4648
+2873:1:2636
+2874:1:2637
+2875:1:2641
+2876:1:2642
+2877:1:2650
+2878:1:2651
+2879:1:2655
+2880:1:2656
+2881:1:2664
+2882:1:2669
+2883:1:2673
+2884:1:2674
+2885:1:2682
+2886:1:2683
+2887:1:2687
+2888:1:2688
+2889:1:2682
+2890:1:2683
+2891:1:2687
+2892:1:2688
+2893:1:2696
+2894:1:2701
+2895:1:2702
+2896:1:2713
+2897:1:2714
+2898:1:2715
+2899:1:2726
+2900:1:2731
+2901:1:2732
+2902:1:2743
+2903:1:2744
+2904:1:2745
+2905:1:2743
+2906:1:2744
+2907:1:2745
+2908:1:2756
+2909:1:2763
+2910:1:2767
+2911:0:4648
+2912:2:3765
+2913:0:4648
+2914:2:3764
+2915:0:4648
+2916:1:15
+2917:0:4648
+2918:2:3765
+2919:0:4648
+2920:2:3764
+2921:0:4648
+2922:1:16
+-1:-1:-1
+2923:0:4648
+2924:2:3765
+2925:0:4648
+2926:2:3764
+2927:0:4648
+2928:2:3765
+2929:0:4648
+2930:2:3764
+2931:0:4648
+2932:2:3765
+2933:0:4648
+2934:2:3764
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_writer.define b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_writer.define
new file mode 100644 (file)
index 0000000..1e4417f
--- /dev/null
@@ -0,0 +1 @@
+#define WRITER_PROGRESS
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_writer.log b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_writer.log
new file mode 100644 (file)
index 0000000..09dde01
--- /dev/null
@@ -0,0 +1,677 @@
+make[1]: Entering directory `/home/compudj/doc/userspace-rcu/formal-model/urcu-controldataflow'
+rm -f pan* trail.out .input.spin* *.spin.trail .input.define
+touch .input.define
+cat .input.define > pan.ltl
+cat DEFINES >> pan.ltl
+spin -f "!(`cat urcu_progress.ltl | grep -v ^//`)" >> pan.ltl
+cp urcu_progress_writer.define .input.define
+cat .input.define > .input.spin
+cat DEFINES >> .input.spin
+cat urcu.spin >> .input.spin
+rm -f .input.spin.trail
+spin -a -X -N pan.ltl .input.spin
+Exit-Status 0
+gcc -O2 -w -DHASH64 -o pan pan.c
+./pan -a -f -v -c1 -X -m10000000 -w20
+warning: for p.o. reduction to be valid the never claim must be stutter-invariant
+(never claims generated from LTL formulae are stutter-invariant)
+depth 0: Claim reached state 5 (line 1245)
+depth 23: Claim reached state 9 (line 1250)
+depth 51: Claim reached state 9 (line 1249)
+pan: acceptance cycle (at depth 573)
+pan: wrote .input.spin.trail
+
+(Spin Version 5.1.7 -- 23 December 2008)
+Warning: Search not completed
+       + Partial Order Reduction
+
+Full statespace search for:
+       never claim             +
+       assertion violations    + (if within scope of claim)
+       acceptance   cycles     + (fairness enabled)
+       invalid end states      - (disabled by never claim)
+
+State-vector 88 byte, depth reached 3997, errors: 1
+    24768 states, stored (55970 visited)
+ 10426084 states, matched
+ 10482054 transitions (= visited+matched)
+ 56520057 atomic steps
+hash conflicts:     68749 (resolved)
+
+Stats on memory usage (in Megabytes):
+    2.740      equivalent memory usage for states (stored*(State-vector + overhead))
+    2.770      actual memory usage for states (unsuccessful compression: 101.10%)
+               state-vector as stored = 89 byte + 28 byte overhead
+    8.000      memory used for hash table (-w20)
+  457.764      memory used for DFS stack (-m10000000)
+  468.498      total actual memory usage
+
+unreached in proctype urcu_reader
+       line 647, "pan.___", state 20, "(1)"
+       line 250, "pan.___", state 32, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 54, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 63, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 79, "(1)"
+       line 231, "pan.___", state 87, "(1)"
+       line 235, "pan.___", state 99, "(1)"
+       line 239, "pan.___", state 107, "(1)"
+       line 387, "pan.___", state 133, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 165, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 179, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 198, "(1)"
+       line 413, "pan.___", state 228, "(1)"
+       line 417, "pan.___", state 241, "(1)"
+       line 663, "pan.___", state 262, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<1))"
+       line 387, "pan.___", state 269, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 301, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 315, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 334, "(1)"
+       line 413, "pan.___", state 364, "(1)"
+       line 417, "pan.___", state 377, "(1)"
+       line 387, "pan.___", state 398, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 430, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 444, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 463, "(1)"
+       line 413, "pan.___", state 493, "(1)"
+       line 417, "pan.___", state 506, "(1)"
+       line 387, "pan.___", state 529, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 531, "(1)"
+       line 387, "pan.___", state 532, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 387, "pan.___", state 532, "else"
+       line 387, "pan.___", state 535, "(1)"
+       line 391, "pan.___", state 543, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 545, "(1)"
+       line 391, "pan.___", state 546, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 391, "pan.___", state 546, "else"
+       line 391, "pan.___", state 549, "(1)"
+       line 391, "pan.___", state 550, "(1)"
+       line 391, "pan.___", state 550, "(1)"
+       line 389, "pan.___", state 555, "((i<1))"
+       line 389, "pan.___", state 555, "((i>=1))"
+       line 396, "pan.___", state 561, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 563, "(1)"
+       line 396, "pan.___", state 564, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 564, "else"
+       line 396, "pan.___", state 567, "(1)"
+       line 396, "pan.___", state 568, "(1)"
+       line 396, "pan.___", state 568, "(1)"
+       line 400, "pan.___", state 575, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 577, "(1)"
+       line 400, "pan.___", state 578, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 578, "else"
+       line 400, "pan.___", state 581, "(1)"
+       line 400, "pan.___", state 582, "(1)"
+       line 400, "pan.___", state 582, "(1)"
+       line 398, "pan.___", state 587, "((i<2))"
+       line 398, "pan.___", state 587, "((i>=2))"
+       line 404, "pan.___", state 594, "(1)"
+       line 404, "pan.___", state 595, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 595, "else"
+       line 404, "pan.___", state 598, "(1)"
+       line 404, "pan.___", state 599, "(1)"
+       line 404, "pan.___", state 599, "(1)"
+       line 408, "pan.___", state 607, "(1)"
+       line 408, "pan.___", state 608, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 608, "else"
+       line 408, "pan.___", state 611, "(1)"
+       line 408, "pan.___", state 612, "(1)"
+       line 408, "pan.___", state 612, "(1)"
+       line 406, "pan.___", state 617, "((i<1))"
+       line 406, "pan.___", state 617, "((i>=1))"
+       line 413, "pan.___", state 624, "(1)"
+       line 413, "pan.___", state 625, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 625, "else"
+       line 413, "pan.___", state 628, "(1)"
+       line 413, "pan.___", state 629, "(1)"
+       line 413, "pan.___", state 629, "(1)"
+       line 417, "pan.___", state 637, "(1)"
+       line 417, "pan.___", state 638, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 638, "else"
+       line 417, "pan.___", state 641, "(1)"
+       line 417, "pan.___", state 642, "(1)"
+       line 417, "pan.___", state 642, "(1)"
+       line 415, "pan.___", state 647, "((i<2))"
+       line 415, "pan.___", state 647, "((i>=2))"
+       line 422, "pan.___", state 651, "(1)"
+       line 422, "pan.___", state 651, "(1)"
+       line 663, "pan.___", state 654, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 663, "pan.___", state 655, "_proc_urcu_reader = (_proc_urcu_reader|(1<<5))"
+       line 663, "pan.___", state 656, "(1)"
+       line 387, "pan.___", state 663, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 695, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 709, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 728, "(1)"
+       line 413, "pan.___", state 758, "(1)"
+       line 417, "pan.___", state 771, "(1)"
+       line 387, "pan.___", state 799, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 801, "(1)"
+       line 387, "pan.___", state 802, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 387, "pan.___", state 802, "else"
+       line 387, "pan.___", state 805, "(1)"
+       line 391, "pan.___", state 813, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 815, "(1)"
+       line 391, "pan.___", state 816, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 391, "pan.___", state 816, "else"
+       line 391, "pan.___", state 819, "(1)"
+       line 391, "pan.___", state 820, "(1)"
+       line 391, "pan.___", state 820, "(1)"
+       line 389, "pan.___", state 825, "((i<1))"
+       line 389, "pan.___", state 825, "((i>=1))"
+       line 396, "pan.___", state 831, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 833, "(1)"
+       line 396, "pan.___", state 834, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 834, "else"
+       line 396, "pan.___", state 837, "(1)"
+       line 396, "pan.___", state 838, "(1)"
+       line 396, "pan.___", state 838, "(1)"
+       line 400, "pan.___", state 845, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 847, "(1)"
+       line 400, "pan.___", state 848, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 848, "else"
+       line 400, "pan.___", state 851, "(1)"
+       line 400, "pan.___", state 852, "(1)"
+       line 400, "pan.___", state 852, "(1)"
+       line 398, "pan.___", state 857, "((i<2))"
+       line 398, "pan.___", state 857, "((i>=2))"
+       line 404, "pan.___", state 864, "(1)"
+       line 404, "pan.___", state 865, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 865, "else"
+       line 404, "pan.___", state 868, "(1)"
+       line 404, "pan.___", state 869, "(1)"
+       line 404, "pan.___", state 869, "(1)"
+       line 408, "pan.___", state 877, "(1)"
+       line 408, "pan.___", state 878, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 878, "else"
+       line 408, "pan.___", state 881, "(1)"
+       line 408, "pan.___", state 882, "(1)"
+       line 408, "pan.___", state 882, "(1)"
+       line 406, "pan.___", state 887, "((i<1))"
+       line 406, "pan.___", state 887, "((i>=1))"
+       line 413, "pan.___", state 894, "(1)"
+       line 413, "pan.___", state 895, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 895, "else"
+       line 413, "pan.___", state 898, "(1)"
+       line 413, "pan.___", state 899, "(1)"
+       line 413, "pan.___", state 899, "(1)"
+       line 417, "pan.___", state 907, "(1)"
+       line 417, "pan.___", state 908, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 908, "else"
+       line 417, "pan.___", state 911, "(1)"
+       line 417, "pan.___", state 912, "(1)"
+       line 417, "pan.___", state 912, "(1)"
+       line 422, "pan.___", state 921, "(1)"
+       line 422, "pan.___", state 921, "(1)"
+       line 387, "pan.___", state 928, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 930, "(1)"
+       line 387, "pan.___", state 931, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 387, "pan.___", state 931, "else"
+       line 387, "pan.___", state 934, "(1)"
+       line 391, "pan.___", state 942, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 944, "(1)"
+       line 391, "pan.___", state 945, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 391, "pan.___", state 945, "else"
+       line 391, "pan.___", state 948, "(1)"
+       line 391, "pan.___", state 949, "(1)"
+       line 391, "pan.___", state 949, "(1)"
+       line 389, "pan.___", state 954, "((i<1))"
+       line 389, "pan.___", state 954, "((i>=1))"
+       line 396, "pan.___", state 960, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 962, "(1)"
+       line 396, "pan.___", state 963, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 963, "else"
+       line 396, "pan.___", state 966, "(1)"
+       line 396, "pan.___", state 967, "(1)"
+       line 396, "pan.___", state 967, "(1)"
+       line 400, "pan.___", state 974, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 976, "(1)"
+       line 400, "pan.___", state 977, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 977, "else"
+       line 400, "pan.___", state 980, "(1)"
+       line 400, "pan.___", state 981, "(1)"
+       line 400, "pan.___", state 981, "(1)"
+       line 398, "pan.___", state 986, "((i<2))"
+       line 398, "pan.___", state 986, "((i>=2))"
+       line 404, "pan.___", state 993, "(1)"
+       line 404, "pan.___", state 994, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 994, "else"
+       line 404, "pan.___", state 997, "(1)"
+       line 404, "pan.___", state 998, "(1)"
+       line 404, "pan.___", state 998, "(1)"
+       line 408, "pan.___", state 1006, "(1)"
+       line 408, "pan.___", state 1007, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 1007, "else"
+       line 408, "pan.___", state 1010, "(1)"
+       line 408, "pan.___", state 1011, "(1)"
+       line 408, "pan.___", state 1011, "(1)"
+       line 406, "pan.___", state 1016, "((i<1))"
+       line 406, "pan.___", state 1016, "((i>=1))"
+       line 413, "pan.___", state 1023, "(1)"
+       line 413, "pan.___", state 1024, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 1024, "else"
+       line 413, "pan.___", state 1027, "(1)"
+       line 413, "pan.___", state 1028, "(1)"
+       line 413, "pan.___", state 1028, "(1)"
+       line 417, "pan.___", state 1036, "(1)"
+       line 417, "pan.___", state 1037, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 1037, "else"
+       line 417, "pan.___", state 1040, "(1)"
+       line 417, "pan.___", state 1041, "(1)"
+       line 417, "pan.___", state 1041, "(1)"
+       line 415, "pan.___", state 1046, "((i<2))"
+       line 415, "pan.___", state 1046, "((i>=2))"
+       line 422, "pan.___", state 1050, "(1)"
+       line 422, "pan.___", state 1050, "(1)"
+       line 671, "pan.___", state 1054, "_proc_urcu_reader = (_proc_urcu_reader|(1<<11))"
+       line 387, "pan.___", state 1059, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1091, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1105, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1124, "(1)"
+       line 413, "pan.___", state 1154, "(1)"
+       line 417, "pan.___", state 1167, "(1)"
+       line 387, "pan.___", state 1191, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1223, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1237, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1256, "(1)"
+       line 413, "pan.___", state 1286, "(1)"
+       line 417, "pan.___", state 1299, "(1)"
+       line 387, "pan.___", state 1324, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1356, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1370, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1389, "(1)"
+       line 413, "pan.___", state 1419, "(1)"
+       line 417, "pan.___", state 1432, "(1)"
+       line 387, "pan.___", state 1453, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1485, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1499, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1518, "(1)"
+       line 413, "pan.___", state 1548, "(1)"
+       line 417, "pan.___", state 1561, "(1)"
+       line 387, "pan.___", state 1587, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1619, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1633, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1652, "(1)"
+       line 413, "pan.___", state 1682, "(1)"
+       line 417, "pan.___", state 1695, "(1)"
+       line 387, "pan.___", state 1716, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1748, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1762, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1781, "(1)"
+       line 413, "pan.___", state 1811, "(1)"
+       line 417, "pan.___", state 1824, "(1)"
+       line 387, "pan.___", state 1848, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 1880, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1894, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1913, "(1)"
+       line 413, "pan.___", state 1943, "(1)"
+       line 417, "pan.___", state 1956, "(1)"
+       line 710, "pan.___", state 1977, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<19))"
+       line 387, "pan.___", state 1984, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2016, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2030, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2049, "(1)"
+       line 413, "pan.___", state 2079, "(1)"
+       line 417, "pan.___", state 2092, "(1)"
+       line 387, "pan.___", state 2113, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2145, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2159, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2178, "(1)"
+       line 413, "pan.___", state 2208, "(1)"
+       line 417, "pan.___", state 2221, "(1)"
+       line 387, "pan.___", state 2244, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 2246, "(1)"
+       line 387, "pan.___", state 2247, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 387, "pan.___", state 2247, "else"
+       line 387, "pan.___", state 2250, "(1)"
+       line 391, "pan.___", state 2258, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 2260, "(1)"
+       line 391, "pan.___", state 2261, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 391, "pan.___", state 2261, "else"
+       line 391, "pan.___", state 2264, "(1)"
+       line 391, "pan.___", state 2265, "(1)"
+       line 391, "pan.___", state 2265, "(1)"
+       line 389, "pan.___", state 2270, "((i<1))"
+       line 389, "pan.___", state 2270, "((i>=1))"
+       line 396, "pan.___", state 2276, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2278, "(1)"
+       line 396, "pan.___", state 2279, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 2279, "else"
+       line 396, "pan.___", state 2282, "(1)"
+       line 396, "pan.___", state 2283, "(1)"
+       line 396, "pan.___", state 2283, "(1)"
+       line 400, "pan.___", state 2290, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2292, "(1)"
+       line 400, "pan.___", state 2293, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 2293, "else"
+       line 400, "pan.___", state 2296, "(1)"
+       line 400, "pan.___", state 2297, "(1)"
+       line 400, "pan.___", state 2297, "(1)"
+       line 398, "pan.___", state 2302, "((i<2))"
+       line 398, "pan.___", state 2302, "((i>=2))"
+       line 404, "pan.___", state 2309, "(1)"
+       line 404, "pan.___", state 2310, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 2310, "else"
+       line 404, "pan.___", state 2313, "(1)"
+       line 404, "pan.___", state 2314, "(1)"
+       line 404, "pan.___", state 2314, "(1)"
+       line 408, "pan.___", state 2322, "(1)"
+       line 408, "pan.___", state 2323, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 2323, "else"
+       line 408, "pan.___", state 2326, "(1)"
+       line 408, "pan.___", state 2327, "(1)"
+       line 408, "pan.___", state 2327, "(1)"
+       line 406, "pan.___", state 2332, "((i<1))"
+       line 406, "pan.___", state 2332, "((i>=1))"
+       line 413, "pan.___", state 2339, "(1)"
+       line 413, "pan.___", state 2340, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 2340, "else"
+       line 413, "pan.___", state 2343, "(1)"
+       line 413, "pan.___", state 2344, "(1)"
+       line 413, "pan.___", state 2344, "(1)"
+       line 417, "pan.___", state 2352, "(1)"
+       line 417, "pan.___", state 2353, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 2353, "else"
+       line 417, "pan.___", state 2356, "(1)"
+       line 417, "pan.___", state 2357, "(1)"
+       line 417, "pan.___", state 2357, "(1)"
+       line 415, "pan.___", state 2362, "((i<2))"
+       line 415, "pan.___", state 2362, "((i>=2))"
+       line 422, "pan.___", state 2366, "(1)"
+       line 422, "pan.___", state 2366, "(1)"
+       line 710, "pan.___", state 2369, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 710, "pan.___", state 2370, "_proc_urcu_reader = (_proc_urcu_reader|(1<<23))"
+       line 710, "pan.___", state 2371, "(1)"
+       line 387, "pan.___", state 2378, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2410, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2424, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2443, "(1)"
+       line 413, "pan.___", state 2473, "(1)"
+       line 417, "pan.___", state 2486, "(1)"
+       line 387, "pan.___", state 2513, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2545, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2559, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2578, "(1)"
+       line 413, "pan.___", state 2608, "(1)"
+       line 417, "pan.___", state 2621, "(1)"
+       line 387, "pan.___", state 2642, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2674, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2688, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2707, "(1)"
+       line 413, "pan.___", state 2737, "(1)"
+       line 417, "pan.___", state 2750, "(1)"
+       line 227, "pan.___", state 2783, "(1)"
+       line 235, "pan.___", state 2803, "(1)"
+       line 239, "pan.___", state 2811, "(1)"
+       line 227, "pan.___", state 2826, "(1)"
+       line 235, "pan.___", state 2846, "(1)"
+       line 239, "pan.___", state 2854, "(1)"
+       line 870, "pan.___", state 2871, "-end-"
+       (279 of 2871 states)
+unreached in proctype urcu_writer
+       line 387, "pan.___", state 18, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 387, "pan.___", state 24, "(1)"
+       line 391, "pan.___", state 32, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 38, "(1)"
+       line 391, "pan.___", state 39, "(1)"
+       line 391, "pan.___", state 39, "(1)"
+       line 389, "pan.___", state 44, "((i<1))"
+       line 389, "pan.___", state 44, "((i>=1))"
+       line 396, "pan.___", state 50, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 56, "(1)"
+       line 396, "pan.___", state 57, "(1)"
+       line 396, "pan.___", state 57, "(1)"
+       line 400, "pan.___", state 64, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 70, "(1)"
+       line 400, "pan.___", state 71, "(1)"
+       line 400, "pan.___", state 71, "(1)"
+       line 398, "pan.___", state 76, "((i<2))"
+       line 398, "pan.___", state 76, "((i>=2))"
+       line 404, "pan.___", state 83, "(1)"
+       line 404, "pan.___", state 84, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 404, "pan.___", state 84, "else"
+       line 404, "pan.___", state 87, "(1)"
+       line 404, "pan.___", state 88, "(1)"
+       line 404, "pan.___", state 88, "(1)"
+       line 408, "pan.___", state 96, "(1)"
+       line 408, "pan.___", state 97, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 408, "pan.___", state 97, "else"
+       line 408, "pan.___", state 100, "(1)"
+       line 408, "pan.___", state 101, "(1)"
+       line 408, "pan.___", state 101, "(1)"
+       line 406, "pan.___", state 106, "((i<1))"
+       line 406, "pan.___", state 106, "((i>=1))"
+       line 413, "pan.___", state 113, "(1)"
+       line 413, "pan.___", state 114, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 114, "else"
+       line 413, "pan.___", state 117, "(1)"
+       line 413, "pan.___", state 118, "(1)"
+       line 413, "pan.___", state 118, "(1)"
+       line 417, "pan.___", state 126, "(1)"
+       line 417, "pan.___", state 127, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 127, "else"
+       line 417, "pan.___", state 130, "(1)"
+       line 417, "pan.___", state 131, "(1)"
+       line 417, "pan.___", state 131, "(1)"
+       line 415, "pan.___", state 136, "((i<2))"
+       line 415, "pan.___", state 136, "((i>=2))"
+       line 422, "pan.___", state 140, "(1)"
+       line 422, "pan.___", state 140, "(1)"
+       line 250, "pan.___", state 149, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 158, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 252, "pan.___", state 166, "((i<1))"
+       line 252, "pan.___", state 166, "((i>=1))"
+       line 258, "pan.___", state 171, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 993, "pan.___", state 199, "old_data = cached_rcu_ptr.val[_pid]"
+       line 387, "pan.___", state 211, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 391, "pan.___", state 225, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 243, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 257, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 276, "(1)"
+       line 408, "pan.___", state 289, "(1)"
+       line 413, "pan.___", state 306, "(1)"
+       line 417, "pan.___", state 319, "(1)"
+       line 391, "pan.___", state 356, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 374, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 388, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 420, "(1)"
+       line 413, "pan.___", state 437, "(1)"
+       line 417, "pan.___", state 450, "(1)"
+       line 391, "pan.___", state 494, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 512, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 526, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 558, "(1)"
+       line 413, "pan.___", state 575, "(1)"
+       line 417, "pan.___", state 588, "(1)"
+       line 391, "pan.___", state 623, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 641, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 655, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 687, "(1)"
+       line 413, "pan.___", state 704, "(1)"
+       line 417, "pan.___", state 717, "(1)"
+       line 391, "pan.___", state 754, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 772, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 786, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 818, "(1)"
+       line 413, "pan.___", state 835, "(1)"
+       line 417, "pan.___", state 848, "(1)"
+       line 1113, "pan.___", state 872, "_proc_urcu_writer = (_proc_urcu_writer&~(((1<<12)|(1<<11))))"
+       line 250, "pan.___", state 903, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 912, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 252, "pan.___", state 920, "((i<1))"
+       line 252, "pan.___", state 920, "((i>=1))"
+       line 258, "pan.___", state 927, "(1)"
+       line 258, "pan.___", state 928, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 928, "else"
+       line 262, "pan.___", state 934, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 260, "pan.___", state 942, "((i<2))"
+       line 260, "pan.___", state 942, "((i>=2))"
+       line 227, "pan.___", state 950, "(1)"
+       line 231, "pan.___", state 958, "(1)"
+       line 231, "pan.___", state 959, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 959, "else"
+       line 229, "pan.___", state 964, "((i<1))"
+       line 229, "pan.___", state 964, "((i>=1))"
+       line 235, "pan.___", state 970, "(1)"
+       line 235, "pan.___", state 971, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 971, "else"
+       line 239, "pan.___", state 978, "(1)"
+       line 239, "pan.___", state 979, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 979, "else"
+       line 244, "pan.___", state 988, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 988, "else"
+       line 250, "pan.___", state 1009, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1018, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1031, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1040, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1056, "(1)"
+       line 231, "pan.___", state 1064, "(1)"
+       line 235, "pan.___", state 1076, "(1)"
+       line 239, "pan.___", state 1084, "(1)"
+       line 250, "pan.___", state 1101, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1110, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 252, "pan.___", state 1118, "((i<1))"
+       line 252, "pan.___", state 1118, "((i>=1))"
+       line 258, "pan.___", state 1123, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1132, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 260, "pan.___", state 1140, "((i<2))"
+       line 260, "pan.___", state 1140, "((i>=2))"
+       line 227, "pan.___", state 1148, "(1)"
+       line 231, "pan.___", state 1156, "(1)"
+       line 231, "pan.___", state 1157, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 1157, "else"
+       line 229, "pan.___", state 1162, "((i<1))"
+       line 229, "pan.___", state 1162, "((i>=1))"
+       line 235, "pan.___", state 1168, "(1)"
+       line 235, "pan.___", state 1169, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 1169, "else"
+       line 239, "pan.___", state 1176, "(1)"
+       line 239, "pan.___", state 1177, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 1177, "else"
+       line 244, "pan.___", state 1186, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 1186, "else"
+       line 1180, "pan.___", state 1189, "i = 0"
+       line 1180, "pan.___", state 1191, "reader_barrier = 1"
+       line 1180, "pan.___", state 1202, "((i<1))"
+       line 1180, "pan.___", state 1202, "((i>=1))"
+       line 250, "pan.___", state 1207, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1216, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 252, "pan.___", state 1224, "((i<1))"
+       line 252, "pan.___", state 1224, "((i>=1))"
+       line 258, "pan.___", state 1229, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1238, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 260, "pan.___", state 1246, "((i<2))"
+       line 260, "pan.___", state 1246, "((i>=2))"
+       line 227, "pan.___", state 1254, "(1)"
+       line 231, "pan.___", state 1262, "(1)"
+       line 231, "pan.___", state 1263, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 1263, "else"
+       line 229, "pan.___", state 1268, "((i<1))"
+       line 229, "pan.___", state 1268, "((i>=1))"
+       line 235, "pan.___", state 1274, "(1)"
+       line 235, "pan.___", state 1275, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 1275, "else"
+       line 239, "pan.___", state 1282, "(1)"
+       line 239, "pan.___", state 1283, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 1283, "else"
+       line 244, "pan.___", state 1292, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 1292, "else"
+       line 250, "pan.___", state 1299, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 250, "pan.___", state 1301, "(1)"
+       line 254, "pan.___", state 1308, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1310, "(1)"
+       line 254, "pan.___", state 1311, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 254, "pan.___", state 1311, "else"
+       line 252, "pan.___", state 1316, "((i<1))"
+       line 252, "pan.___", state 1316, "((i>=1))"
+       line 258, "pan.___", state 1321, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1323, "(1)"
+       line 258, "pan.___", state 1324, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 1324, "else"
+       line 262, "pan.___", state 1330, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1332, "(1)"
+       line 262, "pan.___", state 1333, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 262, "pan.___", state 1333, "else"
+       line 260, "pan.___", state 1338, "((i<2))"
+       line 260, "pan.___", state 1338, "((i>=2))"
+       line 227, "pan.___", state 1346, "(1)"
+       line 231, "pan.___", state 1354, "(1)"
+       line 231, "pan.___", state 1355, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 1355, "else"
+       line 229, "pan.___", state 1360, "((i<1))"
+       line 229, "pan.___", state 1360, "((i>=1))"
+       line 235, "pan.___", state 1366, "(1)"
+       line 235, "pan.___", state 1367, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 1367, "else"
+       line 239, "pan.___", state 1374, "(1)"
+       line 239, "pan.___", state 1375, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 1375, "else"
+       line 244, "pan.___", state 1384, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 1384, "else"
+       line 1183, "pan.___", state 1387, "i = 0"
+       line 1183, "pan.___", state 1389, "reader_barrier = 1"
+       line 1183, "pan.___", state 1400, "((i<1))"
+       line 1183, "pan.___", state 1400, "((i>=1))"
+       line 250, "pan.___", state 1405, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 250, "pan.___", state 1407, "(1)"
+       line 254, "pan.___", state 1414, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1416, "(1)"
+       line 254, "pan.___", state 1417, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 254, "pan.___", state 1417, "else"
+       line 252, "pan.___", state 1422, "((i<1))"
+       line 252, "pan.___", state 1422, "((i>=1))"
+       line 258, "pan.___", state 1427, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1429, "(1)"
+       line 258, "pan.___", state 1430, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 1430, "else"
+       line 262, "pan.___", state 1436, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1438, "(1)"
+       line 262, "pan.___", state 1439, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 262, "pan.___", state 1439, "else"
+       line 260, "pan.___", state 1444, "((i<2))"
+       line 260, "pan.___", state 1444, "((i>=2))"
+       line 227, "pan.___", state 1452, "(1)"
+       line 231, "pan.___", state 1460, "(1)"
+       line 231, "pan.___", state 1461, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 1461, "else"
+       line 229, "pan.___", state 1466, "((i<1))"
+       line 229, "pan.___", state 1466, "((i>=1))"
+       line 235, "pan.___", state 1472, "(1)"
+       line 235, "pan.___", state 1473, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 1473, "else"
+       line 239, "pan.___", state 1480, "(1)"
+       line 239, "pan.___", state 1481, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 1481, "else"
+       line 244, "pan.___", state 1490, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 1490, "else"
+       line 277, "pan.___", state 1492, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 277, "pan.___", state 1492, "else"
+       line 1183, "pan.___", state 1493, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 1183, "pan.___", state 1493, "else"
+       line 254, "pan.___", state 1506, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1519, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1528, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1544, "(1)"
+       line 231, "pan.___", state 1552, "(1)"
+       line 235, "pan.___", state 1564, "(1)"
+       line 239, "pan.___", state 1572, "(1)"
+       line 250, "pan.___", state 1603, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1612, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1625, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1634, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1650, "(1)"
+       line 231, "pan.___", state 1658, "(1)"
+       line 235, "pan.___", state 1670, "(1)"
+       line 239, "pan.___", state 1678, "(1)"
+       line 1191, "pan.___", state 1694, "-end-"
+       (192 of 1694 states)
+unreached in proctype :init:
+       (0 of 78 states)
+unreached in proctype :never:
+       line 1252, "pan.___", state 11, "-end-"
+       (1 of 11 states)
+
+pan: elapsed time 13.7 seconds
+pan: rate 4094.3672 states/second
+pan: avg transition delay 1.3041e-06 usec
+cp .input.spin urcu_progress_writer.spin.input
+cp .input.spin.trail urcu_progress_writer.spin.input.trail
+make[1]: Leaving directory `/home/compudj/doc/userspace-rcu/formal-model/urcu-controldataflow'
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_writer.spin.input b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_writer.spin.input
new file mode 100644 (file)
index 0000000..f1dd6fb
--- /dev/null
@@ -0,0 +1,1227 @@
+#define WRITER_PROGRESS
+
+// Poison value for freed memory
+#define POISON 1
+// Memory with correct data
+#define WINE 0
+#define SLAB_SIZE 2
+
+#define read_poison    (data_read_first[0] == POISON || data_read_second[0] == POISON)
+
+#define RCU_GP_CTR_BIT (1 << 7)
+#define RCU_GP_CTR_NEST_MASK (RCU_GP_CTR_BIT - 1)
+
+//disabled
+#define REMOTE_BARRIERS
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+typedef per_proc_bit {
+       bit val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bitfield {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bitfield cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               smp_mb(i, j);
+               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
+               break;
+       od;
+}
+
+#ifdef WRITER_PROGRESS
+//#define PROGRESS_LABEL(progressid)   progress_writer_progid_##progressid:
+#define PROGRESS_LABEL(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;                                          \
+               /*                                                              \
+                * 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)                                                     \
+               do                                                              \
+               :: (reader_barrier[i] == 1) -> skip;                            \
+               :: (reader_barrier[i] == 0) -> break;                           \
+               od;                                                             \
+               i++;                                                            \
+       :: i >= NR_READERS ->                                                   \
+               break                                                           \
+       od;                                                                     \
+       smp_mb(i, j);                                                           \
+}
+
+#else
+
+#define smp_mb_send(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, smp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only one reader */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* RCU data */
+DECLARE_CACHED_VAR(bit, rcu_data[SLAB_SIZE]);
+
+/* RCU pointer */
+#if (SLAB_SIZE == 2)
+DECLARE_CACHED_VAR(bit, rcu_ptr);
+bit ptr_read_first[NR_READERS];
+bit ptr_read_second[NR_READERS];
+#else
+DECLARE_CACHED_VAR(byte, rcu_ptr);
+byte ptr_read_first[NR_READERS];
+byte ptr_read_second[NR_READERS];
+#endif
+
+bit data_read_first[NR_READERS];
+bit data_read_second[NR_READERS];
+
+bit init_done = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               :: 1 -> skip;
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               ptr_read_first[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb1;
+rmb1_end:
+                               data_read_first[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_first[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               ptr_read_second[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb2;
+rmb2_end:
+                               data_read_second[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_second[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+rmb1:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb1_end;
+rmb2:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_DATA                     (1 << 1)
+#define WRITE_PROC_WMB                 (1 << 2)
+#define WRITE_XCHG_PTR                 (1 << 3)
+
+#define WRITE_PROC_FIRST_MB            (1 << 4)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 5)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 6)
+#define WRITE_PROC_FIRST_WAIT          (1 << 7)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 8)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 9)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 10)
+#define WRITE_PROC_SECOND_WAIT         (1 << 11)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 12)
+
+#define WRITE_PROC_SECOND_MB           (1 << 13)
+
+#define WRITE_FREE                     (1 << 14)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_DATA                    \
+                                       | WRITE_PROC_WMB                \
+                                       | WRITE_XCHG_PTR                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB          \
+                                       | WRITE_FREE)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 15) - 1)
+
+/*
+ * Mutexes are implied around writer execution. A single writer at a time.
+ */
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte cur_data = 0, old_data, loop_nr = 0;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (loop_nr < 3) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               loop_nr = loop_nr + 1;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_WMB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+#endif
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_DATA) ->
+                       ooo_mem(i);
+                       cur_data = (cur_data + 1) % SLAB_SIZE;
+                       WRITE_CACHED_VAR(rcu_data[cur_data], WINE);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_DATA);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA,
+                                 WRITE_PROC_WMB) ->
+                       smp_wmb(i, j);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_WMB,
+                                 WRITE_XCHG_PTR) ->
+                       /* rcu_xchg_pointer() */
+                       atomic {
+                               old_data = READ_CACHED_VAR(rcu_ptr);
+                               WRITE_CACHED_VAR(rcu_ptr, cur_data);
+                       }
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_XCHG_PTR);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_WMB      /* No dependency on
+                                                        * WRITE_DATA because we
+                                                        * write to a
+                                                        * different location. */
+                                 | WRITE_PROC_SECOND_MB
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_FREE) ->
+                       WRITE_CACHED_VAR(rcu_data[old_data], POISON);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_FREE);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+               /*
+                * Note : Promela model adds implicit serialization of the
+                * WRITE_FREE instruction. Normally, it would be permitted to
+                * spill on the next loop execution. Given the validation we do
+                * checks for the data entry read to be poisoned, it's ok if
+                * we do not check "late arriving" memory poisoning.
+                */
+       :: 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
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(rcu_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       ptr_read_first[i] = 1;
+                       ptr_read_second[i] = 1;
+                       data_read_first[i] = WINE;
+                       data_read_second[i] = WINE;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               INIT_CACHED_VAR(rcu_data[0], WINE, j);
+               i = 1;
+               do
+               :: i < SLAB_SIZE ->
+                       INIT_CACHED_VAR(rcu_data[i], POISON, j);
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_writer.spin.input.trail b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_writer.spin.input.trail
new file mode 100644 (file)
index 0000000..e8b02f0
--- /dev/null
@@ -0,0 +1,884 @@
+-2:3:-2
+-4:-4:-4
+1:0:4645
+2:3:4565
+3:3:4568
+4:3:4568
+5:3:4571
+6:3:4579
+7:3:4579
+8:3:4582
+9:3:4588
+10:3:4592
+11:3:4592
+12:3:4595
+13:3:4605
+14:3:4613
+15:3:4613
+16:3:4616
+17:3:4622
+18:3:4626
+19:3:4626
+20:3:4629
+21:3:4635
+22:3:4639
+23:3:4640
+24:0:4645
+25:3:4642
+26:0:4645
+27:2:2873
+28:0:4645
+29:2:2879
+30:0:4645
+31:2:2880
+32:0:4645
+33:2:2881
+34:0:4643
+35:2:2882
+36:0:4649
+37:2:2883
+38:0:4649
+39:2:2884
+40:2:2885
+41:2:2889
+42:2:2890
+43:2:2898
+44:2:2899
+45:2:2903
+46:2:2904
+47:2:2912
+48:2:2917
+49:2:2921
+50:2:2922
+51:2:2930
+52:2:2931
+53:2:2935
+54:2:2936
+55:2:2930
+56:2:2931
+57:2:2935
+58:2:2936
+59:2:2944
+60:2:2949
+61:2:2950
+62:2:2961
+63:2:2962
+64:2:2963
+65:2:2974
+66:2:2979
+67:2:2980
+68:2:2991
+69:2:2992
+70:2:2993
+71:2:2991
+72:2:2992
+73:2:2993
+74:2:3004
+75:2:3012
+76:0:4649
+77:2:2883
+78:0:4649
+79:2:3016
+80:2:3020
+81:2:3021
+82:2:3025
+83:2:3029
+84:2:3030
+85:2:3034
+86:2:3042
+87:2:3043
+88:2:3047
+89:2:3051
+90:2:3052
+91:2:3047
+92:2:3048
+93:2:3056
+94:0:4649
+95:2:2883
+96:0:4649
+97:2:3064
+98:2:3065
+99:2:3066
+100:0:4649
+101:2:2883
+102:0:4649
+103:2:3071
+104:0:4649
+105:2:3774
+106:2:3775
+107:2:3779
+108:2:3783
+109:2:3784
+110:2:3788
+111:2:3793
+112:2:3801
+113:2:3805
+114:2:3806
+115:2:3801
+116:2:3805
+117:2:3806
+118:2:3810
+119:2:3817
+120:2:3824
+121:2:3825
+122:2:3832
+123:2:3837
+124:2:3844
+125:2:3845
+126:2:3844
+127:2:3845
+128:2:3852
+129:2:3856
+130:0:4649
+131:2:3861
+132:0:4649
+133:2:3862
+134:0:4649
+135:2:3863
+136:0:4649
+137:2:3864
+138:0:4649
+139:1:2
+140:0:4649
+141:2:3865
+142:0:4649
+143:1:8
+144:0:4649
+145:1:9
+146:0:4649
+147:2:3864
+148:0:4649
+149:2:3865
+150:0:4649
+151:1:10
+152:0:4649
+153:2:3864
+154:0:4649
+155:2:3865
+156:0:4649
+157:1:11
+158:0:4649
+159:2:3864
+160:0:4649
+161:2:3865
+162:0:4649
+163:1:12
+164:0:4649
+165:2:3864
+166:0:4649
+167:2:3865
+168:0:4649
+169:1:13
+170:0:4649
+171:2:3864
+172:0:4649
+173:2:3865
+174:0:4649
+175:1:14
+176:0:4649
+177:1:15
+178:0:4649
+179:1:23
+180:0:4649
+181:1:24
+182:0:4649
+183:2:3864
+184:0:4649
+185:2:3865
+186:0:4649
+187:1:128
+188:1:129
+189:1:133
+190:1:134
+191:1:142
+192:1:143
+193:1:147
+194:1:148
+195:1:156
+196:1:161
+197:1:165
+198:1:166
+199:1:174
+200:1:175
+201:1:179
+202:1:180
+203:1:174
+204:1:175
+205:1:179
+206:1:180
+207:1:188
+208:1:193
+209:1:194
+210:1:205
+211:1:206
+212:1:207
+213:1:218
+214:1:223
+215:1:224
+216:1:235
+217:1:236
+218:1:237
+219:1:235
+220:1:236
+221:1:237
+222:1:248
+223:0:4649
+224:1:15
+225:0:4649
+226:1:23
+227:0:4649
+228:1:24
+229:0:4649
+230:2:3864
+231:0:4649
+232:2:3865
+233:0:4649
+234:1:257
+235:1:258
+236:0:4649
+237:1:15
+238:0:4649
+239:1:23
+240:0:4649
+241:1:24
+242:0:4649
+243:2:3864
+244:0:4649
+245:2:3865
+246:0:4649
+247:1:264
+248:1:265
+249:1:269
+250:1:270
+251:1:278
+252:1:279
+253:1:283
+254:1:284
+255:1:292
+256:1:297
+257:1:301
+258:1:302
+259:1:310
+260:1:311
+261:1:315
+262:1:316
+263:1:310
+264:1:311
+265:1:315
+266:1:316
+267:1:324
+268:1:329
+269:1:330
+270:1:341
+271:1:342
+272:1:343
+273:1:354
+274:1:359
+275:1:360
+276:1:371
+277:1:372
+278:1:373
+279:1:371
+280:1:372
+281:1:373
+282:1:384
+283:0:4649
+284:1:15
+285:0:4649
+286:1:23
+287:0:4649
+288:1:24
+289:0:4649
+290:2:3864
+291:0:4649
+292:2:3865
+293:0:4649
+294:1:393
+295:1:394
+296:1:398
+297:1:399
+298:1:407
+299:1:408
+300:1:412
+301:1:413
+302:1:421
+303:1:426
+304:1:430
+305:1:431
+306:1:439
+307:1:440
+308:1:444
+309:1:445
+310:1:439
+311:1:440
+312:1:444
+313:1:445
+314:1:453
+315:1:458
+316:1:459
+317:1:470
+318:1:471
+319:1:472
+320:1:483
+321:1:488
+322:1:489
+323:1:500
+324:1:501
+325:1:502
+326:1:500
+327:1:501
+328:1:502
+329:1:513
+330:1:520
+331:0:4649
+332:1:15
+333:0:4649
+334:1:16
+335:0:4649
+336:2:3864
+337:0:4649
+338:2:3865
+339:0:4649
+340:1:17
+341:0:4649
+342:2:3864
+343:0:4649
+344:2:3865
+345:0:4649
+346:1:28
+347:0:4649
+348:2:3864
+349:0:4649
+350:2:3865
+351:0:4649
+352:1:32
+353:1:33
+354:1:37
+355:1:38
+356:1:46
+357:1:54
+358:1:55
+359:1:59
+360:1:63
+361:1:64
+362:1:59
+363:1:63
+364:1:64
+365:1:68
+366:1:75
+367:1:82
+368:1:83
+369:1:90
+370:1:95
+371:1:102
+372:1:103
+373:1:102
+374:1:103
+375:1:110
+376:1:114
+377:0:4649
+378:2:3864
+379:0:4649
+380:2:3865
+381:0:4649
+382:1:119
+383:0:4649
+384:2:3866
+385:0:4649
+386:2:3871
+387:0:4649
+388:2:3872
+389:0:4649
+390:2:3880
+391:2:3881
+392:2:3885
+393:2:3889
+394:2:3890
+395:2:3894
+396:2:3902
+397:2:3903
+398:2:3907
+399:2:3911
+400:2:3912
+401:2:3907
+402:2:3911
+403:2:3912
+404:2:3916
+405:2:3923
+406:2:3930
+407:2:3931
+408:2:3938
+409:2:3943
+410:2:3950
+411:2:3951
+412:2:3950
+413:2:3951
+414:2:3958
+415:2:3962
+416:0:4649
+417:2:3073
+418:2:3755
+419:0:4649
+420:2:2883
+421:0:4649
+422:2:3074
+423:0:4649
+424:2:2883
+425:0:4649
+426:2:3077
+427:2:3078
+428:2:3082
+429:2:3083
+430:2:3091
+431:2:3092
+432:2:3096
+433:2:3097
+434:2:3105
+435:2:3110
+436:2:3114
+437:2:3115
+438:2:3123
+439:2:3124
+440:2:3128
+441:2:3129
+442:2:3123
+443:2:3124
+444:2:3128
+445:2:3129
+446:2:3137
+447:2:3142
+448:2:3143
+449:2:3154
+450:2:3155
+451:2:3156
+452:2:3167
+453:2:3172
+454:2:3173
+455:2:3184
+456:2:3185
+457:2:3186
+458:2:3184
+459:2:3185
+460:2:3186
+461:2:3197
+462:2:3204
+463:0:4649
+464:2:2883
+465:0:4649
+466:2:3208
+467:2:3209
+468:2:3210
+469:2:3222
+470:2:3223
+471:2:3227
+472:2:3228
+473:2:3236
+474:2:3241
+475:2:3245
+476:2:3246
+477:2:3254
+478:2:3255
+479:2:3259
+480:2:3260
+481:2:3254
+482:2:3255
+483:2:3259
+484:2:3260
+485:2:3268
+486:2:3273
+487:2:3274
+488:2:3285
+489:2:3286
+490:2:3287
+491:2:3298
+492:2:3303
+493:2:3304
+494:2:3315
+495:2:3316
+496:2:3317
+497:2:3315
+498:2:3316
+499:2:3317
+500:2:3328
+501:2:3337
+502:0:4649
+503:2:2883
+504:0:4649
+505:2:3343
+506:0:4649
+507:2:3972
+508:2:3973
+509:2:3977
+510:2:3981
+511:2:3982
+512:2:3986
+513:2:3994
+514:2:3995
+515:2:3999
+516:2:4003
+517:2:4004
+518:2:3999
+519:2:4003
+520:2:4004
+521:2:4008
+522:2:4015
+523:2:4022
+524:2:4023
+525:2:4030
+526:2:4035
+527:2:4042
+528:2:4043
+529:2:4042
+530:2:4043
+531:2:4050
+532:2:4054
+533:0:4649
+534:2:4059
+535:0:4649
+536:2:4060
+537:0:4649
+538:2:4061
+539:0:4649
+540:2:4062
+541:0:4649
+542:1:28
+543:0:4649
+544:2:4063
+545:0:4649
+546:2:4062
+547:0:4649
+548:1:32
+549:1:33
+550:1:37
+551:1:41
+552:1:42
+553:1:46
+554:1:54
+555:1:55
+556:1:59
+557:1:63
+558:1:64
+559:1:59
+560:1:63
+561:1:64
+562:1:68
+563:1:75
+564:1:82
+565:1:83
+566:1:90
+567:1:95
+568:1:102
+569:1:103
+570:1:102
+571:1:103
+572:1:110
+573:1:114
+-1:-1:-1
+574:0:4649
+575:2:4063
+576:0:4649
+577:2:4062
+578:0:4649
+579:1:119
+580:0:4649
+581:2:4063
+582:0:4649
+583:2:4064
+584:0:4649
+585:2:4069
+586:0:4649
+587:2:4070
+588:0:4649
+589:2:4078
+590:2:4079
+591:2:4083
+592:2:4087
+593:2:4088
+594:2:4092
+595:2:4100
+596:2:4101
+597:2:4105
+598:2:4109
+599:2:4110
+600:2:4105
+601:2:4109
+602:2:4110
+603:2:4114
+604:2:4121
+605:2:4128
+606:2:4129
+607:2:4136
+608:2:4141
+609:2:4148
+610:2:4149
+611:2:4148
+612:2:4149
+613:2:4156
+614:2:4160
+615:0:4649
+616:2:3345
+617:2:3755
+618:0:4649
+619:2:2883
+620:0:4649
+621:2:3208
+622:2:3209
+623:2:3213
+624:2:3214
+625:2:3222
+626:2:3223
+627:2:3227
+628:2:3228
+629:2:3236
+630:2:3241
+631:2:3245
+632:2:3246
+633:2:3254
+634:2:3255
+635:2:3259
+636:2:3260
+637:2:3254
+638:2:3255
+639:2:3259
+640:2:3260
+641:2:3268
+642:2:3273
+643:2:3274
+644:2:3285
+645:2:3286
+646:2:3287
+647:2:3298
+648:2:3303
+649:2:3304
+650:2:3315
+651:2:3316
+652:2:3317
+653:2:3315
+654:2:3316
+655:2:3317
+656:2:3328
+657:2:3337
+658:0:4649
+659:2:2883
+660:0:4649
+661:2:3343
+662:0:4649
+663:2:3972
+664:2:3973
+665:2:3977
+666:2:3981
+667:2:3982
+668:2:3986
+669:2:3994
+670:2:3995
+671:2:3999
+672:2:4003
+673:2:4004
+674:2:3999
+675:2:4003
+676:2:4004
+677:2:4008
+678:2:4015
+679:2:4022
+680:2:4023
+681:2:4030
+682:2:4035
+683:2:4042
+684:2:4043
+685:2:4042
+686:2:4043
+687:2:4050
+688:2:4054
+689:0:4649
+690:2:4059
+691:0:4649
+692:2:4060
+693:0:4649
+694:2:4061
+695:0:4649
+696:2:4062
+697:0:4649
+698:1:28
+699:0:4649
+700:2:4063
+701:0:4649
+702:1:32
+703:1:33
+704:1:37
+705:1:41
+706:1:42
+707:1:46
+708:1:54
+709:1:55
+710:1:59
+711:1:63
+712:1:64
+713:1:59
+714:1:63
+715:1:64
+716:1:68
+717:1:75
+718:1:82
+719:1:83
+720:1:90
+721:1:95
+722:1:102
+723:1:103
+724:1:102
+725:1:103
+726:1:110
+727:1:114
+728:0:4649
+729:2:4062
+730:0:4649
+731:2:4063
+732:0:4649
+733:1:119
+734:0:4649
+735:2:4064
+736:0:4649
+737:2:4069
+738:0:4649
+739:2:4070
+740:0:4649
+741:2:4078
+742:2:4079
+743:2:4083
+744:2:4087
+745:2:4088
+746:2:4092
+747:2:4100
+748:2:4101
+749:2:4105
+750:2:4109
+751:2:4110
+752:2:4105
+753:2:4109
+754:2:4110
+755:2:4114
+756:2:4121
+757:2:4128
+758:2:4129
+759:2:4136
+760:2:4141
+761:2:4148
+762:2:4149
+763:2:4148
+764:2:4149
+765:2:4156
+766:2:4160
+767:0:4649
+768:2:3345
+769:2:3755
+770:0:4649
+771:2:2883
+772:0:4649
+773:2:3208
+774:2:3209
+775:2:3213
+776:2:3214
+777:2:3222
+778:2:3223
+779:2:3227
+780:2:3228
+781:2:3236
+782:2:3241
+783:2:3245
+784:2:3246
+785:2:3254
+786:2:3255
+787:2:3259
+788:2:3260
+789:2:3254
+790:2:3255
+791:2:3259
+792:2:3260
+793:2:3268
+794:2:3273
+795:2:3274
+796:2:3285
+797:2:3286
+798:2:3287
+799:2:3298
+800:2:3303
+801:2:3304
+802:2:3315
+803:2:3316
+804:2:3317
+805:2:3315
+806:2:3316
+807:2:3317
+808:2:3328
+809:2:3337
+810:0:4649
+811:2:2883
+812:0:4649
+813:2:3343
+814:0:4649
+815:2:3972
+816:2:3973
+817:2:3977
+818:2:3981
+819:2:3982
+820:2:3986
+821:2:3994
+822:2:3995
+823:2:3999
+824:2:4003
+825:2:4004
+826:2:3999
+827:2:4003
+828:2:4004
+829:2:4008
+830:2:4015
+831:2:4022
+832:2:4023
+833:2:4030
+834:2:4035
+835:2:4042
+836:2:4043
+837:2:4042
+838:2:4043
+839:2:4050
+840:2:4054
+841:0:4649
+842:2:4059
+843:0:4649
+844:2:4060
+845:0:4649
+846:2:4061
+847:0:4649
+848:2:4062
+849:0:4649
+850:1:28
+851:0:4649
+852:2:4063
+853:0:4649
+854:2:4062
+855:0:4649
+856:1:32
+857:1:33
+858:1:37
+859:1:41
+860:1:42
+861:1:46
+862:1:54
+863:1:55
+864:1:59
+865:1:63
+866:1:64
+867:1:59
+868:1:63
+869:1:64
+870:1:68
+871:1:75
+872:1:82
+873:1:83
+874:1:90
+875:1:95
+876:1:102
+877:1:103
+878:1:102
+879:1:103
+880:1:110
+881:1:114
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_writer_error.define b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_writer_error.define
new file mode 100644 (file)
index 0000000..8d304f5
--- /dev/null
@@ -0,0 +1,2 @@
+#define WRITER_PROGRESS
+#define GEN_ERROR_WRITER_PROGRESS
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_writer_error.log b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_writer_error.log
new file mode 100644 (file)
index 0000000..d6f24ba
--- /dev/null
@@ -0,0 +1,620 @@
+make[1]: Entering directory `/home/compudj/doc/userspace-rcu/formal-model/urcu-controldataflow'
+rm -f pan* trail.out .input.spin* *.spin.trail .input.define
+touch .input.define
+cat .input.define > pan.ltl
+cat DEFINES >> pan.ltl
+spin -f "!(`cat urcu_progress.ltl | grep -v ^//`)" >> pan.ltl
+cp urcu_progress_writer_error.define .input.define
+cat .input.define > .input.spin
+cat DEFINES >> .input.spin
+cat urcu.spin >> .input.spin
+rm -f .input.spin.trail
+spin -a -X -N pan.ltl .input.spin
+Exit-Status 0
+gcc -O2 -w -DHASH64 -o pan pan.c
+./pan -a -f -v -c1 -X -m10000000 -w20
+warning: for p.o. reduction to be valid the never claim must be stutter-invariant
+(never claims generated from LTL formulae are stutter-invariant)
+depth 0: Claim reached state 5 (line 1246)
+depth 23: Claim reached state 9 (line 1251)
+depth 51: Claim reached state 9 (line 1250)
+pan: acceptance cycle (at depth 1200)
+pan: wrote .input.spin.trail
+
+(Spin Version 5.1.7 -- 23 December 2008)
+Warning: Search not completed
+       + Partial Order Reduction
+
+Full statespace search for:
+       never claim             +
+       assertion violations    + (if within scope of claim)
+       acceptance   cycles     + (fairness enabled)
+       invalid end states      - (disabled by never claim)
+
+State-vector 88 byte, depth reached 3997, errors: 1
+    26291 states, stored (59381 visited)
+ 11000989 states, matched
+ 11060370 transitions (= visited+matched)
+ 60052117 atomic steps
+hash conflicts:     84608 (resolved)
+
+Stats on memory usage (in Megabytes):
+    2.908      equivalent memory usage for states (stored*(State-vector + overhead))
+    2.889      actual memory usage for states (compression: 99.33%)
+               state-vector as stored = 87 byte + 28 byte overhead
+    8.000      memory used for hash table (-w20)
+  457.764      memory used for DFS stack (-m10000000)
+  468.596      total actual memory usage
+
+unreached in proctype urcu_reader
+       line 648, "pan.___", state 20, "(1)"
+       line 251, "pan.___", state 32, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 259, "pan.___", state 54, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 263, "pan.___", state 63, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 228, "pan.___", state 79, "(1)"
+       line 232, "pan.___", state 87, "(1)"
+       line 236, "pan.___", state 99, "(1)"
+       line 240, "pan.___", state 107, "(1)"
+       line 388, "pan.___", state 133, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 397, "pan.___", state 165, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 401, "pan.___", state 179, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 198, "(1)"
+       line 414, "pan.___", state 228, "(1)"
+       line 418, "pan.___", state 241, "(1)"
+       line 664, "pan.___", state 262, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<1))"
+       line 388, "pan.___", state 269, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 397, "pan.___", state 301, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 401, "pan.___", state 315, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 334, "(1)"
+       line 414, "pan.___", state 364, "(1)"
+       line 418, "pan.___", state 377, "(1)"
+       line 388, "pan.___", state 398, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 397, "pan.___", state 430, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 401, "pan.___", state 444, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 463, "(1)"
+       line 414, "pan.___", state 493, "(1)"
+       line 418, "pan.___", state 506, "(1)"
+       line 388, "pan.___", state 529, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 388, "pan.___", state 531, "(1)"
+       line 388, "pan.___", state 532, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 388, "pan.___", state 532, "else"
+       line 388, "pan.___", state 535, "(1)"
+       line 392, "pan.___", state 543, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 392, "pan.___", state 545, "(1)"
+       line 392, "pan.___", state 546, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 392, "pan.___", state 546, "else"
+       line 392, "pan.___", state 549, "(1)"
+       line 392, "pan.___", state 550, "(1)"
+       line 392, "pan.___", state 550, "(1)"
+       line 390, "pan.___", state 555, "((i<1))"
+       line 390, "pan.___", state 555, "((i>=1))"
+       line 397, "pan.___", state 561, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 397, "pan.___", state 563, "(1)"
+       line 397, "pan.___", state 564, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 397, "pan.___", state 564, "else"
+       line 397, "pan.___", state 567, "(1)"
+       line 397, "pan.___", state 568, "(1)"
+       line 397, "pan.___", state 568, "(1)"
+       line 401, "pan.___", state 575, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 401, "pan.___", state 577, "(1)"
+       line 401, "pan.___", state 578, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 401, "pan.___", state 578, "else"
+       line 401, "pan.___", state 581, "(1)"
+       line 401, "pan.___", state 582, "(1)"
+       line 401, "pan.___", state 582, "(1)"
+       line 399, "pan.___", state 587, "((i<2))"
+       line 399, "pan.___", state 587, "((i>=2))"
+       line 405, "pan.___", state 594, "(1)"
+       line 405, "pan.___", state 595, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 405, "pan.___", state 595, "else"
+       line 405, "pan.___", state 598, "(1)"
+       line 405, "pan.___", state 599, "(1)"
+       line 405, "pan.___", state 599, "(1)"
+       line 409, "pan.___", state 607, "(1)"
+       line 409, "pan.___", state 608, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 409, "pan.___", state 608, "else"
+       line 409, "pan.___", state 611, "(1)"
+       line 409, "pan.___", state 612, "(1)"
+       line 409, "pan.___", state 612, "(1)"
+       line 407, "pan.___", state 617, "((i<1))"
+       line 407, "pan.___", state 617, "((i>=1))"
+       line 414, "pan.___", state 624, "(1)"
+       line 414, "pan.___", state 625, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 414, "pan.___", state 625, "else"
+       line 414, "pan.___", state 628, "(1)"
+       line 414, "pan.___", state 629, "(1)"
+       line 414, "pan.___", state 629, "(1)"
+       line 418, "pan.___", state 637, "(1)"
+       line 418, "pan.___", state 638, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 418, "pan.___", state 638, "else"
+       line 418, "pan.___", state 641, "(1)"
+       line 418, "pan.___", state 642, "(1)"
+       line 418, "pan.___", state 642, "(1)"
+       line 416, "pan.___", state 647, "((i<2))"
+       line 416, "pan.___", state 647, "((i>=2))"
+       line 423, "pan.___", state 651, "(1)"
+       line 423, "pan.___", state 651, "(1)"
+       line 664, "pan.___", state 654, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 664, "pan.___", state 655, "_proc_urcu_reader = (_proc_urcu_reader|(1<<5))"
+       line 664, "pan.___", state 656, "(1)"
+       line 388, "pan.___", state 663, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 397, "pan.___", state 695, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 401, "pan.___", state 709, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 728, "(1)"
+       line 414, "pan.___", state 758, "(1)"
+       line 418, "pan.___", state 771, "(1)"
+       line 388, "pan.___", state 799, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 388, "pan.___", state 801, "(1)"
+       line 388, "pan.___", state 802, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 388, "pan.___", state 802, "else"
+       line 388, "pan.___", state 805, "(1)"
+       line 392, "pan.___", state 813, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 392, "pan.___", state 815, "(1)"
+       line 392, "pan.___", state 816, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 392, "pan.___", state 816, "else"
+       line 392, "pan.___", state 819, "(1)"
+       line 392, "pan.___", state 820, "(1)"
+       line 392, "pan.___", state 820, "(1)"
+       line 390, "pan.___", state 825, "((i<1))"
+       line 390, "pan.___", state 825, "((i>=1))"
+       line 397, "pan.___", state 831, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 397, "pan.___", state 833, "(1)"
+       line 397, "pan.___", state 834, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 397, "pan.___", state 834, "else"
+       line 397, "pan.___", state 837, "(1)"
+       line 397, "pan.___", state 838, "(1)"
+       line 397, "pan.___", state 838, "(1)"
+       line 401, "pan.___", state 845, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 401, "pan.___", state 847, "(1)"
+       line 401, "pan.___", state 848, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 401, "pan.___", state 848, "else"
+       line 401, "pan.___", state 851, "(1)"
+       line 401, "pan.___", state 852, "(1)"
+       line 401, "pan.___", state 852, "(1)"
+       line 399, "pan.___", state 857, "((i<2))"
+       line 399, "pan.___", state 857, "((i>=2))"
+       line 405, "pan.___", state 864, "(1)"
+       line 405, "pan.___", state 865, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 405, "pan.___", state 865, "else"
+       line 405, "pan.___", state 868, "(1)"
+       line 405, "pan.___", state 869, "(1)"
+       line 405, "pan.___", state 869, "(1)"
+       line 409, "pan.___", state 877, "(1)"
+       line 409, "pan.___", state 878, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 409, "pan.___", state 878, "else"
+       line 409, "pan.___", state 881, "(1)"
+       line 409, "pan.___", state 882, "(1)"
+       line 409, "pan.___", state 882, "(1)"
+       line 407, "pan.___", state 887, "((i<1))"
+       line 407, "pan.___", state 887, "((i>=1))"
+       line 414, "pan.___", state 894, "(1)"
+       line 414, "pan.___", state 895, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 414, "pan.___", state 895, "else"
+       line 414, "pan.___", state 898, "(1)"
+       line 414, "pan.___", state 899, "(1)"
+       line 414, "pan.___", state 899, "(1)"
+       line 418, "pan.___", state 907, "(1)"
+       line 418, "pan.___", state 908, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 418, "pan.___", state 908, "else"
+       line 418, "pan.___", state 911, "(1)"
+       line 418, "pan.___", state 912, "(1)"
+       line 418, "pan.___", state 912, "(1)"
+       line 423, "pan.___", state 921, "(1)"
+       line 423, "pan.___", state 921, "(1)"
+       line 388, "pan.___", state 928, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 388, "pan.___", state 930, "(1)"
+       line 388, "pan.___", state 931, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 388, "pan.___", state 931, "else"
+       line 388, "pan.___", state 934, "(1)"
+       line 392, "pan.___", state 942, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 392, "pan.___", state 944, "(1)"
+       line 392, "pan.___", state 945, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 392, "pan.___", state 945, "else"
+       line 392, "pan.___", state 948, "(1)"
+       line 392, "pan.___", state 949, "(1)"
+       line 392, "pan.___", state 949, "(1)"
+       line 390, "pan.___", state 954, "((i<1))"
+       line 390, "pan.___", state 954, "((i>=1))"
+       line 397, "pan.___", state 960, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 397, "pan.___", state 962, "(1)"
+       line 397, "pan.___", state 963, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 397, "pan.___", state 963, "else"
+       line 397, "pan.___", state 966, "(1)"
+       line 397, "pan.___", state 967, "(1)"
+       line 397, "pan.___", state 967, "(1)"
+       line 401, "pan.___", state 974, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 401, "pan.___", state 976, "(1)"
+       line 401, "pan.___", state 977, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 401, "pan.___", state 977, "else"
+       line 401, "pan.___", state 980, "(1)"
+       line 401, "pan.___", state 981, "(1)"
+       line 401, "pan.___", state 981, "(1)"
+       line 399, "pan.___", state 986, "((i<2))"
+       line 399, "pan.___", state 986, "((i>=2))"
+       line 405, "pan.___", state 993, "(1)"
+       line 405, "pan.___", state 994, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 405, "pan.___", state 994, "else"
+       line 405, "pan.___", state 997, "(1)"
+       line 405, "pan.___", state 998, "(1)"
+       line 405, "pan.___", state 998, "(1)"
+       line 409, "pan.___", state 1006, "(1)"
+       line 409, "pan.___", state 1007, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 409, "pan.___", state 1007, "else"
+       line 409, "pan.___", state 1010, "(1)"
+       line 409, "pan.___", state 1011, "(1)"
+       line 409, "pan.___", state 1011, "(1)"
+       line 407, "pan.___", state 1016, "((i<1))"
+       line 407, "pan.___", state 1016, "((i>=1))"
+       line 414, "pan.___", state 1023, "(1)"
+       line 414, "pan.___", state 1024, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 414, "pan.___", state 1024, "else"
+       line 414, "pan.___", state 1027, "(1)"
+       line 414, "pan.___", state 1028, "(1)"
+       line 414, "pan.___", state 1028, "(1)"
+       line 418, "pan.___", state 1036, "(1)"
+       line 418, "pan.___", state 1037, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 418, "pan.___", state 1037, "else"
+       line 418, "pan.___", state 1040, "(1)"
+       line 418, "pan.___", state 1041, "(1)"
+       line 418, "pan.___", state 1041, "(1)"
+       line 416, "pan.___", state 1046, "((i<2))"
+       line 416, "pan.___", state 1046, "((i>=2))"
+       line 423, "pan.___", state 1050, "(1)"
+       line 423, "pan.___", state 1050, "(1)"
+       line 672, "pan.___", state 1054, "_proc_urcu_reader = (_proc_urcu_reader|(1<<11))"
+       line 388, "pan.___", state 1059, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 397, "pan.___", state 1091, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 401, "pan.___", state 1105, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 1124, "(1)"
+       line 414, "pan.___", state 1154, "(1)"
+       line 418, "pan.___", state 1167, "(1)"
+       line 388, "pan.___", state 1191, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 397, "pan.___", state 1223, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 401, "pan.___", state 1237, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 1256, "(1)"
+       line 414, "pan.___", state 1286, "(1)"
+       line 418, "pan.___", state 1299, "(1)"
+       line 388, "pan.___", state 1324, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 397, "pan.___", state 1356, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 401, "pan.___", state 1370, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 1389, "(1)"
+       line 414, "pan.___", state 1419, "(1)"
+       line 418, "pan.___", state 1432, "(1)"
+       line 388, "pan.___", state 1453, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 397, "pan.___", state 1485, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 401, "pan.___", state 1499, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 1518, "(1)"
+       line 414, "pan.___", state 1548, "(1)"
+       line 418, "pan.___", state 1561, "(1)"
+       line 388, "pan.___", state 1587, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 397, "pan.___", state 1619, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 401, "pan.___", state 1633, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 1652, "(1)"
+       line 414, "pan.___", state 1682, "(1)"
+       line 418, "pan.___", state 1695, "(1)"
+       line 388, "pan.___", state 1716, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 397, "pan.___", state 1748, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 401, "pan.___", state 1762, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 1781, "(1)"
+       line 414, "pan.___", state 1811, "(1)"
+       line 418, "pan.___", state 1824, "(1)"
+       line 388, "pan.___", state 1848, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 397, "pan.___", state 1880, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 401, "pan.___", state 1894, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 1913, "(1)"
+       line 414, "pan.___", state 1943, "(1)"
+       line 418, "pan.___", state 1956, "(1)"
+       line 711, "pan.___", state 1977, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<19))"
+       line 388, "pan.___", state 1984, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 397, "pan.___", state 2016, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 401, "pan.___", state 2030, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 2049, "(1)"
+       line 414, "pan.___", state 2079, "(1)"
+       line 418, "pan.___", state 2092, "(1)"
+       line 388, "pan.___", state 2113, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 397, "pan.___", state 2145, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 401, "pan.___", state 2159, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 2178, "(1)"
+       line 414, "pan.___", state 2208, "(1)"
+       line 418, "pan.___", state 2221, "(1)"
+       line 388, "pan.___", state 2244, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 388, "pan.___", state 2246, "(1)"
+       line 388, "pan.___", state 2247, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 388, "pan.___", state 2247, "else"
+       line 388, "pan.___", state 2250, "(1)"
+       line 392, "pan.___", state 2258, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 392, "pan.___", state 2260, "(1)"
+       line 392, "pan.___", state 2261, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 392, "pan.___", state 2261, "else"
+       line 392, "pan.___", state 2264, "(1)"
+       line 392, "pan.___", state 2265, "(1)"
+       line 392, "pan.___", state 2265, "(1)"
+       line 390, "pan.___", state 2270, "((i<1))"
+       line 390, "pan.___", state 2270, "((i>=1))"
+       line 397, "pan.___", state 2276, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 397, "pan.___", state 2278, "(1)"
+       line 397, "pan.___", state 2279, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 397, "pan.___", state 2279, "else"
+       line 397, "pan.___", state 2282, "(1)"
+       line 397, "pan.___", state 2283, "(1)"
+       line 397, "pan.___", state 2283, "(1)"
+       line 401, "pan.___", state 2290, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 401, "pan.___", state 2292, "(1)"
+       line 401, "pan.___", state 2293, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 401, "pan.___", state 2293, "else"
+       line 401, "pan.___", state 2296, "(1)"
+       line 401, "pan.___", state 2297, "(1)"
+       line 401, "pan.___", state 2297, "(1)"
+       line 399, "pan.___", state 2302, "((i<2))"
+       line 399, "pan.___", state 2302, "((i>=2))"
+       line 405, "pan.___", state 2309, "(1)"
+       line 405, "pan.___", state 2310, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 405, "pan.___", state 2310, "else"
+       line 405, "pan.___", state 2313, "(1)"
+       line 405, "pan.___", state 2314, "(1)"
+       line 405, "pan.___", state 2314, "(1)"
+       line 409, "pan.___", state 2322, "(1)"
+       line 409, "pan.___", state 2323, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 409, "pan.___", state 2323, "else"
+       line 409, "pan.___", state 2326, "(1)"
+       line 409, "pan.___", state 2327, "(1)"
+       line 409, "pan.___", state 2327, "(1)"
+       line 407, "pan.___", state 2332, "((i<1))"
+       line 407, "pan.___", state 2332, "((i>=1))"
+       line 414, "pan.___", state 2339, "(1)"
+       line 414, "pan.___", state 2340, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 414, "pan.___", state 2340, "else"
+       line 414, "pan.___", state 2343, "(1)"
+       line 414, "pan.___", state 2344, "(1)"
+       line 414, "pan.___", state 2344, "(1)"
+       line 418, "pan.___", state 2352, "(1)"
+       line 418, "pan.___", state 2353, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 418, "pan.___", state 2353, "else"
+       line 418, "pan.___", state 2356, "(1)"
+       line 418, "pan.___", state 2357, "(1)"
+       line 418, "pan.___", state 2357, "(1)"
+       line 416, "pan.___", state 2362, "((i<2))"
+       line 416, "pan.___", state 2362, "((i>=2))"
+       line 423, "pan.___", state 2366, "(1)"
+       line 423, "pan.___", state 2366, "(1)"
+       line 711, "pan.___", state 2369, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 711, "pan.___", state 2370, "_proc_urcu_reader = (_proc_urcu_reader|(1<<23))"
+       line 711, "pan.___", state 2371, "(1)"
+       line 388, "pan.___", state 2378, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 397, "pan.___", state 2410, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 401, "pan.___", state 2424, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 2443, "(1)"
+       line 414, "pan.___", state 2473, "(1)"
+       line 418, "pan.___", state 2486, "(1)"
+       line 388, "pan.___", state 2513, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 397, "pan.___", state 2545, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 401, "pan.___", state 2559, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 2578, "(1)"
+       line 414, "pan.___", state 2608, "(1)"
+       line 418, "pan.___", state 2621, "(1)"
+       line 388, "pan.___", state 2642, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 397, "pan.___", state 2674, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 401, "pan.___", state 2688, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 2707, "(1)"
+       line 414, "pan.___", state 2737, "(1)"
+       line 418, "pan.___", state 2750, "(1)"
+       line 228, "pan.___", state 2783, "(1)"
+       line 236, "pan.___", state 2803, "(1)"
+       line 240, "pan.___", state 2811, "(1)"
+       line 228, "pan.___", state 2826, "(1)"
+       line 236, "pan.___", state 2846, "(1)"
+       line 240, "pan.___", state 2854, "(1)"
+       line 871, "pan.___", state 2871, "-end-"
+       (279 of 2871 states)
+unreached in proctype urcu_writer
+       line 388, "pan.___", state 18, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 388, "pan.___", state 24, "(1)"
+       line 392, "pan.___", state 32, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 392, "pan.___", state 38, "(1)"
+       line 392, "pan.___", state 39, "(1)"
+       line 392, "pan.___", state 39, "(1)"
+       line 390, "pan.___", state 44, "((i<1))"
+       line 390, "pan.___", state 44, "((i>=1))"
+       line 397, "pan.___", state 50, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 397, "pan.___", state 56, "(1)"
+       line 397, "pan.___", state 57, "(1)"
+       line 397, "pan.___", state 57, "(1)"
+       line 401, "pan.___", state 64, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 401, "pan.___", state 70, "(1)"
+       line 401, "pan.___", state 71, "(1)"
+       line 401, "pan.___", state 71, "(1)"
+       line 399, "pan.___", state 76, "((i<2))"
+       line 399, "pan.___", state 76, "((i>=2))"
+       line 405, "pan.___", state 83, "(1)"
+       line 405, "pan.___", state 84, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 405, "pan.___", state 84, "else"
+       line 405, "pan.___", state 87, "(1)"
+       line 405, "pan.___", state 88, "(1)"
+       line 405, "pan.___", state 88, "(1)"
+       line 409, "pan.___", state 96, "(1)"
+       line 409, "pan.___", state 97, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 409, "pan.___", state 97, "else"
+       line 409, "pan.___", state 100, "(1)"
+       line 409, "pan.___", state 101, "(1)"
+       line 409, "pan.___", state 101, "(1)"
+       line 407, "pan.___", state 106, "((i<1))"
+       line 407, "pan.___", state 106, "((i>=1))"
+       line 414, "pan.___", state 113, "(1)"
+       line 414, "pan.___", state 114, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 414, "pan.___", state 114, "else"
+       line 414, "pan.___", state 117, "(1)"
+       line 414, "pan.___", state 118, "(1)"
+       line 414, "pan.___", state 118, "(1)"
+       line 418, "pan.___", state 126, "(1)"
+       line 418, "pan.___", state 127, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 418, "pan.___", state 127, "else"
+       line 418, "pan.___", state 130, "(1)"
+       line 418, "pan.___", state 131, "(1)"
+       line 418, "pan.___", state 131, "(1)"
+       line 416, "pan.___", state 136, "((i<2))"
+       line 416, "pan.___", state 136, "((i>=2))"
+       line 423, "pan.___", state 140, "(1)"
+       line 423, "pan.___", state 140, "(1)"
+       line 251, "pan.___", state 149, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 255, "pan.___", state 158, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 253, "pan.___", state 166, "((i<1))"
+       line 253, "pan.___", state 166, "((i>=1))"
+       line 259, "pan.___", state 171, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 994, "pan.___", state 199, "old_data = cached_rcu_ptr.val[_pid]"
+       line 388, "pan.___", state 211, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 392, "pan.___", state 225, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 397, "pan.___", state 243, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 401, "pan.___", state 257, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 276, "(1)"
+       line 409, "pan.___", state 289, "(1)"
+       line 414, "pan.___", state 306, "(1)"
+       line 418, "pan.___", state 319, "(1)"
+       line 392, "pan.___", state 356, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 397, "pan.___", state 374, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 401, "pan.___", state 388, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 420, "(1)"
+       line 414, "pan.___", state 437, "(1)"
+       line 418, "pan.___", state 450, "(1)"
+       line 392, "pan.___", state 491, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 397, "pan.___", state 509, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 401, "pan.___", state 523, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 555, "(1)"
+       line 414, "pan.___", state 572, "(1)"
+       line 418, "pan.___", state 585, "(1)"
+       line 392, "pan.___", state 619, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 397, "pan.___", state 637, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 401, "pan.___", state 651, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 683, "(1)"
+       line 414, "pan.___", state 700, "(1)"
+       line 418, "pan.___", state 713, "(1)"
+       line 392, "pan.___", state 748, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 397, "pan.___", state 766, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 401, "pan.___", state 780, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 812, "(1)"
+       line 414, "pan.___", state 829, "(1)"
+       line 418, "pan.___", state 842, "(1)"
+       line 392, "pan.___", state 879, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 397, "pan.___", state 897, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 401, "pan.___", state 911, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 943, "(1)"
+       line 414, "pan.___", state 960, "(1)"
+       line 418, "pan.___", state 973, "(1)"
+       line 388, "pan.___", state 999, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 388, "pan.___", state 1001, "(1)"
+       line 388, "pan.___", state 1002, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 388, "pan.___", state 1002, "else"
+       line 388, "pan.___", state 1005, "(1)"
+       line 392, "pan.___", state 1013, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 392, "pan.___", state 1015, "(1)"
+       line 392, "pan.___", state 1016, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 392, "pan.___", state 1016, "else"
+       line 392, "pan.___", state 1019, "(1)"
+       line 392, "pan.___", state 1020, "(1)"
+       line 392, "pan.___", state 1020, "(1)"
+       line 390, "pan.___", state 1025, "((i<1))"
+       line 390, "pan.___", state 1025, "((i>=1))"
+       line 397, "pan.___", state 1031, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 397, "pan.___", state 1033, "(1)"
+       line 397, "pan.___", state 1034, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 397, "pan.___", state 1034, "else"
+       line 397, "pan.___", state 1037, "(1)"
+       line 397, "pan.___", state 1038, "(1)"
+       line 397, "pan.___", state 1038, "(1)"
+       line 401, "pan.___", state 1045, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 401, "pan.___", state 1047, "(1)"
+       line 401, "pan.___", state 1048, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 401, "pan.___", state 1048, "else"
+       line 401, "pan.___", state 1051, "(1)"
+       line 401, "pan.___", state 1052, "(1)"
+       line 401, "pan.___", state 1052, "(1)"
+       line 399, "pan.___", state 1057, "((i<2))"
+       line 399, "pan.___", state 1057, "((i>=2))"
+       line 405, "pan.___", state 1064, "(1)"
+       line 405, "pan.___", state 1065, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 405, "pan.___", state 1065, "else"
+       line 405, "pan.___", state 1068, "(1)"
+       line 405, "pan.___", state 1069, "(1)"
+       line 405, "pan.___", state 1069, "(1)"
+       line 409, "pan.___", state 1077, "(1)"
+       line 409, "pan.___", state 1078, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 409, "pan.___", state 1078, "else"
+       line 409, "pan.___", state 1081, "(1)"
+       line 409, "pan.___", state 1082, "(1)"
+       line 409, "pan.___", state 1082, "(1)"
+       line 407, "pan.___", state 1087, "((i<1))"
+       line 407, "pan.___", state 1087, "((i>=1))"
+       line 414, "pan.___", state 1094, "(1)"
+       line 414, "pan.___", state 1095, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 414, "pan.___", state 1095, "else"
+       line 414, "pan.___", state 1098, "(1)"
+       line 414, "pan.___", state 1099, "(1)"
+       line 414, "pan.___", state 1099, "(1)"
+       line 418, "pan.___", state 1107, "(1)"
+       line 418, "pan.___", state 1108, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 418, "pan.___", state 1108, "else"
+       line 418, "pan.___", state 1111, "(1)"
+       line 418, "pan.___", state 1112, "(1)"
+       line 418, "pan.___", state 1112, "(1)"
+       line 423, "pan.___", state 1121, "(1)"
+       line 423, "pan.___", state 1121, "(1)"
+       line 251, "pan.___", state 1153, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 255, "pan.___", state 1162, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 253, "pan.___", state 1170, "((i<1))"
+       line 253, "pan.___", state 1170, "((i>=1))"
+       line 259, "pan.___", state 1177, "(1)"
+       line 259, "pan.___", state 1178, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 259, "pan.___", state 1178, "else"
+       line 263, "pan.___", state 1184, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 261, "pan.___", state 1192, "((i<2))"
+       line 261, "pan.___", state 1192, "((i>=2))"
+       line 228, "pan.___", state 1200, "(1)"
+       line 232, "pan.___", state 1208, "(1)"
+       line 232, "pan.___", state 1209, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 232, "pan.___", state 1209, "else"
+       line 230, "pan.___", state 1214, "((i<1))"
+       line 230, "pan.___", state 1214, "((i>=1))"
+       line 236, "pan.___", state 1220, "(1)"
+       line 236, "pan.___", state 1221, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 236, "pan.___", state 1221, "else"
+       line 240, "pan.___", state 1228, "(1)"
+       line 240, "pan.___", state 1229, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 240, "pan.___", state 1229, "else"
+       line 245, "pan.___", state 1238, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 245, "pan.___", state 1238, "else"
+       line 251, "pan.___", state 1259, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 255, "pan.___", state 1268, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 259, "pan.___", state 1281, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 263, "pan.___", state 1290, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 228, "pan.___", state 1306, "(1)"
+       line 232, "pan.___", state 1314, "(1)"
+       line 236, "pan.___", state 1326, "(1)"
+       line 240, "pan.___", state 1334, "(1)"
+       line 255, "pan.___", state 1360, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 259, "pan.___", state 1373, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 263, "pan.___", state 1382, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 228, "pan.___", state 1398, "(1)"
+       line 232, "pan.___", state 1406, "(1)"
+       line 236, "pan.___", state 1418, "(1)"
+       line 240, "pan.___", state 1426, "(1)"
+       line 251, "pan.___", state 1457, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 255, "pan.___", state 1466, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 259, "pan.___", state 1479, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 263, "pan.___", state 1488, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 228, "pan.___", state 1504, "(1)"
+       line 232, "pan.___", state 1512, "(1)"
+       line 236, "pan.___", state 1524, "(1)"
+       line 240, "pan.___", state 1532, "(1)"
+       line 1192, "pan.___", state 1548, "-end-"
+       (154 of 1548 states)
+unreached in proctype :init:
+       (0 of 78 states)
+unreached in proctype :never:
+       line 1253, "pan.___", state 11, "-end-"
+       (1 of 11 states)
+
+pan: elapsed time 14 seconds
+pan: rate 4238.4725 states/second
+pan: avg transition delay 1.2667e-06 usec
+cp .input.spin urcu_progress_writer_error.spin.input
+cp .input.spin.trail urcu_progress_writer_error.spin.input.trail
+make[1]: Leaving directory `/home/compudj/doc/userspace-rcu/formal-model/urcu-controldataflow'
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_writer_error.spin.input b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_writer_error.spin.input
new file mode 100644 (file)
index 0000000..b4c4af4
--- /dev/null
@@ -0,0 +1,1228 @@
+#define WRITER_PROGRESS
+#define GEN_ERROR_WRITER_PROGRESS
+
+// Poison value for freed memory
+#define POISON 1
+// Memory with correct data
+#define WINE 0
+#define SLAB_SIZE 2
+
+#define read_poison    (data_read_first[0] == POISON || data_read_second[0] == POISON)
+
+#define RCU_GP_CTR_BIT (1 << 7)
+#define RCU_GP_CTR_NEST_MASK (RCU_GP_CTR_BIT - 1)
+
+//disabled
+#define REMOTE_BARRIERS
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+typedef per_proc_bit {
+       bit val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bitfield {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bitfield cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               smp_mb(i, j);
+               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
+               break;
+       od;
+}
+
+#ifdef WRITER_PROGRESS
+//#define PROGRESS_LABEL(progressid)   progress_writer_progid_##progressid:
+#define PROGRESS_LABEL(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;                                          \
+               /*                                                              \
+                * 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)                                                     \
+               do                                                              \
+               :: (reader_barrier[i] == 1) -> skip;                            \
+               :: (reader_barrier[i] == 0) -> break;                           \
+               od;                                                             \
+               i++;                                                            \
+       :: i >= NR_READERS ->                                                   \
+               break                                                           \
+       od;                                                                     \
+       smp_mb(i, j);                                                           \
+}
+
+#else
+
+#define smp_mb_send(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, smp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only one reader */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* RCU data */
+DECLARE_CACHED_VAR(bit, rcu_data[SLAB_SIZE]);
+
+/* RCU pointer */
+#if (SLAB_SIZE == 2)
+DECLARE_CACHED_VAR(bit, rcu_ptr);
+bit ptr_read_first[NR_READERS];
+bit ptr_read_second[NR_READERS];
+#else
+DECLARE_CACHED_VAR(byte, rcu_ptr);
+byte ptr_read_first[NR_READERS];
+byte ptr_read_second[NR_READERS];
+#endif
+
+bit data_read_first[NR_READERS];
+bit data_read_second[NR_READERS];
+
+bit init_done = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               :: 1 -> skip;
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               ptr_read_first[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb1;
+rmb1_end:
+                               data_read_first[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_first[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               ptr_read_second[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb2;
+rmb2_end:
+                               data_read_second[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_second[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+rmb1:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb1_end;
+rmb2:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_DATA                     (1 << 1)
+#define WRITE_PROC_WMB                 (1 << 2)
+#define WRITE_XCHG_PTR                 (1 << 3)
+
+#define WRITE_PROC_FIRST_MB            (1 << 4)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 5)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 6)
+#define WRITE_PROC_FIRST_WAIT          (1 << 7)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 8)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 9)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 10)
+#define WRITE_PROC_SECOND_WAIT         (1 << 11)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 12)
+
+#define WRITE_PROC_SECOND_MB           (1 << 13)
+
+#define WRITE_FREE                     (1 << 14)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_DATA                    \
+                                       | WRITE_PROC_WMB                \
+                                       | WRITE_XCHG_PTR                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB          \
+                                       | WRITE_FREE)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 15) - 1)
+
+/*
+ * Mutexes are implied around writer execution. A single writer at a time.
+ */
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte cur_data = 0, old_data, loop_nr = 0;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (loop_nr < 3) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               loop_nr = loop_nr + 1;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_WMB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+#endif
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_DATA) ->
+                       ooo_mem(i);
+                       cur_data = (cur_data + 1) % SLAB_SIZE;
+                       WRITE_CACHED_VAR(rcu_data[cur_data], WINE);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_DATA);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA,
+                                 WRITE_PROC_WMB) ->
+                       smp_wmb(i, j);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_WMB,
+                                 WRITE_XCHG_PTR) ->
+                       /* rcu_xchg_pointer() */
+                       atomic {
+                               old_data = READ_CACHED_VAR(rcu_ptr);
+                               WRITE_CACHED_VAR(rcu_ptr, cur_data);
+                       }
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_XCHG_PTR);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_WMB      /* No dependency on
+                                                        * WRITE_DATA because we
+                                                        * write to a
+                                                        * different location. */
+                                 | WRITE_PROC_SECOND_MB
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_FREE) ->
+                       WRITE_CACHED_VAR(rcu_data[old_data], POISON);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_FREE);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+               /*
+                * Note : Promela model adds implicit serialization of the
+                * WRITE_FREE instruction. Normally, it would be permitted to
+                * spill on the next loop execution. Given the validation we do
+                * checks for the data entry read to be poisoned, it's ok if
+                * we do not check "late arriving" memory poisoning.
+                */
+       :: 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
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(rcu_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       ptr_read_first[i] = 1;
+                       ptr_read_second[i] = 1;
+                       data_read_first[i] = WINE;
+                       data_read_second[i] = WINE;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               INIT_CACHED_VAR(rcu_data[0], WINE, j);
+               i = 1;
+               do
+               :: i < SLAB_SIZE ->
+                       INIT_CACHED_VAR(rcu_data[i], POISON, j);
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_writer_error.spin.input.trail b/formal-model/results/urcu-controldataflow-no-ipi/result-ipi-urcu_free/urcu_progress_writer_error.spin.input.trail
new file mode 100644 (file)
index 0000000..de65bad
--- /dev/null
@@ -0,0 +1,1215 @@
+-2:3:-2
+-4:-4:-4
+1:0:4499
+2:3:4419
+3:3:4422
+4:3:4422
+5:3:4425
+6:3:4433
+7:3:4433
+8:3:4436
+9:3:4442
+10:3:4446
+11:3:4446
+12:3:4449
+13:3:4459
+14:3:4467
+15:3:4467
+16:3:4470
+17:3:4476
+18:3:4480
+19:3:4480
+20:3:4483
+21:3:4489
+22:3:4493
+23:3:4494
+24:0:4499
+25:3:4496
+26:0:4499
+27:2:2873
+28:0:4499
+29:2:2879
+30:0:4499
+31:2:2880
+32:0:4499
+33:2:2881
+34:0:4497
+35:2:2882
+36:0:4503
+37:2:2883
+38:0:4503
+39:2:2884
+40:2:2885
+41:2:2889
+42:2:2890
+43:2:2898
+44:2:2899
+45:2:2903
+46:2:2904
+47:2:2912
+48:2:2917
+49:2:2921
+50:2:2922
+51:2:2930
+52:2:2931
+53:2:2935
+54:2:2936
+55:2:2930
+56:2:2931
+57:2:2935
+58:2:2936
+59:2:2944
+60:2:2949
+61:2:2950
+62:2:2961
+63:2:2962
+64:2:2963
+65:2:2974
+66:2:2979
+67:2:2980
+68:2:2991
+69:2:2992
+70:2:2993
+71:2:2991
+72:2:2992
+73:2:2993
+74:2:3004
+75:2:3012
+76:0:4503
+77:2:2883
+78:0:4503
+79:2:3016
+80:2:3020
+81:2:3021
+82:2:3025
+83:2:3029
+84:2:3030
+85:2:3034
+86:2:3042
+87:2:3043
+88:2:3047
+89:2:3051
+90:2:3052
+91:2:3047
+92:2:3048
+93:2:3056
+94:0:4503
+95:2:2883
+96:0:4503
+97:2:3064
+98:2:3065
+99:2:3066
+100:0:4503
+101:2:2883
+102:0:4503
+103:2:3071
+104:0:4503
+105:2:4024
+106:2:4025
+107:2:4029
+108:2:4033
+109:2:4034
+110:2:4038
+111:2:4043
+112:2:4051
+113:2:4055
+114:2:4056
+115:2:4051
+116:2:4055
+117:2:4056
+118:2:4060
+119:2:4067
+120:2:4074
+121:2:4075
+122:2:4082
+123:2:4087
+124:2:4094
+125:2:4095
+126:2:4094
+127:2:4095
+128:2:4102
+129:2:4106
+130:0:4503
+131:2:4111
+132:0:4503
+133:2:4112
+134:0:4503
+135:2:4113
+136:0:4503
+137:2:4114
+138:0:4503
+139:1:2
+140:0:4503
+141:2:4115
+142:0:4503
+143:1:8
+144:0:4503
+145:1:9
+146:0:4503
+147:2:4114
+148:0:4503
+149:2:4115
+150:0:4503
+151:1:10
+152:0:4503
+153:2:4114
+154:0:4503
+155:2:4115
+156:0:4503
+157:1:11
+158:0:4503
+159:2:4114
+160:0:4503
+161:2:4115
+162:0:4503
+163:1:12
+164:0:4503
+165:2:4114
+166:0:4503
+167:2:4115
+168:0:4503
+169:1:13
+170:0:4503
+171:2:4114
+172:0:4503
+173:2:4115
+174:0:4503
+175:1:14
+176:0:4503
+177:1:15
+178:0:4503
+179:1:23
+180:0:4503
+181:1:24
+182:0:4503
+183:2:4114
+184:0:4503
+185:2:4115
+186:0:4503
+187:1:128
+188:1:129
+189:1:133
+190:1:134
+191:1:142
+192:1:143
+193:1:147
+194:1:148
+195:1:156
+196:1:161
+197:1:165
+198:1:166
+199:1:174
+200:1:175
+201:1:179
+202:1:180
+203:1:174
+204:1:175
+205:1:179
+206:1:180
+207:1:188
+208:1:193
+209:1:194
+210:1:205
+211:1:206
+212:1:207
+213:1:218
+214:1:223
+215:1:224
+216:1:235
+217:1:236
+218:1:237
+219:1:235
+220:1:236
+221:1:237
+222:1:248
+223:0:4503
+224:1:15
+225:0:4503
+226:1:23
+227:0:4503
+228:1:24
+229:0:4503
+230:2:4114
+231:0:4503
+232:2:4115
+233:0:4503
+234:1:257
+235:1:258
+236:0:4503
+237:1:15
+238:0:4503
+239:1:23
+240:0:4503
+241:1:24
+242:0:4503
+243:2:4114
+244:0:4503
+245:2:4115
+246:0:4503
+247:1:264
+248:1:265
+249:1:269
+250:1:270
+251:1:278
+252:1:279
+253:1:283
+254:1:284
+255:1:292
+256:1:297
+257:1:301
+258:1:302
+259:1:310
+260:1:311
+261:1:315
+262:1:316
+263:1:310
+264:1:311
+265:1:315
+266:1:316
+267:1:324
+268:1:329
+269:1:330
+270:1:341
+271:1:342
+272:1:343
+273:1:354
+274:1:359
+275:1:360
+276:1:371
+277:1:372
+278:1:373
+279:1:371
+280:1:372
+281:1:373
+282:1:384
+283:0:4503
+284:1:15
+285:0:4503
+286:1:23
+287:0:4503
+288:1:24
+289:0:4503
+290:2:4114
+291:0:4503
+292:2:4115
+293:0:4503
+294:1:393
+295:1:394
+296:1:398
+297:1:399
+298:1:407
+299:1:408
+300:1:412
+301:1:413
+302:1:421
+303:1:426
+304:1:430
+305:1:431
+306:1:439
+307:1:440
+308:1:444
+309:1:445
+310:1:439
+311:1:440
+312:1:444
+313:1:445
+314:1:453
+315:1:458
+316:1:459
+317:1:470
+318:1:471
+319:1:472
+320:1:483
+321:1:488
+322:1:489
+323:1:500
+324:1:501
+325:1:502
+326:1:500
+327:1:501
+328:1:502
+329:1:513
+330:1:520
+331:0:4503
+332:1:15
+333:0:4503
+334:1:23
+335:0:4503
+336:1:24
+337:0:4503
+338:2:4114
+339:0:4503
+340:2:4115
+341:0:4503
+342:1:658
+343:1:659
+344:1:663
+345:1:664
+346:1:672
+347:1:673
+348:1:674
+349:1:686
+350:1:691
+351:1:695
+352:1:696
+353:1:704
+354:1:705
+355:1:709
+356:1:710
+357:1:704
+358:1:705
+359:1:709
+360:1:710
+361:1:718
+362:1:723
+363:1:724
+364:1:735
+365:1:736
+366:1:737
+367:1:748
+368:1:753
+369:1:754
+370:1:765
+371:1:766
+372:1:767
+373:1:765
+374:1:766
+375:1:767
+376:1:778
+377:0:4503
+378:1:15
+379:0:4503
+380:1:23
+381:0:4503
+382:1:24
+383:0:4503
+384:2:4114
+385:0:4503
+386:2:4115
+387:0:4503
+388:1:787
+389:1:790
+390:1:791
+391:0:4503
+392:1:15
+393:0:4503
+394:1:23
+395:0:4503
+396:1:24
+397:0:4503
+398:2:4114
+399:0:4503
+400:2:4115
+401:0:4503
+402:1:1054
+403:1:1055
+404:1:1059
+405:1:1060
+406:1:1068
+407:1:1069
+408:1:1073
+409:1:1074
+410:1:1082
+411:1:1087
+412:1:1091
+413:1:1092
+414:1:1100
+415:1:1101
+416:1:1105
+417:1:1106
+418:1:1100
+419:1:1101
+420:1:1105
+421:1:1106
+422:1:1114
+423:1:1119
+424:1:1120
+425:1:1131
+426:1:1132
+427:1:1133
+428:1:1144
+429:1:1149
+430:1:1150
+431:1:1161
+432:1:1162
+433:1:1163
+434:1:1161
+435:1:1162
+436:1:1163
+437:1:1174
+438:1:1181
+439:1:1185
+440:0:4503
+441:1:15
+442:0:4503
+443:1:23
+444:0:4503
+445:1:24
+446:0:4503
+447:2:4114
+448:0:4503
+449:2:4115
+450:0:4503
+451:1:1186
+452:1:1187
+453:1:1191
+454:1:1192
+455:1:1200
+456:1:1201
+457:1:1202
+458:1:1214
+459:1:1219
+460:1:1223
+461:1:1224
+462:1:1232
+463:1:1233
+464:1:1237
+465:1:1238
+466:1:1232
+467:1:1233
+468:1:1237
+469:1:1238
+470:1:1246
+471:1:1251
+472:1:1252
+473:1:1263
+474:1:1264
+475:1:1265
+476:1:1276
+477:1:1281
+478:1:1282
+479:1:1293
+480:1:1294
+481:1:1295
+482:1:1293
+483:1:1294
+484:1:1295
+485:1:1306
+486:0:4503
+487:1:15
+488:0:4503
+489:1:23
+490:0:4503
+491:1:24
+492:0:4503
+493:2:4114
+494:0:4503
+495:2:4115
+496:0:4503
+497:1:1315
+498:0:4503
+499:2:4114
+500:0:4503
+501:2:4115
+502:0:4503
+503:1:2779
+504:1:2786
+505:1:2787
+506:1:2794
+507:1:2799
+508:1:2806
+509:1:2807
+510:1:2806
+511:1:2807
+512:1:2814
+513:1:2818
+514:0:4503
+515:2:4114
+516:0:4503
+517:2:4115
+518:0:4503
+519:1:1317
+520:1:1318
+521:0:4503
+522:1:15
+523:0:4503
+524:1:23
+525:0:4503
+526:1:24
+527:0:4503
+528:2:4114
+529:0:4503
+530:2:4115
+531:0:4503
+532:1:1319
+533:1:1320
+534:1:1324
+535:1:1325
+536:1:1333
+537:1:1334
+538:1:1338
+539:1:1339
+540:1:1347
+541:1:1352
+542:1:1356
+543:1:1357
+544:1:1365
+545:1:1366
+546:1:1370
+547:1:1371
+548:1:1365
+549:1:1366
+550:1:1370
+551:1:1371
+552:1:1379
+553:1:1384
+554:1:1385
+555:1:1396
+556:1:1397
+557:1:1398
+558:1:1409
+559:1:1414
+560:1:1415
+561:1:1426
+562:1:1427
+563:1:1428
+564:1:1426
+565:1:1427
+566:1:1428
+567:1:1439
+568:0:4503
+569:1:15
+570:0:4503
+571:1:23
+572:0:4503
+573:1:24
+574:0:4503
+575:2:4114
+576:0:4503
+577:2:4115
+578:0:4503
+579:1:1448
+580:1:1449
+581:1:1453
+582:1:1454
+583:1:1462
+584:1:1463
+585:1:1467
+586:1:1468
+587:1:1476
+588:1:1481
+589:1:1485
+590:1:1486
+591:1:1494
+592:1:1495
+593:1:1499
+594:1:1500
+595:1:1494
+596:1:1495
+597:1:1499
+598:1:1500
+599:1:1508
+600:1:1513
+601:1:1514
+602:1:1525
+603:1:1526
+604:1:1527
+605:1:1538
+606:1:1543
+607:1:1544
+608:1:1555
+609:1:1556
+610:1:1557
+611:1:1555
+612:1:1556
+613:1:1557
+614:1:1568
+615:1:1575
+616:1:1579
+617:0:4503
+618:1:15
+619:0:4503
+620:1:23
+621:0:4503
+622:1:24
+623:0:4503
+624:2:4114
+625:0:4503
+626:2:4115
+627:0:4503
+628:1:1582
+629:1:1583
+630:1:1587
+631:1:1588
+632:1:1596
+633:1:1597
+634:1:1598
+635:1:1610
+636:1:1615
+637:1:1619
+638:1:1620
+639:1:1628
+640:1:1629
+641:1:1633
+642:1:1634
+643:1:1628
+644:1:1629
+645:1:1633
+646:1:1634
+647:1:1642
+648:1:1647
+649:1:1648
+650:1:1659
+651:1:1660
+652:1:1661
+653:1:1672
+654:1:1677
+655:1:1678
+656:1:1689
+657:1:1690
+658:1:1691
+659:1:1689
+660:1:1690
+661:1:1691
+662:1:1702
+663:0:4503
+664:1:15
+665:0:4503
+666:1:23
+667:0:4503
+668:1:24
+669:0:4503
+670:2:4114
+671:0:4503
+672:2:4115
+673:0:4503
+674:1:1711
+675:1:1712
+676:1:1716
+677:1:1717
+678:1:1725
+679:1:1726
+680:1:1730
+681:1:1731
+682:1:1739
+683:1:1744
+684:1:1748
+685:1:1749
+686:1:1757
+687:1:1758
+688:1:1762
+689:1:1763
+690:1:1757
+691:1:1758
+692:1:1762
+693:1:1763
+694:1:1771
+695:1:1776
+696:1:1777
+697:1:1788
+698:1:1789
+699:1:1790
+700:1:1801
+701:1:1806
+702:1:1807
+703:1:1818
+704:1:1819
+705:1:1820
+706:1:1818
+707:1:1819
+708:1:1820
+709:1:1831
+710:1:1838
+711:1:1842
+712:0:4503
+713:1:15
+714:0:4503
+715:1:23
+716:0:4503
+717:1:24
+718:0:4503
+719:2:4114
+720:0:4503
+721:2:4115
+722:0:4503
+723:1:1843
+724:1:1844
+725:1:1848
+726:1:1849
+727:1:1857
+728:1:1858
+729:1:1859
+730:1:1871
+731:1:1876
+732:1:1880
+733:1:1881
+734:1:1889
+735:1:1890
+736:1:1894
+737:1:1895
+738:1:1889
+739:1:1890
+740:1:1894
+741:1:1895
+742:1:1903
+743:1:1908
+744:1:1909
+745:1:1920
+746:1:1921
+747:1:1922
+748:1:1933
+749:1:1938
+750:1:1939
+751:1:1950
+752:1:1951
+753:1:1952
+754:1:1950
+755:1:1951
+756:1:1952
+757:1:1963
+758:0:4503
+759:1:15
+760:0:4503
+761:1:23
+762:0:4503
+763:1:24
+764:0:4503
+765:2:4114
+766:0:4503
+767:2:4115
+768:0:4503
+769:1:1972
+770:1:1973
+771:0:4503
+772:1:15
+773:0:4503
+774:1:23
+775:0:4503
+776:1:24
+777:0:4503
+778:2:4114
+779:0:4503
+780:2:4115
+781:0:4503
+782:1:1979
+783:1:1980
+784:1:1984
+785:1:1985
+786:1:1993
+787:1:1994
+788:1:1998
+789:1:1999
+790:1:2007
+791:1:2012
+792:1:2016
+793:1:2017
+794:1:2025
+795:1:2026
+796:1:2030
+797:1:2031
+798:1:2025
+799:1:2026
+800:1:2030
+801:1:2031
+802:1:2039
+803:1:2044
+804:1:2045
+805:1:2056
+806:1:2057
+807:1:2058
+808:1:2069
+809:1:2074
+810:1:2075
+811:1:2086
+812:1:2087
+813:1:2088
+814:1:2086
+815:1:2087
+816:1:2088
+817:1:2099
+818:0:4503
+819:1:15
+820:0:4503
+821:1:23
+822:0:4503
+823:1:24
+824:0:4503
+825:2:4114
+826:0:4503
+827:2:4115
+828:0:4503
+829:1:2108
+830:1:2109
+831:1:2113
+832:1:2114
+833:1:2122
+834:1:2123
+835:1:2127
+836:1:2128
+837:1:2136
+838:1:2141
+839:1:2145
+840:1:2146
+841:1:2154
+842:1:2155
+843:1:2159
+844:1:2160
+845:1:2154
+846:1:2155
+847:1:2159
+848:1:2160
+849:1:2168
+850:1:2173
+851:1:2174
+852:1:2185
+853:1:2186
+854:1:2187
+855:1:2198
+856:1:2203
+857:1:2204
+858:1:2215
+859:1:2216
+860:1:2217
+861:1:2215
+862:1:2216
+863:1:2217
+864:1:2228
+865:1:2235
+866:0:4503
+867:1:15
+868:0:4503
+869:1:23
+870:0:4503
+871:1:24
+872:0:4503
+873:2:4114
+874:0:4503
+875:2:4115
+876:0:4503
+877:1:2373
+878:1:2374
+879:1:2378
+880:1:2379
+881:1:2387
+882:1:2388
+883:1:2389
+884:1:2401
+885:1:2406
+886:1:2410
+887:1:2411
+888:1:2419
+889:1:2420
+890:1:2424
+891:1:2425
+892:1:2419
+893:1:2420
+894:1:2424
+895:1:2425
+896:1:2433
+897:1:2438
+898:1:2439
+899:1:2450
+900:1:2451
+901:1:2452
+902:1:2463
+903:1:2468
+904:1:2469
+905:1:2480
+906:1:2481
+907:1:2482
+908:1:2480
+909:1:2481
+910:1:2482
+911:1:2493
+912:0:4503
+913:1:15
+914:0:4503
+915:1:23
+916:0:4503
+917:1:24
+918:0:4503
+919:2:4114
+920:0:4503
+921:2:4115
+922:0:4503
+923:1:2502
+924:0:4503
+925:2:4114
+926:0:4503
+927:2:4115
+928:0:4503
+929:1:2822
+930:1:2829
+931:1:2830
+932:1:2837
+933:1:2842
+934:1:2849
+935:1:2850
+936:1:2849
+937:1:2850
+938:1:2857
+939:1:2861
+940:0:4503
+941:2:4114
+942:0:4503
+943:2:4115
+944:0:4503
+945:1:2504
+946:1:2505
+947:0:4503
+948:1:15
+949:0:4503
+950:1:23
+951:0:4503
+952:1:24
+953:0:4503
+954:2:4114
+955:0:4503
+956:2:4115
+957:0:4503
+958:1:2508
+959:1:2509
+960:1:2513
+961:1:2514
+962:1:2522
+963:1:2523
+964:1:2527
+965:1:2528
+966:1:2536
+967:1:2541
+968:1:2545
+969:1:2546
+970:1:2554
+971:1:2555
+972:1:2559
+973:1:2560
+974:1:2554
+975:1:2555
+976:1:2559
+977:1:2560
+978:1:2568
+979:1:2573
+980:1:2574
+981:1:2585
+982:1:2586
+983:1:2587
+984:1:2598
+985:1:2603
+986:1:2604
+987:1:2615
+988:1:2616
+989:1:2617
+990:1:2615
+991:1:2616
+992:1:2617
+993:1:2628
+994:0:4503
+995:1:15
+996:0:4503
+997:1:23
+998:0:4503
+999:1:24
+1000:0:4503
+1001:2:4114
+1002:0:4503
+1003:2:4115
+1004:0:4503
+1005:1:2637
+1006:1:2638
+1007:1:2642
+1008:1:2643
+1009:1:2651
+1010:1:2652
+1011:1:2656
+1012:1:2657
+1013:1:2665
+1014:1:2670
+1015:1:2674
+1016:1:2675
+1017:1:2683
+1018:1:2684
+1019:1:2688
+1020:1:2689
+1021:1:2683
+1022:1:2684
+1023:1:2688
+1024:1:2689
+1025:1:2697
+1026:1:2702
+1027:1:2703
+1028:1:2714
+1029:1:2715
+1030:1:2716
+1031:1:2727
+1032:1:2732
+1033:1:2733
+1034:1:2744
+1035:1:2745
+1036:1:2746
+1037:1:2744
+1038:1:2745
+1039:1:2746
+1040:1:2757
+1041:1:2764
+1042:1:2768
+1043:0:4503
+1044:1:15
+1045:0:4503
+1046:1:23
+1047:0:4503
+1048:1:24
+1049:0:4503
+1050:2:4114
+1051:0:4503
+1052:2:4115
+1053:0:4503
+1054:1:2769
+1055:0:4503
+1056:1:2777
+1057:0:4503
+1058:1:2865
+1059:0:4503
+1060:1:9
+1061:0:4503
+1062:2:4114
+1063:0:4503
+1064:2:4115
+1065:0:4503
+1066:1:10
+1067:0:4503
+1068:2:4114
+1069:0:4503
+1070:2:4115
+1071:0:4503
+1072:1:11
+1073:0:4503
+1074:2:4114
+1075:0:4503
+1076:2:4115
+1077:0:4503
+1078:1:12
+1079:0:4503
+1080:2:4114
+1081:0:4503
+1082:2:4115
+1083:0:4503
+1084:1:13
+1085:0:4503
+1086:2:4114
+1087:0:4503
+1088:2:4115
+1089:0:4503
+1090:1:14
+1091:0:4503
+1092:1:15
+1093:0:4503
+1094:1:23
+1095:0:4503
+1096:1:24
+1097:0:4503
+1098:2:4114
+1099:0:4503
+1100:2:4115
+1101:0:4503
+1102:1:128
+1103:1:129
+1104:1:133
+1105:1:134
+1106:1:142
+1107:1:143
+1108:1:144
+1109:1:156
+1110:1:161
+1111:1:165
+1112:1:166
+1113:1:174
+1114:1:175
+1115:1:179
+1116:1:180
+1117:1:174
+1118:1:175
+1119:1:179
+1120:1:180
+1121:1:188
+1122:1:193
+1123:1:194
+1124:1:205
+1125:1:206
+1126:1:207
+1127:1:218
+1128:1:223
+1129:1:224
+1130:1:235
+1131:1:236
+1132:1:237
+1133:1:235
+1134:1:236
+1135:1:237
+1136:1:248
+1137:0:4503
+1138:1:15
+1139:0:4503
+1140:1:23
+1141:0:4503
+1142:1:24
+1143:0:4503
+1144:2:4114
+1145:0:4503
+1146:2:4115
+1147:0:4503
+1148:1:257
+1149:1:258
+1150:0:4503
+1151:1:15
+1152:0:4503
+1153:1:23
+1154:0:4503
+1155:1:24
+1156:0:4503
+1157:2:4114
+1158:0:4503
+1159:2:4115
+1160:0:4503
+1161:1:1186
+1162:1:1187
+1163:1:1191
+1164:1:1192
+1165:1:1200
+1166:1:1201
+1167:1:1205
+1168:1:1206
+1169:1:1214
+1170:1:1219
+1171:1:1223
+1172:1:1224
+1173:1:1232
+1174:1:1233
+1175:1:1237
+1176:1:1238
+1177:1:1232
+1178:1:1233
+1179:1:1237
+1180:1:1238
+1181:1:1246
+1182:1:1251
+1183:1:1252
+1184:1:1263
+1185:1:1264
+1186:1:1265
+1187:1:1276
+1188:1:1281
+1189:1:1282
+1190:1:1293
+1191:1:1294
+1192:1:1295
+1193:1:1293
+1194:1:1294
+1195:1:1295
+1196:1:1306
+1197:0:4503
+1198:1:15
+1199:0:4503
+1200:1:16
+-1:-1:-1
+1201:0:4503
+1202:2:4114
+1203:0:4503
+1204:2:4115
+1205:0:4503
+1206:2:4114
+1207:0:4503
+1208:2:4115
+1209:0:4503
+1210:2:4114
+1211:0:4503
+1212:2:4115
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/todo.sh b/formal-model/results/urcu-controldataflow-no-ipi/todo.sh
new file mode 100644 (file)
index 0000000..f2bcdf6
--- /dev/null
@@ -0,0 +1,18 @@
+echo testing no ipi
+make urcu_free | tee urcu_free.log
+echo testing no ipi
+make urcu_free_no_mb | tee urcu_free_no_mb.log
+echo testing no ipi
+make urcu_free_no_rmb | tee urcu_free_no_rmb.log
+echo testing no ipi
+make urcu_free_no_wmb | tee urcu_free_no_wmb.log
+echo testing no ipi
+make urcu_free_single_flip | tee urcu_free_single_flip.log
+echo testing no ipi
+make urcu_progress_writer | tee urcu_progress_writer.log
+echo testing no ipi
+make urcu_progress_reader | tee urcu_progress_reader.log
+echo testing no ipi
+make urcu_progress_writer_error | tee urcu_progress_writer_error.log
+echo testing no ipi
+make asserts | tee asserts.log
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu.sh b/formal-model/results/urcu-controldataflow-no-ipi/urcu.sh
new file mode 100644 (file)
index 0000000..65ff517
--- /dev/null
@@ -0,0 +1,29 @@
+#!/bin/sh
+#
+# Compiles and runs the urcu.spin Promela model.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# Copyright (C) IBM Corporation, 2009
+#               Mathieu Desnoyers, 2009
+#
+# Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
+#          Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
+
+# Basic execution, without LTL clauses. See Makefile.
+
+spin -a urcu.spin
+cc -DSAFETY -o pan pan.c
+./pan -v -c1 -X -m10000000 -w21
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu.spin b/formal-model/results/urcu-controldataflow-no-ipi/urcu.spin
new file mode 100644 (file)
index 0000000..4fe6b9e
--- /dev/null
@@ -0,0 +1,1225 @@
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+typedef per_proc_bit {
+       bit val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bitfield {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bitfield cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               /*
+                * 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, j);
+               reader_barrier[get_readerid()] = 0;
+       :: 1 ->
+               /*
+                * 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)
+//#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);                                                           \
+       i = 0;                                                                  \
+       do                                                                      \
+       :: i < NR_READERS ->                                                    \
+               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.                                            \
+                */                                                             \
+               do                                                              \
+               :: (reader_barrier[i] == 1) ->                                  \
+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(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, smp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only one reader */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* RCU data */
+DECLARE_CACHED_VAR(bit, rcu_data[SLAB_SIZE]);
+
+/* RCU pointer */
+#if (SLAB_SIZE == 2)
+DECLARE_CACHED_VAR(bit, rcu_ptr);
+bit ptr_read_first[NR_READERS];
+bit ptr_read_second[NR_READERS];
+#else
+DECLARE_CACHED_VAR(byte, rcu_ptr);
+byte ptr_read_first[NR_READERS];
+byte ptr_read_second[NR_READERS];
+#endif
+
+bit data_read_first[NR_READERS];
+bit data_read_second[NR_READERS];
+
+bit init_done = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               ptr_read_first[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb1;
+rmb1_end:
+                               data_read_first[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_first[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               ptr_read_second[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb2;
+rmb2_end:
+                               data_read_second[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_second[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+rmb1:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb1_end;
+rmb2:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_DATA                     (1 << 1)
+#define WRITE_PROC_WMB                 (1 << 2)
+#define WRITE_XCHG_PTR                 (1 << 3)
+
+#define WRITE_PROC_FIRST_MB            (1 << 4)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 5)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 6)
+#define WRITE_PROC_FIRST_WAIT          (1 << 7)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 8)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 9)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 10)
+#define WRITE_PROC_SECOND_WAIT         (1 << 11)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 12)
+
+#define WRITE_PROC_SECOND_MB           (1 << 13)
+
+#define WRITE_FREE                     (1 << 14)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_DATA                    \
+                                       | WRITE_PROC_WMB                \
+                                       | WRITE_XCHG_PTR                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB          \
+                                       | WRITE_FREE)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 15) - 1)
+
+/*
+ * Mutexes are implied around writer execution. A single writer at a time.
+ */
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte cur_data = 0, old_data, loop_nr = 0;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (loop_nr < 3) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               loop_nr = loop_nr + 1;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_WMB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+#endif
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_DATA) ->
+                       ooo_mem(i);
+                       cur_data = (cur_data + 1) % SLAB_SIZE;
+                       WRITE_CACHED_VAR(rcu_data[cur_data], WINE);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_DATA);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA,
+                                 WRITE_PROC_WMB) ->
+                       smp_wmb(i, j);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_WMB,
+                                 WRITE_XCHG_PTR) ->
+                       /* rcu_xchg_pointer() */
+                       atomic {
+                               old_data = READ_CACHED_VAR(rcu_ptr);
+                               WRITE_CACHED_VAR(rcu_ptr, cur_data);
+                       }
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_XCHG_PTR);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_WMB      /* No dependency on
+                                                        * WRITE_DATA because we
+                                                        * write to a
+                                                        * different location. */
+                                 | WRITE_PROC_SECOND_MB
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_FREE) ->
+                       WRITE_CACHED_VAR(rcu_data[old_data], POISON);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_FREE);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+               /*
+                * Note : Promela model adds implicit serialization of the
+                * WRITE_FREE instruction. Normally, it would be permitted to
+                * spill on the next loop execution. Given the validation we do
+                * checks for the data entry read to be poisoned, it's ok if
+                * we do not check "late arriving" memory poisoning.
+                */
+       :: 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
+#ifdef READER_PROGRESS
+               /*
+                * Make sure we don't block the reader's progress.
+                */
+               smp_mb_send(i, j, 5);
+#endif
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(rcu_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       ptr_read_first[i] = 1;
+                       ptr_read_second[i] = 1;
+                       data_read_first[i] = WINE;
+                       data_read_second[i] = WINE;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               INIT_CACHED_VAR(rcu_data[0], WINE, j);
+               i = 1;
+               do
+               :: i < SLAB_SIZE ->
+                       INIT_CACHED_VAR(rcu_data[i], POISON, j);
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu.spin.bkp.b4ptr b/formal-model/results/urcu-controldataflow-no-ipi/urcu.spin.bkp.b4ptr
new file mode 100644 (file)
index 0000000..6670f3e
--- /dev/null
@@ -0,0 +1,1123 @@
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bit {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bit cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(generation_ptr, get_pid());
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(generation_ptr, get_pid());
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               smp_mb(i, j);
+               reader_barrier[get_readerid()] = 0;
+       :: 1 ->
+       /*
+        * Busy-looping waiting for other barrier requests is not considered as
+        * non-progress.
+        */
+#ifdef READER_PROGRESS
+progress_reader2:
+#endif
+#ifdef WRITER_PROGRESS
+//progress_writer_from_reader1:
+#endif
+               skip;
+       :: 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_reader2:
+#endif
+               break;
+       od;
+}
+
+#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;                                          \
+               /*                                                              \
+                * 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)                                                     \
+               do                                                              \
+               :: (reader_barrier[i] == 1) -> skip;                            \
+               :: (reader_barrier[i] == 0) -> break;                           \
+               od;                                                             \
+               i++;                                                            \
+       :: i >= NR_READERS ->                                                   \
+               break                                                           \
+       od;                                                                     \
+       smp_mb(i, j);                                                           \
+}
+
+#else
+
+#define smp_mb_send(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, wmp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only two readers */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* pointer generation */
+DECLARE_CACHED_VAR(byte, generation_ptr);
+
+byte last_free_gen = 0;
+bit free_done = 0;
+byte read_generation[NR_READERS];
+bit data_access[NR_READERS];
+
+bit write_lock = 0;
+
+bit init_done = 0;
+
+bit sighand_exec = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(generation_ptr, get_pid());
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(generation_ptr, get_pid());
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               :: 1 -> skip;
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               read_generation[get_readerid()] =
+                                       READ_CACHED_VAR(generation_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               ooo_mem(i);
+                               goto non_atomic;
+non_atomic_end:
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               read_generation[get_readerid()] =
+                                       READ_CACHED_VAR(generation_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               goto non_atomic2;
+non_atomic2_end:
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+non_atomic:
+       data_access[get_readerid()] = 1;
+       data_access[get_readerid()] = 0;
+       goto non_atomic_end;
+non_atomic2:
+       data_access[get_readerid()] = 1;
+       data_access[get_readerid()] = 0;
+       goto non_atomic2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_PROC_FIRST_MB            (1 << 1)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 2)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 3)
+#define WRITE_PROC_FIRST_WAIT          (1 << 4)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 5)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 6)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 7)
+#define WRITE_PROC_SECOND_WAIT         (1 << 8)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 9)
+
+#define WRITE_PROC_SECOND_MB           (1 << 10)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 11) - 1)
+
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte old_gen;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (READ_CACHED_VAR(generation_ptr) < 5) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               ooo_mem(i);
+               atomic {
+                       old_gen = READ_CACHED_VAR(generation_ptr);
+                       WRITE_CACHED_VAR(generation_ptr, old_gen + 1);
+               }
+               ooo_mem(i);
+
+               do
+               :: 1 ->
+                       atomic {
+                               if
+                               :: write_lock == 0 ->
+                                       write_lock = 1;
+                                       break;
+                               :: else ->
+                                       skip;
+                               fi;
+                       }
+               od;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+
+               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
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(generation_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       read_generation[i] = 1;
+                       data_access[i] = 0;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu_free.log b/formal-model/results/urcu-controldataflow-no-ipi/urcu_free.log
new file mode 100644 (file)
index 0000000..8d1493e
--- /dev/null
@@ -0,0 +1,525 @@
+rm -f pan* trail.out .input.spin* *.spin.trail .input.define
+touch .input.define
+cat .input.define >> pan.ltl
+cat DEFINES >> pan.ltl
+spin -f "!(`cat urcu_free.ltl | grep -v ^//`)" >> pan.ltl
+cat .input.define > .input.spin
+cat DEFINES >> .input.spin
+cat urcu.spin >> .input.spin
+rm -f .input.spin.trail
+spin -a -X -N pan.ltl .input.spin
+Exit-Status 0
+gcc -O2 -w -DHASH64 -o pan pan.c
+./pan -a -v -c1 -X -m10000000 -w20
+warning: for p.o. reduction to be valid the never claim must be stutter-invariant
+(never claims generated from LTL formulae are stutter-invariant)
+depth 0: Claim reached state 5 (line 1257)
+Depth=    4688 States=    1e+06 Transitions= 4.65e+08 Memory=   550.432        t=    592 R=   2e+03
+
+(Spin Version 5.1.7 -- 23 December 2008)
+       + Partial Order Reduction
+
+Full statespace search for:
+       never claim             +
+       assertion violations    + (if within scope of claim)
+       acceptance   cycles     + (fairness disabled)
+       invalid end states      - (disabled by never claim)
+
+State-vector 88 byte, depth reached 4688, errors: 0
+  1884295 states, stored
+9.0500538e+08 states, matched
+9.0688968e+08 transitions (= stored+matched)
+5.3819272e+09 atomic steps
+hash conflicts: 4.4602277e+08 (resolved)
+
+Stats on memory usage (in Megabytes):
+  208.452      equivalent memory usage for states (stored*(State-vector + overhead))
+  159.034      actual memory usage for states (compression: 76.29%)
+               state-vector as stored = 60 byte + 28 byte overhead
+    8.000      memory used for hash table (-w20)
+  457.764      memory used for DFS stack (-m10000000)
+  624.651      total actual memory usage
+
+unreached in proctype urcu_reader
+       line 394, "pan.___", state 17, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 49, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 63, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 82, "(1)"
+       line 420, "pan.___", state 112, "(1)"
+       line 424, "pan.___", state 125, "(1)"
+       line 575, "pan.___", state 146, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<1))"
+       line 394, "pan.___", state 153, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 185, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 199, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 218, "(1)"
+       line 420, "pan.___", state 248, "(1)"
+       line 424, "pan.___", state 261, "(1)"
+       line 394, "pan.___", state 282, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 314, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 328, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 347, "(1)"
+       line 420, "pan.___", state 377, "(1)"
+       line 424, "pan.___", state 390, "(1)"
+       line 394, "pan.___", state 413, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 394, "pan.___", state 415, "(1)"
+       line 394, "pan.___", state 416, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 394, "pan.___", state 416, "else"
+       line 394, "pan.___", state 419, "(1)"
+       line 398, "pan.___", state 427, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 398, "pan.___", state 429, "(1)"
+       line 398, "pan.___", state 430, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 398, "pan.___", state 430, "else"
+       line 398, "pan.___", state 433, "(1)"
+       line 398, "pan.___", state 434, "(1)"
+       line 398, "pan.___", state 434, "(1)"
+       line 396, "pan.___", state 439, "((i<1))"
+       line 396, "pan.___", state 439, "((i>=1))"
+       line 403, "pan.___", state 445, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 447, "(1)"
+       line 403, "pan.___", state 448, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 403, "pan.___", state 448, "else"
+       line 403, "pan.___", state 451, "(1)"
+       line 403, "pan.___", state 452, "(1)"
+       line 403, "pan.___", state 452, "(1)"
+       line 407, "pan.___", state 459, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 461, "(1)"
+       line 407, "pan.___", state 462, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 407, "pan.___", state 462, "else"
+       line 407, "pan.___", state 465, "(1)"
+       line 407, "pan.___", state 466, "(1)"
+       line 407, "pan.___", state 466, "(1)"
+       line 405, "pan.___", state 471, "((i<2))"
+       line 405, "pan.___", state 471, "((i>=2))"
+       line 411, "pan.___", state 478, "(1)"
+       line 411, "pan.___", state 479, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 411, "pan.___", state 479, "else"
+       line 411, "pan.___", state 482, "(1)"
+       line 411, "pan.___", state 483, "(1)"
+       line 411, "pan.___", state 483, "(1)"
+       line 415, "pan.___", state 491, "(1)"
+       line 415, "pan.___", state 492, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 415, "pan.___", state 492, "else"
+       line 415, "pan.___", state 495, "(1)"
+       line 415, "pan.___", state 496, "(1)"
+       line 415, "pan.___", state 496, "(1)"
+       line 413, "pan.___", state 501, "((i<1))"
+       line 413, "pan.___", state 501, "((i>=1))"
+       line 420, "pan.___", state 508, "(1)"
+       line 420, "pan.___", state 509, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 420, "pan.___", state 509, "else"
+       line 420, "pan.___", state 512, "(1)"
+       line 420, "pan.___", state 513, "(1)"
+       line 420, "pan.___", state 513, "(1)"
+       line 424, "pan.___", state 521, "(1)"
+       line 424, "pan.___", state 522, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 424, "pan.___", state 522, "else"
+       line 424, "pan.___", state 525, "(1)"
+       line 424, "pan.___", state 526, "(1)"
+       line 424, "pan.___", state 526, "(1)"
+       line 422, "pan.___", state 531, "((i<2))"
+       line 422, "pan.___", state 531, "((i>=2))"
+       line 429, "pan.___", state 535, "(1)"
+       line 429, "pan.___", state 535, "(1)"
+       line 575, "pan.___", state 538, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 575, "pan.___", state 539, "_proc_urcu_reader = (_proc_urcu_reader|(1<<5))"
+       line 575, "pan.___", state 540, "(1)"
+       line 249, "pan.___", state 544, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 253, "pan.___", state 555, "(1)"
+       line 257, "pan.___", state 566, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, "pan.___", state 575, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, "pan.___", state 591, "(1)"
+       line 230, "pan.___", state 599, "(1)"
+       line 234, "pan.___", state 611, "(1)"
+       line 238, "pan.___", state 619, "(1)"
+       line 394, "pan.___", state 637, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 398, "pan.___", state 651, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 669, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 683, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 702, "(1)"
+       line 415, "pan.___", state 715, "(1)"
+       line 420, "pan.___", state 732, "(1)"
+       line 424, "pan.___", state 745, "(1)"
+       line 394, "pan.___", state 773, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 394, "pan.___", state 775, "(1)"
+       line 394, "pan.___", state 776, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 394, "pan.___", state 776, "else"
+       line 394, "pan.___", state 779, "(1)"
+       line 398, "pan.___", state 787, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 398, "pan.___", state 789, "(1)"
+       line 398, "pan.___", state 790, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 398, "pan.___", state 790, "else"
+       line 398, "pan.___", state 793, "(1)"
+       line 398, "pan.___", state 794, "(1)"
+       line 398, "pan.___", state 794, "(1)"
+       line 396, "pan.___", state 799, "((i<1))"
+       line 396, "pan.___", state 799, "((i>=1))"
+       line 403, "pan.___", state 805, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 807, "(1)"
+       line 403, "pan.___", state 808, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 403, "pan.___", state 808, "else"
+       line 403, "pan.___", state 811, "(1)"
+       line 403, "pan.___", state 812, "(1)"
+       line 403, "pan.___", state 812, "(1)"
+       line 407, "pan.___", state 819, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 821, "(1)"
+       line 407, "pan.___", state 822, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 407, "pan.___", state 822, "else"
+       line 407, "pan.___", state 825, "(1)"
+       line 407, "pan.___", state 826, "(1)"
+       line 407, "pan.___", state 826, "(1)"
+       line 405, "pan.___", state 831, "((i<2))"
+       line 405, "pan.___", state 831, "((i>=2))"
+       line 411, "pan.___", state 838, "(1)"
+       line 411, "pan.___", state 839, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 411, "pan.___", state 839, "else"
+       line 411, "pan.___", state 842, "(1)"
+       line 411, "pan.___", state 843, "(1)"
+       line 411, "pan.___", state 843, "(1)"
+       line 415, "pan.___", state 851, "(1)"
+       line 415, "pan.___", state 852, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 415, "pan.___", state 852, "else"
+       line 415, "pan.___", state 855, "(1)"
+       line 415, "pan.___", state 856, "(1)"
+       line 415, "pan.___", state 856, "(1)"
+       line 413, "pan.___", state 861, "((i<1))"
+       line 413, "pan.___", state 861, "((i>=1))"
+       line 420, "pan.___", state 868, "(1)"
+       line 420, "pan.___", state 869, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 420, "pan.___", state 869, "else"
+       line 420, "pan.___", state 872, "(1)"
+       line 420, "pan.___", state 873, "(1)"
+       line 420, "pan.___", state 873, "(1)"
+       line 424, "pan.___", state 881, "(1)"
+       line 424, "pan.___", state 882, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 424, "pan.___", state 882, "else"
+       line 424, "pan.___", state 885, "(1)"
+       line 424, "pan.___", state 886, "(1)"
+       line 424, "pan.___", state 886, "(1)"
+       line 429, "pan.___", state 895, "(1)"
+       line 429, "pan.___", state 895, "(1)"
+       line 394, "pan.___", state 902, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 394, "pan.___", state 904, "(1)"
+       line 394, "pan.___", state 905, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 394, "pan.___", state 905, "else"
+       line 394, "pan.___", state 908, "(1)"
+       line 398, "pan.___", state 916, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 398, "pan.___", state 918, "(1)"
+       line 398, "pan.___", state 919, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 398, "pan.___", state 919, "else"
+       line 398, "pan.___", state 922, "(1)"
+       line 398, "pan.___", state 923, "(1)"
+       line 398, "pan.___", state 923, "(1)"
+       line 396, "pan.___", state 928, "((i<1))"
+       line 396, "pan.___", state 928, "((i>=1))"
+       line 403, "pan.___", state 934, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 936, "(1)"
+       line 403, "pan.___", state 937, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 403, "pan.___", state 937, "else"
+       line 403, "pan.___", state 940, "(1)"
+       line 403, "pan.___", state 941, "(1)"
+       line 403, "pan.___", state 941, "(1)"
+       line 407, "pan.___", state 948, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 950, "(1)"
+       line 407, "pan.___", state 951, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 407, "pan.___", state 951, "else"
+       line 407, "pan.___", state 954, "(1)"
+       line 407, "pan.___", state 955, "(1)"
+       line 407, "pan.___", state 955, "(1)"
+       line 405, "pan.___", state 960, "((i<2))"
+       line 405, "pan.___", state 960, "((i>=2))"
+       line 411, "pan.___", state 967, "(1)"
+       line 411, "pan.___", state 968, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 411, "pan.___", state 968, "else"
+       line 411, "pan.___", state 971, "(1)"
+       line 411, "pan.___", state 972, "(1)"
+       line 411, "pan.___", state 972, "(1)"
+       line 415, "pan.___", state 980, "(1)"
+       line 415, "pan.___", state 981, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 415, "pan.___", state 981, "else"
+       line 415, "pan.___", state 984, "(1)"
+       line 415, "pan.___", state 985, "(1)"
+       line 415, "pan.___", state 985, "(1)"
+       line 413, "pan.___", state 990, "((i<1))"
+       line 413, "pan.___", state 990, "((i>=1))"
+       line 420, "pan.___", state 997, "(1)"
+       line 420, "pan.___", state 998, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 420, "pan.___", state 998, "else"
+       line 420, "pan.___", state 1001, "(1)"
+       line 420, "pan.___", state 1002, "(1)"
+       line 420, "pan.___", state 1002, "(1)"
+       line 424, "pan.___", state 1010, "(1)"
+       line 424, "pan.___", state 1011, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 424, "pan.___", state 1011, "else"
+       line 424, "pan.___", state 1014, "(1)"
+       line 424, "pan.___", state 1015, "(1)"
+       line 424, "pan.___", state 1015, "(1)"
+       line 422, "pan.___", state 1020, "((i<2))"
+       line 422, "pan.___", state 1020, "((i>=2))"
+       line 429, "pan.___", state 1024, "(1)"
+       line 429, "pan.___", state 1024, "(1)"
+       line 583, "pan.___", state 1028, "_proc_urcu_reader = (_proc_urcu_reader|(1<<11))"
+       line 394, "pan.___", state 1033, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 398, "pan.___", state 1047, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 1065, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 1079, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 1098, "(1)"
+       line 415, "pan.___", state 1111, "(1)"
+       line 420, "pan.___", state 1128, "(1)"
+       line 424, "pan.___", state 1141, "(1)"
+       line 394, "pan.___", state 1165, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 1197, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 1211, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 1230, "(1)"
+       line 420, "pan.___", state 1260, "(1)"
+       line 424, "pan.___", state 1273, "(1)"
+       line 394, "pan.___", state 1298, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 1330, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 1344, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 1363, "(1)"
+       line 420, "pan.___", state 1393, "(1)"
+       line 424, "pan.___", state 1406, "(1)"
+       line 394, "pan.___", state 1427, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 1459, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 1473, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 1492, "(1)"
+       line 420, "pan.___", state 1522, "(1)"
+       line 424, "pan.___", state 1535, "(1)"
+       line 249, "pan.___", state 1558, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 257, "pan.___", state 1580, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, "pan.___", state 1589, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, "pan.___", state 1605, "(1)"
+       line 230, "pan.___", state 1613, "(1)"
+       line 234, "pan.___", state 1625, "(1)"
+       line 238, "pan.___", state 1633, "(1)"
+       line 394, "pan.___", state 1651, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 398, "pan.___", state 1665, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 1683, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 1697, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 1716, "(1)"
+       line 415, "pan.___", state 1729, "(1)"
+       line 420, "pan.___", state 1746, "(1)"
+       line 424, "pan.___", state 1759, "(1)"
+       line 394, "pan.___", state 1780, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 398, "pan.___", state 1794, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 1812, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 1826, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 1845, "(1)"
+       line 415, "pan.___", state 1858, "(1)"
+       line 420, "pan.___", state 1875, "(1)"
+       line 424, "pan.___", state 1888, "(1)"
+       line 394, "pan.___", state 1912, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 398, "pan.___", state 1928, "(1)"
+       line 403, "pan.___", state 1944, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 1958, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 1977, "(1)"
+       line 420, "pan.___", state 2007, "(1)"
+       line 424, "pan.___", state 2020, "(1)"
+       line 622, "pan.___", state 2041, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<19))"
+       line 394, "pan.___", state 2048, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 2080, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 2094, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 2113, "(1)"
+       line 420, "pan.___", state 2143, "(1)"
+       line 424, "pan.___", state 2156, "(1)"
+       line 394, "pan.___", state 2177, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 2209, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 2223, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 2242, "(1)"
+       line 420, "pan.___", state 2272, "(1)"
+       line 424, "pan.___", state 2285, "(1)"
+       line 394, "pan.___", state 2308, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 394, "pan.___", state 2310, "(1)"
+       line 394, "pan.___", state 2311, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 394, "pan.___", state 2311, "else"
+       line 394, "pan.___", state 2314, "(1)"
+       line 398, "pan.___", state 2322, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 398, "pan.___", state 2324, "(1)"
+       line 398, "pan.___", state 2325, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 398, "pan.___", state 2325, "else"
+       line 398, "pan.___", state 2328, "(1)"
+       line 398, "pan.___", state 2329, "(1)"
+       line 398, "pan.___", state 2329, "(1)"
+       line 396, "pan.___", state 2334, "((i<1))"
+       line 396, "pan.___", state 2334, "((i>=1))"
+       line 403, "pan.___", state 2340, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 2342, "(1)"
+       line 403, "pan.___", state 2343, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 403, "pan.___", state 2343, "else"
+       line 403, "pan.___", state 2346, "(1)"
+       line 403, "pan.___", state 2347, "(1)"
+       line 403, "pan.___", state 2347, "(1)"
+       line 407, "pan.___", state 2354, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 2356, "(1)"
+       line 407, "pan.___", state 2357, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 407, "pan.___", state 2357, "else"
+       line 407, "pan.___", state 2360, "(1)"
+       line 407, "pan.___", state 2361, "(1)"
+       line 407, "pan.___", state 2361, "(1)"
+       line 405, "pan.___", state 2366, "((i<2))"
+       line 405, "pan.___", state 2366, "((i>=2))"
+       line 411, "pan.___", state 2373, "(1)"
+       line 411, "pan.___", state 2374, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 411, "pan.___", state 2374, "else"
+       line 411, "pan.___", state 2377, "(1)"
+       line 411, "pan.___", state 2378, "(1)"
+       line 411, "pan.___", state 2378, "(1)"
+       line 415, "pan.___", state 2386, "(1)"
+       line 415, "pan.___", state 2387, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 415, "pan.___", state 2387, "else"
+       line 415, "pan.___", state 2390, "(1)"
+       line 415, "pan.___", state 2391, "(1)"
+       line 415, "pan.___", state 2391, "(1)"
+       line 413, "pan.___", state 2396, "((i<1))"
+       line 413, "pan.___", state 2396, "((i>=1))"
+       line 420, "pan.___", state 2403, "(1)"
+       line 420, "pan.___", state 2404, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 420, "pan.___", state 2404, "else"
+       line 420, "pan.___", state 2407, "(1)"
+       line 420, "pan.___", state 2408, "(1)"
+       line 420, "pan.___", state 2408, "(1)"
+       line 424, "pan.___", state 2416, "(1)"
+       line 424, "pan.___", state 2417, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 424, "pan.___", state 2417, "else"
+       line 424, "pan.___", state 2420, "(1)"
+       line 424, "pan.___", state 2421, "(1)"
+       line 424, "pan.___", state 2421, "(1)"
+       line 422, "pan.___", state 2426, "((i<2))"
+       line 422, "pan.___", state 2426, "((i>=2))"
+       line 429, "pan.___", state 2430, "(1)"
+       line 429, "pan.___", state 2430, "(1)"
+       line 622, "pan.___", state 2433, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 622, "pan.___", state 2434, "_proc_urcu_reader = (_proc_urcu_reader|(1<<23))"
+       line 622, "pan.___", state 2435, "(1)"
+       line 249, "pan.___", state 2439, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 253, "pan.___", state 2450, "(1)"
+       line 257, "pan.___", state 2461, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, "pan.___", state 2470, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, "pan.___", state 2486, "(1)"
+       line 230, "pan.___", state 2494, "(1)"
+       line 234, "pan.___", state 2506, "(1)"
+       line 238, "pan.___", state 2514, "(1)"
+       line 394, "pan.___", state 2532, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 398, "pan.___", state 2546, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 2564, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 2578, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 2597, "(1)"
+       line 415, "pan.___", state 2610, "(1)"
+       line 420, "pan.___", state 2627, "(1)"
+       line 424, "pan.___", state 2640, "(1)"
+       line 249, "pan.___", state 2664, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 253, "pan.___", state 2673, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, "pan.___", state 2686, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, "pan.___", state 2695, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, "pan.___", state 2711, "(1)"
+       line 230, "pan.___", state 2719, "(1)"
+       line 234, "pan.___", state 2731, "(1)"
+       line 238, "pan.___", state 2739, "(1)"
+       line 394, "pan.___", state 2757, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 398, "pan.___", state 2771, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 2789, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 2803, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 2822, "(1)"
+       line 415, "pan.___", state 2835, "(1)"
+       line 420, "pan.___", state 2852, "(1)"
+       line 424, "pan.___", state 2865, "(1)"
+       line 394, "pan.___", state 2886, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 398, "pan.___", state 2900, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 2918, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 2932, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 2951, "(1)"
+       line 415, "pan.___", state 2964, "(1)"
+       line 420, "pan.___", state 2981, "(1)"
+       line 424, "pan.___", state 2994, "(1)"
+       line 226, "pan.___", state 3027, "(1)"
+       line 234, "pan.___", state 3047, "(1)"
+       line 238, "pan.___", state 3055, "(1)"
+       line 226, "pan.___", state 3070, "(1)"
+       line 230, "pan.___", state 3078, "(1)"
+       line 234, "pan.___", state 3090, "(1)"
+       line 238, "pan.___", state 3098, "(1)"
+       line 876, "pan.___", state 3115, "-end-"
+       (318 of 3115 states)
+unreached in proctype urcu_writer
+       line 394, "pan.___", state 18, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 398, "pan.___", state 32, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 50, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 83, "(1)"
+       line 415, "pan.___", state 96, "(1)"
+       line 420, "pan.___", state 113, "(1)"
+       line 249, "pan.___", state 149, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 253, "pan.___", state 158, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, "pan.___", state 171, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 394, "pan.___", state 211, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 398, "pan.___", state 225, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 243, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 257, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 411, "pan.___", state 276, "(1)"
+       line 415, "pan.___", state 289, "(1)"
+       line 420, "pan.___", state 306, "(1)"
+       line 424, "pan.___", state 319, "(1)"
+       line 398, "pan.___", state 356, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 374, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 388, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 415, "pan.___", state 420, "(1)"
+       line 420, "pan.___", state 437, "(1)"
+       line 424, "pan.___", state 450, "(1)"
+       line 398, "pan.___", state 494, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 512, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 526, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 415, "pan.___", state 558, "(1)"
+       line 420, "pan.___", state 575, "(1)"
+       line 424, "pan.___", state 588, "(1)"
+       line 398, "pan.___", state 623, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 641, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 655, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 415, "pan.___", state 687, "(1)"
+       line 420, "pan.___", state 704, "(1)"
+       line 424, "pan.___", state 717, "(1)"
+       line 398, "pan.___", state 754, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 403, "pan.___", state 772, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 407, "pan.___", state 786, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 415, "pan.___", state 818, "(1)"
+       line 420, "pan.___", state 835, "(1)"
+       line 424, "pan.___", state 848, "(1)"
+       line 249, "pan.___", state 903, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 253, "pan.___", state 912, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, "pan.___", state 927, "(1)"
+       line 261, "pan.___", state 934, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, "pan.___", state 950, "(1)"
+       line 230, "pan.___", state 958, "(1)"
+       line 234, "pan.___", state 970, "(1)"
+       line 238, "pan.___", state 978, "(1)"
+       line 253, "pan.___", state 1003, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, "pan.___", state 1016, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, "pan.___", state 1025, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, "pan.___", state 1041, "(1)"
+       line 230, "pan.___", state 1049, "(1)"
+       line 234, "pan.___", state 1061, "(1)"
+       line 238, "pan.___", state 1069, "(1)"
+       line 253, "pan.___", state 1094, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, "pan.___", state 1107, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, "pan.___", state 1116, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, "pan.___", state 1132, "(1)"
+       line 230, "pan.___", state 1140, "(1)"
+       line 234, "pan.___", state 1152, "(1)"
+       line 238, "pan.___", state 1160, "(1)"
+       line 253, "pan.___", state 1185, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 257, "pan.___", state 1198, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 261, "pan.___", state 1207, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 226, "pan.___", state 1223, "(1)"
+       line 230, "pan.___", state 1231, "(1)"
+       line 234, "pan.___", state 1243, "(1)"
+       line 238, "pan.___", state 1251, "(1)"
+       line 1203, "pan.___", state 1266, "-end-"
+       (71 of 1266 states)
+unreached in proctype :init:
+       (0 of 78 states)
+unreached in proctype :never:
+       line 1262, "pan.___", state 8, "-end-"
+       (1 of 8 states)
+
+pan: elapsed time 1.16e+03 seconds
+pan: rate 1618.1151 states/second
+pan: avg transition delay 1.2841e-06 usec
+cp .input.spin urcu_free.spin.input
+cp .input.spin.trail urcu_free.spin.input.trail
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu_free.ltl b/formal-model/results/urcu-controldataflow-no-ipi/urcu_free.ltl
new file mode 100644 (file)
index 0000000..6be1be9
--- /dev/null
@@ -0,0 +1 @@
+[] (!read_poison)
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu_free.spin.input b/formal-model/results/urcu-controldataflow-no-ipi/urcu_free.spin.input
new file mode 100644 (file)
index 0000000..542625d
--- /dev/null
@@ -0,0 +1,1239 @@
+
+// Poison value for freed memory
+#define POISON 1
+// Memory with correct data
+#define WINE 0
+#define SLAB_SIZE 2
+
+#define read_poison    (data_read_first[0] == POISON || data_read_second[0] == POISON)
+
+#define RCU_GP_CTR_BIT (1 << 7)
+#define RCU_GP_CTR_NEST_MASK (RCU_GP_CTR_BIT - 1)
+
+//disabled
+//#define REMOTE_BARRIERS
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+typedef per_proc_bit {
+       bit val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bitfield {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bitfield cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               /*
+                * 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, j);
+               reader_barrier[get_readerid()] = 0;
+       :: 1 ->
+               /*
+                * 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)
+//#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);                                                           \
+       i = 0;                                                                  \
+       do                                                                      \
+       :: i < NR_READERS ->                                                    \
+               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.                                            \
+                */                                                             \
+               do                                                              \
+               :: (reader_barrier[i] == 1) ->                                  \
+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(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, smp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only one reader */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* RCU data */
+DECLARE_CACHED_VAR(bit, rcu_data[SLAB_SIZE]);
+
+/* RCU pointer */
+#if (SLAB_SIZE == 2)
+DECLARE_CACHED_VAR(bit, rcu_ptr);
+bit ptr_read_first[NR_READERS];
+bit ptr_read_second[NR_READERS];
+#else
+DECLARE_CACHED_VAR(byte, rcu_ptr);
+byte ptr_read_first[NR_READERS];
+byte ptr_read_second[NR_READERS];
+#endif
+
+bit data_read_first[NR_READERS];
+bit data_read_second[NR_READERS];
+
+bit init_done = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               ptr_read_first[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb1;
+rmb1_end:
+                               data_read_first[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_first[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               ptr_read_second[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb2;
+rmb2_end:
+                               data_read_second[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_second[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+rmb1:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb1_end;
+rmb2:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_DATA                     (1 << 1)
+#define WRITE_PROC_WMB                 (1 << 2)
+#define WRITE_XCHG_PTR                 (1 << 3)
+
+#define WRITE_PROC_FIRST_MB            (1 << 4)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 5)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 6)
+#define WRITE_PROC_FIRST_WAIT          (1 << 7)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 8)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 9)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 10)
+#define WRITE_PROC_SECOND_WAIT         (1 << 11)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 12)
+
+#define WRITE_PROC_SECOND_MB           (1 << 13)
+
+#define WRITE_FREE                     (1 << 14)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_DATA                    \
+                                       | WRITE_PROC_WMB                \
+                                       | WRITE_XCHG_PTR                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB          \
+                                       | WRITE_FREE)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 15) - 1)
+
+/*
+ * Mutexes are implied around writer execution. A single writer at a time.
+ */
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte cur_data = 0, old_data, loop_nr = 0;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (loop_nr < 3) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               loop_nr = loop_nr + 1;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_WMB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+#endif
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_DATA) ->
+                       ooo_mem(i);
+                       cur_data = (cur_data + 1) % SLAB_SIZE;
+                       WRITE_CACHED_VAR(rcu_data[cur_data], WINE);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_DATA);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA,
+                                 WRITE_PROC_WMB) ->
+                       smp_wmb(i, j);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_WMB,
+                                 WRITE_XCHG_PTR) ->
+                       /* rcu_xchg_pointer() */
+                       atomic {
+                               old_data = READ_CACHED_VAR(rcu_ptr);
+                               WRITE_CACHED_VAR(rcu_ptr, cur_data);
+                       }
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_XCHG_PTR);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_WMB      /* No dependency on
+                                                        * WRITE_DATA because we
+                                                        * write to a
+                                                        * different location. */
+                                 | WRITE_PROC_SECOND_MB
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_FREE) ->
+                       WRITE_CACHED_VAR(rcu_data[old_data], POISON);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_FREE);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+               /*
+                * Note : Promela model adds implicit serialization of the
+                * WRITE_FREE instruction. Normally, it would be permitted to
+                * spill on the next loop execution. Given the validation we do
+                * checks for the data entry read to be poisoned, it's ok if
+                * we do not check "late arriving" memory poisoning.
+                */
+       :: 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
+#ifdef READER_PROGRESS
+               /*
+                * Make sure we don't block the reader's progress.
+                */
+               smp_mb_send(i, j, 5);
+#endif
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(rcu_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       ptr_read_first[i] = 1;
+                       ptr_read_second[i] = 1;
+                       data_read_first[i] = WINE;
+                       data_read_second[i] = WINE;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               INIT_CACHED_VAR(rcu_data[0], WINE, j);
+               i = 1;
+               do
+               :: i < SLAB_SIZE ->
+                       INIT_CACHED_VAR(rcu_data[i], POISON, j);
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_nested.define b/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_nested.define
new file mode 100644 (file)
index 0000000..0fb59bd
--- /dev/null
@@ -0,0 +1 @@
+#define READER_NEST_LEVEL 2
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_mb.define b/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_mb.define
new file mode 100644 (file)
index 0000000..d99d793
--- /dev/null
@@ -0,0 +1 @@
+#define NO_MB
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_mb.log b/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_mb.log
new file mode 100644 (file)
index 0000000..b27c022
--- /dev/null
@@ -0,0 +1,884 @@
+rm -f pan* trail.out .input.spin* *.spin.trail .input.define
+touch .input.define
+cat .input.define >> pan.ltl
+cat DEFINES >> pan.ltl
+spin -f "!(`cat urcu_free.ltl | grep -v ^//`)" >> pan.ltl
+cp urcu_free_no_mb.define .input.define
+cat .input.define > .input.spin
+cat DEFINES >> .input.spin
+cat urcu.spin >> .input.spin
+rm -f .input.spin.trail
+spin -a -X -N pan.ltl .input.spin
+Exit-Status 0
+gcc -O2 -w -DHASH64 -o pan pan.c
+./pan -a -v -c1 -X -m10000000 -w20
+warning: for p.o. reduction to be valid the never claim must be stutter-invariant
+(never claims generated from LTL formulae are stutter-invariant)
+depth 0: Claim reached state 5 (line 1258)
+Depth=   11321 States=    1e+06 Transitions= 3.42e+08 Memory=   550.432        t=    421 R=   2e+03
+pan: claim violated! (at depth 1224)
+pan: wrote .input.spin.trail
+
+(Spin Version 5.1.7 -- 23 December 2008)
+Warning: Search not completed
+       + Partial Order Reduction
+
+Full statespace search for:
+       never claim             +
+       assertion violations    + (if within scope of claim)
+       acceptance   cycles     + (fairness disabled)
+       invalid end states      - (disabled by never claim)
+
+State-vector 88 byte, depth reached 11321, errors: 1
+  1661452 states, stored
+5.1024872e+08 states, matched
+5.1191017e+08 transitions (= stored+matched)
+2.8514789e+09 atomic steps
+hash conflicts: 2.0792287e+08 (resolved)
+
+Stats on memory usage (in Megabytes):
+  183.800      equivalent memory usage for states (stored*(State-vector + overhead))
+  140.372      actual memory usage for states (compression: 76.37%)
+               state-vector as stored = 61 byte + 28 byte overhead
+    8.000      memory used for hash table (-w20)
+  457.764      memory used for DFS stack (-m10000000)
+  605.998      total actual memory usage
+
+unreached in proctype urcu_reader
+       line 395, "pan.___", state 21, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 53, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 67, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 86, "(1)"
+       line 421, "pan.___", state 116, "(1)"
+       line 425, "pan.___", state 129, "(1)"
+       line 582, "pan.___", state 150, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<1))"
+       line 395, "pan.___", state 157, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 189, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 203, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 222, "(1)"
+       line 421, "pan.___", state 252, "(1)"
+       line 425, "pan.___", state 265, "(1)"
+       line 395, "pan.___", state 286, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 318, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 332, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 351, "(1)"
+       line 421, "pan.___", state 381, "(1)"
+       line 425, "pan.___", state 394, "(1)"
+       line 395, "pan.___", state 417, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 419, "(1)"
+       line 395, "pan.___", state 420, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 420, "else"
+       line 395, "pan.___", state 423, "(1)"
+       line 399, "pan.___", state 431, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 433, "(1)"
+       line 399, "pan.___", state 434, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 434, "else"
+       line 399, "pan.___", state 437, "(1)"
+       line 399, "pan.___", state 438, "(1)"
+       line 399, "pan.___", state 438, "(1)"
+       line 397, "pan.___", state 443, "((i<1))"
+       line 397, "pan.___", state 443, "((i>=1))"
+       line 404, "pan.___", state 449, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 451, "(1)"
+       line 404, "pan.___", state 452, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 452, "else"
+       line 404, "pan.___", state 455, "(1)"
+       line 404, "pan.___", state 456, "(1)"
+       line 404, "pan.___", state 456, "(1)"
+       line 408, "pan.___", state 463, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 465, "(1)"
+       line 408, "pan.___", state 466, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 466, "else"
+       line 408, "pan.___", state 469, "(1)"
+       line 408, "pan.___", state 470, "(1)"
+       line 408, "pan.___", state 470, "(1)"
+       line 406, "pan.___", state 475, "((i<2))"
+       line 406, "pan.___", state 475, "((i>=2))"
+       line 412, "pan.___", state 482, "(1)"
+       line 412, "pan.___", state 483, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 483, "else"
+       line 412, "pan.___", state 486, "(1)"
+       line 412, "pan.___", state 487, "(1)"
+       line 412, "pan.___", state 487, "(1)"
+       line 416, "pan.___", state 495, "(1)"
+       line 416, "pan.___", state 496, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 496, "else"
+       line 416, "pan.___", state 499, "(1)"
+       line 416, "pan.___", state 500, "(1)"
+       line 416, "pan.___", state 500, "(1)"
+       line 414, "pan.___", state 505, "((i<1))"
+       line 414, "pan.___", state 505, "((i>=1))"
+       line 421, "pan.___", state 512, "(1)"
+       line 421, "pan.___", state 513, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 513, "else"
+       line 421, "pan.___", state 516, "(1)"
+       line 421, "pan.___", state 517, "(1)"
+       line 421, "pan.___", state 517, "(1)"
+       line 425, "pan.___", state 525, "(1)"
+       line 425, "pan.___", state 526, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 526, "else"
+       line 425, "pan.___", state 529, "(1)"
+       line 425, "pan.___", state 530, "(1)"
+       line 425, "pan.___", state 530, "(1)"
+       line 423, "pan.___", state 535, "((i<2))"
+       line 423, "pan.___", state 535, "((i>=2))"
+       line 430, "pan.___", state 539, "(1)"
+       line 430, "pan.___", state 539, "(1)"
+       line 582, "pan.___", state 542, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 582, "pan.___", state 543, "_proc_urcu_reader = (_proc_urcu_reader|(1<<5))"
+       line 582, "pan.___", state 544, "(1)"
+       line 250, "pan.___", state 548, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 250, "pan.___", state 550, "(1)"
+       line 254, "pan.___", state 557, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 559, "(1)"
+       line 254, "pan.___", state 560, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 254, "pan.___", state 560, "else"
+       line 252, "pan.___", state 565, "((i<1))"
+       line 252, "pan.___", state 565, "((i>=1))"
+       line 258, "pan.___", state 570, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 572, "(1)"
+       line 258, "pan.___", state 573, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 573, "else"
+       line 262, "pan.___", state 579, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 581, "(1)"
+       line 262, "pan.___", state 582, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 262, "pan.___", state 582, "else"
+       line 260, "pan.___", state 587, "((i<2))"
+       line 260, "pan.___", state 587, "((i>=2))"
+       line 227, "pan.___", state 595, "(1)"
+       line 231, "pan.___", state 603, "(1)"
+       line 231, "pan.___", state 604, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 604, "else"
+       line 229, "pan.___", state 609, "((i<1))"
+       line 229, "pan.___", state 609, "((i>=1))"
+       line 235, "pan.___", state 615, "(1)"
+       line 235, "pan.___", state 616, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 616, "else"
+       line 239, "pan.___", state 623, "(1)"
+       line 239, "pan.___", state 624, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 624, "else"
+       line 244, "pan.___", state 633, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 633, "else"
+       line 277, "pan.___", state 635, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 277, "pan.___", state 635, "else"
+       line 395, "pan.___", state 641, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 673, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 687, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 706, "(1)"
+       line 421, "pan.___", state 736, "(1)"
+       line 425, "pan.___", state 749, "(1)"
+       line 395, "pan.___", state 777, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 779, "(1)"
+       line 395, "pan.___", state 780, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 780, "else"
+       line 395, "pan.___", state 783, "(1)"
+       line 399, "pan.___", state 791, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 793, "(1)"
+       line 399, "pan.___", state 794, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 794, "else"
+       line 399, "pan.___", state 797, "(1)"
+       line 399, "pan.___", state 798, "(1)"
+       line 399, "pan.___", state 798, "(1)"
+       line 397, "pan.___", state 803, "((i<1))"
+       line 397, "pan.___", state 803, "((i>=1))"
+       line 404, "pan.___", state 809, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 811, "(1)"
+       line 404, "pan.___", state 812, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 812, "else"
+       line 404, "pan.___", state 815, "(1)"
+       line 404, "pan.___", state 816, "(1)"
+       line 404, "pan.___", state 816, "(1)"
+       line 408, "pan.___", state 823, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 825, "(1)"
+       line 408, "pan.___", state 826, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 826, "else"
+       line 408, "pan.___", state 829, "(1)"
+       line 408, "pan.___", state 830, "(1)"
+       line 408, "pan.___", state 830, "(1)"
+       line 406, "pan.___", state 835, "((i<2))"
+       line 406, "pan.___", state 835, "((i>=2))"
+       line 412, "pan.___", state 842, "(1)"
+       line 412, "pan.___", state 843, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 843, "else"
+       line 412, "pan.___", state 846, "(1)"
+       line 412, "pan.___", state 847, "(1)"
+       line 412, "pan.___", state 847, "(1)"
+       line 416, "pan.___", state 855, "(1)"
+       line 416, "pan.___", state 856, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 856, "else"
+       line 416, "pan.___", state 859, "(1)"
+       line 416, "pan.___", state 860, "(1)"
+       line 416, "pan.___", state 860, "(1)"
+       line 414, "pan.___", state 865, "((i<1))"
+       line 414, "pan.___", state 865, "((i>=1))"
+       line 421, "pan.___", state 872, "(1)"
+       line 421, "pan.___", state 873, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 873, "else"
+       line 421, "pan.___", state 876, "(1)"
+       line 421, "pan.___", state 877, "(1)"
+       line 421, "pan.___", state 877, "(1)"
+       line 425, "pan.___", state 885, "(1)"
+       line 425, "pan.___", state 886, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 886, "else"
+       line 425, "pan.___", state 889, "(1)"
+       line 425, "pan.___", state 890, "(1)"
+       line 425, "pan.___", state 890, "(1)"
+       line 430, "pan.___", state 899, "(1)"
+       line 430, "pan.___", state 899, "(1)"
+       line 395, "pan.___", state 906, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 908, "(1)"
+       line 395, "pan.___", state 909, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 909, "else"
+       line 395, "pan.___", state 912, "(1)"
+       line 399, "pan.___", state 920, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 922, "(1)"
+       line 399, "pan.___", state 923, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 923, "else"
+       line 399, "pan.___", state 926, "(1)"
+       line 399, "pan.___", state 927, "(1)"
+       line 399, "pan.___", state 927, "(1)"
+       line 397, "pan.___", state 932, "((i<1))"
+       line 397, "pan.___", state 932, "((i>=1))"
+       line 404, "pan.___", state 938, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 940, "(1)"
+       line 404, "pan.___", state 941, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 941, "else"
+       line 404, "pan.___", state 944, "(1)"
+       line 404, "pan.___", state 945, "(1)"
+       line 404, "pan.___", state 945, "(1)"
+       line 408, "pan.___", state 952, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 954, "(1)"
+       line 408, "pan.___", state 955, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 955, "else"
+       line 408, "pan.___", state 958, "(1)"
+       line 408, "pan.___", state 959, "(1)"
+       line 408, "pan.___", state 959, "(1)"
+       line 406, "pan.___", state 964, "((i<2))"
+       line 406, "pan.___", state 964, "((i>=2))"
+       line 412, "pan.___", state 971, "(1)"
+       line 412, "pan.___", state 972, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 972, "else"
+       line 412, "pan.___", state 975, "(1)"
+       line 412, "pan.___", state 976, "(1)"
+       line 412, "pan.___", state 976, "(1)"
+       line 416, "pan.___", state 984, "(1)"
+       line 416, "pan.___", state 985, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 985, "else"
+       line 416, "pan.___", state 988, "(1)"
+       line 416, "pan.___", state 989, "(1)"
+       line 416, "pan.___", state 989, "(1)"
+       line 414, "pan.___", state 994, "((i<1))"
+       line 414, "pan.___", state 994, "((i>=1))"
+       line 421, "pan.___", state 1001, "(1)"
+       line 421, "pan.___", state 1002, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 1002, "else"
+       line 421, "pan.___", state 1005, "(1)"
+       line 421, "pan.___", state 1006, "(1)"
+       line 421, "pan.___", state 1006, "(1)"
+       line 425, "pan.___", state 1014, "(1)"
+       line 425, "pan.___", state 1015, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 1015, "else"
+       line 425, "pan.___", state 1018, "(1)"
+       line 425, "pan.___", state 1019, "(1)"
+       line 425, "pan.___", state 1019, "(1)"
+       line 423, "pan.___", state 1024, "((i<2))"
+       line 423, "pan.___", state 1024, "((i>=2))"
+       line 430, "pan.___", state 1028, "(1)"
+       line 430, "pan.___", state 1028, "(1)"
+       line 590, "pan.___", state 1032, "_proc_urcu_reader = (_proc_urcu_reader|(1<<11))"
+       line 395, "pan.___", state 1037, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1069, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1083, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1102, "(1)"
+       line 421, "pan.___", state 1132, "(1)"
+       line 425, "pan.___", state 1145, "(1)"
+       line 395, "pan.___", state 1169, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1201, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1215, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1234, "(1)"
+       line 421, "pan.___", state 1264, "(1)"
+       line 425, "pan.___", state 1277, "(1)"
+       line 395, "pan.___", state 1302, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1334, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1348, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1367, "(1)"
+       line 421, "pan.___", state 1397, "(1)"
+       line 425, "pan.___", state 1410, "(1)"
+       line 395, "pan.___", state 1431, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1463, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1477, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1496, "(1)"
+       line 421, "pan.___", state 1526, "(1)"
+       line 425, "pan.___", state 1539, "(1)"
+       line 250, "pan.___", state 1562, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 250, "pan.___", state 1564, "(1)"
+       line 254, "pan.___", state 1571, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1573, "(1)"
+       line 254, "pan.___", state 1574, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 254, "pan.___", state 1574, "else"
+       line 252, "pan.___", state 1579, "((i<1))"
+       line 252, "pan.___", state 1579, "((i>=1))"
+       line 258, "pan.___", state 1584, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1586, "(1)"
+       line 258, "pan.___", state 1587, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 1587, "else"
+       line 262, "pan.___", state 1593, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1595, "(1)"
+       line 262, "pan.___", state 1596, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 262, "pan.___", state 1596, "else"
+       line 260, "pan.___", state 1601, "((i<2))"
+       line 260, "pan.___", state 1601, "((i>=2))"
+       line 227, "pan.___", state 1609, "(1)"
+       line 231, "pan.___", state 1617, "(1)"
+       line 231, "pan.___", state 1618, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 1618, "else"
+       line 229, "pan.___", state 1623, "((i<1))"
+       line 229, "pan.___", state 1623, "((i>=1))"
+       line 235, "pan.___", state 1629, "(1)"
+       line 235, "pan.___", state 1630, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 1630, "else"
+       line 239, "pan.___", state 1637, "(1)"
+       line 239, "pan.___", state 1638, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 1638, "else"
+       line 244, "pan.___", state 1647, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 1647, "else"
+       line 277, "pan.___", state 1649, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 277, "pan.___", state 1649, "else"
+       line 395, "pan.___", state 1655, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1687, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1701, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1720, "(1)"
+       line 421, "pan.___", state 1750, "(1)"
+       line 425, "pan.___", state 1763, "(1)"
+       line 395, "pan.___", state 1784, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1816, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1830, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1849, "(1)"
+       line 421, "pan.___", state 1879, "(1)"
+       line 425, "pan.___", state 1892, "(1)"
+       line 395, "pan.___", state 1916, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1948, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1962, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1981, "(1)"
+       line 421, "pan.___", state 2011, "(1)"
+       line 425, "pan.___", state 2024, "(1)"
+       line 629, "pan.___", state 2045, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<19))"
+       line 395, "pan.___", state 2052, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2084, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2098, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2117, "(1)"
+       line 421, "pan.___", state 2147, "(1)"
+       line 425, "pan.___", state 2160, "(1)"
+       line 395, "pan.___", state 2181, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2213, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2227, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2246, "(1)"
+       line 421, "pan.___", state 2276, "(1)"
+       line 425, "pan.___", state 2289, "(1)"
+       line 395, "pan.___", state 2312, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 2314, "(1)"
+       line 395, "pan.___", state 2315, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 2315, "else"
+       line 395, "pan.___", state 2318, "(1)"
+       line 399, "pan.___", state 2326, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 2328, "(1)"
+       line 399, "pan.___", state 2329, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 2329, "else"
+       line 399, "pan.___", state 2332, "(1)"
+       line 399, "pan.___", state 2333, "(1)"
+       line 399, "pan.___", state 2333, "(1)"
+       line 397, "pan.___", state 2338, "((i<1))"
+       line 397, "pan.___", state 2338, "((i>=1))"
+       line 404, "pan.___", state 2344, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2346, "(1)"
+       line 404, "pan.___", state 2347, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 2347, "else"
+       line 404, "pan.___", state 2350, "(1)"
+       line 404, "pan.___", state 2351, "(1)"
+       line 404, "pan.___", state 2351, "(1)"
+       line 408, "pan.___", state 2358, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2360, "(1)"
+       line 408, "pan.___", state 2361, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 2361, "else"
+       line 408, "pan.___", state 2364, "(1)"
+       line 408, "pan.___", state 2365, "(1)"
+       line 408, "pan.___", state 2365, "(1)"
+       line 406, "pan.___", state 2370, "((i<2))"
+       line 406, "pan.___", state 2370, "((i>=2))"
+       line 412, "pan.___", state 2377, "(1)"
+       line 412, "pan.___", state 2378, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 2378, "else"
+       line 412, "pan.___", state 2381, "(1)"
+       line 412, "pan.___", state 2382, "(1)"
+       line 412, "pan.___", state 2382, "(1)"
+       line 416, "pan.___", state 2390, "(1)"
+       line 416, "pan.___", state 2391, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 2391, "else"
+       line 416, "pan.___", state 2394, "(1)"
+       line 416, "pan.___", state 2395, "(1)"
+       line 416, "pan.___", state 2395, "(1)"
+       line 414, "pan.___", state 2400, "((i<1))"
+       line 414, "pan.___", state 2400, "((i>=1))"
+       line 421, "pan.___", state 2407, "(1)"
+       line 421, "pan.___", state 2408, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 2408, "else"
+       line 421, "pan.___", state 2411, "(1)"
+       line 421, "pan.___", state 2412, "(1)"
+       line 421, "pan.___", state 2412, "(1)"
+       line 425, "pan.___", state 2420, "(1)"
+       line 425, "pan.___", state 2421, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 2421, "else"
+       line 425, "pan.___", state 2424, "(1)"
+       line 425, "pan.___", state 2425, "(1)"
+       line 425, "pan.___", state 2425, "(1)"
+       line 423, "pan.___", state 2430, "((i<2))"
+       line 423, "pan.___", state 2430, "((i>=2))"
+       line 430, "pan.___", state 2434, "(1)"
+       line 430, "pan.___", state 2434, "(1)"
+       line 629, "pan.___", state 2437, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 629, "pan.___", state 2438, "_proc_urcu_reader = (_proc_urcu_reader|(1<<23))"
+       line 629, "pan.___", state 2439, "(1)"
+       line 250, "pan.___", state 2443, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 250, "pan.___", state 2445, "(1)"
+       line 254, "pan.___", state 2452, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 2454, "(1)"
+       line 254, "pan.___", state 2455, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 254, "pan.___", state 2455, "else"
+       line 252, "pan.___", state 2460, "((i<1))"
+       line 252, "pan.___", state 2460, "((i>=1))"
+       line 258, "pan.___", state 2465, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 2467, "(1)"
+       line 258, "pan.___", state 2468, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 2468, "else"
+       line 262, "pan.___", state 2474, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 2476, "(1)"
+       line 262, "pan.___", state 2477, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 262, "pan.___", state 2477, "else"
+       line 260, "pan.___", state 2482, "((i<2))"
+       line 260, "pan.___", state 2482, "((i>=2))"
+       line 227, "pan.___", state 2490, "(1)"
+       line 231, "pan.___", state 2498, "(1)"
+       line 231, "pan.___", state 2499, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 2499, "else"
+       line 229, "pan.___", state 2504, "((i<1))"
+       line 229, "pan.___", state 2504, "((i>=1))"
+       line 235, "pan.___", state 2510, "(1)"
+       line 235, "pan.___", state 2511, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 2511, "else"
+       line 239, "pan.___", state 2518, "(1)"
+       line 239, "pan.___", state 2519, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 2519, "else"
+       line 244, "pan.___", state 2528, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 2528, "else"
+       line 277, "pan.___", state 2530, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 277, "pan.___", state 2530, "else"
+       line 395, "pan.___", state 2536, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2568, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2582, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2601, "(1)"
+       line 421, "pan.___", state 2631, "(1)"
+       line 425, "pan.___", state 2644, "(1)"
+       line 250, "pan.___", state 2668, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 250, "pan.___", state 2670, "(1)"
+       line 254, "pan.___", state 2677, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 2679, "(1)"
+       line 254, "pan.___", state 2680, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 254, "pan.___", state 2680, "else"
+       line 252, "pan.___", state 2685, "((i<1))"
+       line 252, "pan.___", state 2685, "((i>=1))"
+       line 258, "pan.___", state 2690, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 2692, "(1)"
+       line 258, "pan.___", state 2693, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 2693, "else"
+       line 262, "pan.___", state 2699, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 2701, "(1)"
+       line 262, "pan.___", state 2702, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 262, "pan.___", state 2702, "else"
+       line 260, "pan.___", state 2707, "((i<2))"
+       line 260, "pan.___", state 2707, "((i>=2))"
+       line 227, "pan.___", state 2715, "(1)"
+       line 231, "pan.___", state 2723, "(1)"
+       line 231, "pan.___", state 2724, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 2724, "else"
+       line 229, "pan.___", state 2729, "((i<1))"
+       line 229, "pan.___", state 2729, "((i>=1))"
+       line 235, "pan.___", state 2735, "(1)"
+       line 235, "pan.___", state 2736, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 2736, "else"
+       line 239, "pan.___", state 2743, "(1)"
+       line 239, "pan.___", state 2744, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 2744, "else"
+       line 244, "pan.___", state 2753, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 2753, "else"
+       line 277, "pan.___", state 2755, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 277, "pan.___", state 2755, "else"
+       line 395, "pan.___", state 2761, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2793, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2807, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2826, "(1)"
+       line 421, "pan.___", state 2856, "(1)"
+       line 425, "pan.___", state 2869, "(1)"
+       line 395, "pan.___", state 2890, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2922, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2936, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2955, "(1)"
+       line 421, "pan.___", state 2985, "(1)"
+       line 425, "pan.___", state 2998, "(1)"
+       line 227, "pan.___", state 3031, "(1)"
+       line 235, "pan.___", state 3051, "(1)"
+       line 239, "pan.___", state 3059, "(1)"
+       line 227, "pan.___", state 3074, "(1)"
+       line 235, "pan.___", state 3094, "(1)"
+       line 239, "pan.___", state 3102, "(1)"
+       line 877, "pan.___", state 3119, "-end-"
+       (363 of 3119 states)
+unreached in proctype urcu_writer
+       line 395, "pan.___", state 20, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 26, "(1)"
+       line 399, "pan.___", state 34, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 40, "(1)"
+       line 399, "pan.___", state 41, "(1)"
+       line 399, "pan.___", state 41, "(1)"
+       line 397, "pan.___", state 46, "((i<1))"
+       line 397, "pan.___", state 46, "((i>=1))"
+       line 404, "pan.___", state 52, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 58, "(1)"
+       line 404, "pan.___", state 59, "(1)"
+       line 404, "pan.___", state 59, "(1)"
+       line 408, "pan.___", state 72, "(1)"
+       line 408, "pan.___", state 73, "(1)"
+       line 408, "pan.___", state 73, "(1)"
+       line 406, "pan.___", state 78, "((i<2))"
+       line 406, "pan.___", state 78, "((i>=2))"
+       line 412, "pan.___", state 85, "(1)"
+       line 412, "pan.___", state 86, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 86, "else"
+       line 412, "pan.___", state 89, "(1)"
+       line 412, "pan.___", state 90, "(1)"
+       line 412, "pan.___", state 90, "(1)"
+       line 416, "pan.___", state 98, "(1)"
+       line 416, "pan.___", state 99, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 99, "else"
+       line 416, "pan.___", state 102, "(1)"
+       line 416, "pan.___", state 103, "(1)"
+       line 416, "pan.___", state 103, "(1)"
+       line 414, "pan.___", state 108, "((i<1))"
+       line 414, "pan.___", state 108, "((i>=1))"
+       line 421, "pan.___", state 115, "(1)"
+       line 421, "pan.___", state 116, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 116, "else"
+       line 421, "pan.___", state 119, "(1)"
+       line 421, "pan.___", state 120, "(1)"
+       line 421, "pan.___", state 120, "(1)"
+       line 425, "pan.___", state 128, "(1)"
+       line 425, "pan.___", state 129, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 129, "else"
+       line 425, "pan.___", state 132, "(1)"
+       line 425, "pan.___", state 133, "(1)"
+       line 425, "pan.___", state 133, "(1)"
+       line 423, "pan.___", state 138, "((i<2))"
+       line 423, "pan.___", state 138, "((i>=2))"
+       line 430, "pan.___", state 142, "(1)"
+       line 430, "pan.___", state 142, "(1)"
+       line 250, "pan.___", state 151, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 160, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 252, "pan.___", state 168, "((i<1))"
+       line 252, "pan.___", state 168, "((i>=1))"
+       line 258, "pan.___", state 173, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 1000, "pan.___", state 201, "old_data = cached_rcu_ptr.val[_pid]"
+       line 1011, "pan.___", state 205, "_proc_urcu_writer = (_proc_urcu_writer|(1<<4))"
+       line 395, "pan.___", state 213, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 219, "(1)"
+       line 399, "pan.___", state 227, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 233, "(1)"
+       line 399, "pan.___", state 234, "(1)"
+       line 399, "pan.___", state 234, "(1)"
+       line 397, "pan.___", state 239, "((i<1))"
+       line 397, "pan.___", state 239, "((i>=1))"
+       line 404, "pan.___", state 247, "(1)"
+       line 404, "pan.___", state 248, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 248, "else"
+       line 404, "pan.___", state 251, "(1)"
+       line 404, "pan.___", state 252, "(1)"
+       line 404, "pan.___", state 252, "(1)"
+       line 408, "pan.___", state 259, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 265, "(1)"
+       line 408, "pan.___", state 266, "(1)"
+       line 408, "pan.___", state 266, "(1)"
+       line 406, "pan.___", state 271, "((i<2))"
+       line 406, "pan.___", state 271, "((i>=2))"
+       line 412, "pan.___", state 278, "(1)"
+       line 412, "pan.___", state 279, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 279, "else"
+       line 412, "pan.___", state 282, "(1)"
+       line 412, "pan.___", state 283, "(1)"
+       line 412, "pan.___", state 283, "(1)"
+       line 416, "pan.___", state 291, "(1)"
+       line 416, "pan.___", state 292, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 292, "else"
+       line 416, "pan.___", state 295, "(1)"
+       line 416, "pan.___", state 296, "(1)"
+       line 416, "pan.___", state 296, "(1)"
+       line 414, "pan.___", state 301, "((i<1))"
+       line 414, "pan.___", state 301, "((i>=1))"
+       line 421, "pan.___", state 308, "(1)"
+       line 421, "pan.___", state 309, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 309, "else"
+       line 421, "pan.___", state 312, "(1)"
+       line 421, "pan.___", state 313, "(1)"
+       line 421, "pan.___", state 313, "(1)"
+       line 425, "pan.___", state 321, "(1)"
+       line 425, "pan.___", state 322, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 322, "else"
+       line 425, "pan.___", state 325, "(1)"
+       line 425, "pan.___", state 326, "(1)"
+       line 425, "pan.___", state 326, "(1)"
+       line 423, "pan.___", state 331, "((i<2))"
+       line 423, "pan.___", state 331, "((i>=2))"
+       line 430, "pan.___", state 335, "(1)"
+       line 430, "pan.___", state 335, "(1)"
+       line 395, "pan.___", state 346, "(1)"
+       line 395, "pan.___", state 347, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 347, "else"
+       line 395, "pan.___", state 350, "(1)"
+       line 399, "pan.___", state 358, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 364, "(1)"
+       line 399, "pan.___", state 365, "(1)"
+       line 399, "pan.___", state 365, "(1)"
+       line 397, "pan.___", state 370, "((i<1))"
+       line 397, "pan.___", state 370, "((i>=1))"
+       line 404, "pan.___", state 376, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 382, "(1)"
+       line 404, "pan.___", state 383, "(1)"
+       line 404, "pan.___", state 383, "(1)"
+       line 408, "pan.___", state 390, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 396, "(1)"
+       line 408, "pan.___", state 397, "(1)"
+       line 408, "pan.___", state 397, "(1)"
+       line 406, "pan.___", state 402, "((i<2))"
+       line 406, "pan.___", state 402, "((i>=2))"
+       line 412, "pan.___", state 409, "(1)"
+       line 412, "pan.___", state 410, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 410, "else"
+       line 412, "pan.___", state 413, "(1)"
+       line 412, "pan.___", state 414, "(1)"
+       line 412, "pan.___", state 414, "(1)"
+       line 416, "pan.___", state 422, "(1)"
+       line 416, "pan.___", state 423, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 423, "else"
+       line 416, "pan.___", state 426, "(1)"
+       line 416, "pan.___", state 427, "(1)"
+       line 416, "pan.___", state 427, "(1)"
+       line 414, "pan.___", state 432, "((i<1))"
+       line 414, "pan.___", state 432, "((i>=1))"
+       line 421, "pan.___", state 439, "(1)"
+       line 421, "pan.___", state 440, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 440, "else"
+       line 421, "pan.___", state 443, "(1)"
+       line 421, "pan.___", state 444, "(1)"
+       line 421, "pan.___", state 444, "(1)"
+       line 425, "pan.___", state 452, "(1)"
+       line 425, "pan.___", state 453, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 453, "else"
+       line 425, "pan.___", state 456, "(1)"
+       line 425, "pan.___", state 457, "(1)"
+       line 425, "pan.___", state 457, "(1)"
+       line 423, "pan.___", state 462, "((i<2))"
+       line 423, "pan.___", state 462, "((i>=2))"
+       line 430, "pan.___", state 466, "(1)"
+       line 430, "pan.___", state 466, "(1)"
+       line 1063, "pan.___", state 477, "_proc_urcu_writer = (_proc_urcu_writer&~(((1<<8)|(1<<7))))"
+       line 395, "pan.___", state 482, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 488, "(1)"
+       line 399, "pan.___", state 496, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 502, "(1)"
+       line 399, "pan.___", state 503, "(1)"
+       line 399, "pan.___", state 503, "(1)"
+       line 397, "pan.___", state 508, "((i<1))"
+       line 397, "pan.___", state 508, "((i>=1))"
+       line 404, "pan.___", state 514, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 520, "(1)"
+       line 404, "pan.___", state 521, "(1)"
+       line 404, "pan.___", state 521, "(1)"
+       line 408, "pan.___", state 528, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 534, "(1)"
+       line 408, "pan.___", state 535, "(1)"
+       line 408, "pan.___", state 535, "(1)"
+       line 406, "pan.___", state 540, "((i<2))"
+       line 406, "pan.___", state 540, "((i>=2))"
+       line 412, "pan.___", state 547, "(1)"
+       line 412, "pan.___", state 548, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 548, "else"
+       line 412, "pan.___", state 551, "(1)"
+       line 412, "pan.___", state 552, "(1)"
+       line 412, "pan.___", state 552, "(1)"
+       line 416, "pan.___", state 560, "(1)"
+       line 416, "pan.___", state 561, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 561, "else"
+       line 416, "pan.___", state 564, "(1)"
+       line 416, "pan.___", state 565, "(1)"
+       line 416, "pan.___", state 565, "(1)"
+       line 414, "pan.___", state 570, "((i<1))"
+       line 414, "pan.___", state 570, "((i>=1))"
+       line 421, "pan.___", state 577, "(1)"
+       line 421, "pan.___", state 578, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 578, "else"
+       line 421, "pan.___", state 581, "(1)"
+       line 421, "pan.___", state 582, "(1)"
+       line 421, "pan.___", state 582, "(1)"
+       line 425, "pan.___", state 590, "(1)"
+       line 425, "pan.___", state 591, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 591, "else"
+       line 425, "pan.___", state 594, "(1)"
+       line 425, "pan.___", state 595, "(1)"
+       line 425, "pan.___", state 595, "(1)"
+       line 430, "pan.___", state 604, "(1)"
+       line 430, "pan.___", state 604, "(1)"
+       line 395, "pan.___", state 611, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 625, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 643, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 676, "(1)"
+       line 416, "pan.___", state 689, "(1)"
+       line 421, "pan.___", state 706, "(1)"
+       line 425, "pan.___", state 719, "(1)"
+       line 399, "pan.___", state 756, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 774, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 788, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 820, "(1)"
+       line 421, "pan.___", state 837, "(1)"
+       line 425, "pan.___", state 850, "(1)"
+       line 1135, "pan.___", state 877, "_proc_urcu_writer = (_proc_urcu_writer|(1<<13))"
+       line 250, "pan.___", state 905, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 250, "pan.___", state 907, "(1)"
+       line 254, "pan.___", state 914, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 916, "(1)"
+       line 254, "pan.___", state 917, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 254, "pan.___", state 917, "else"
+       line 252, "pan.___", state 922, "((i<1))"
+       line 252, "pan.___", state 922, "((i>=1))"
+       line 258, "pan.___", state 927, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 929, "(1)"
+       line 258, "pan.___", state 930, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 930, "else"
+       line 262, "pan.___", state 936, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 938, "(1)"
+       line 262, "pan.___", state 939, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 262, "pan.___", state 939, "else"
+       line 260, "pan.___", state 944, "((i<2))"
+       line 260, "pan.___", state 944, "((i>=2))"
+       line 227, "pan.___", state 952, "(1)"
+       line 231, "pan.___", state 960, "(1)"
+       line 231, "pan.___", state 961, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 961, "else"
+       line 229, "pan.___", state 966, "((i<1))"
+       line 229, "pan.___", state 966, "((i>=1))"
+       line 235, "pan.___", state 972, "(1)"
+       line 235, "pan.___", state 973, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 973, "else"
+       line 239, "pan.___", state 980, "(1)"
+       line 239, "pan.___", state 981, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 981, "else"
+       line 244, "pan.___", state 990, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 990, "else"
+       line 277, "pan.___", state 992, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 277, "pan.___", state 992, "else"
+       line 250, "pan.___", state 996, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 250, "pan.___", state 998, "(1)"
+       line 254, "pan.___", state 1005, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1007, "(1)"
+       line 254, "pan.___", state 1008, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 254, "pan.___", state 1008, "else"
+       line 252, "pan.___", state 1013, "((i<1))"
+       line 252, "pan.___", state 1013, "((i>=1))"
+       line 258, "pan.___", state 1018, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1020, "(1)"
+       line 258, "pan.___", state 1021, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 1021, "else"
+       line 262, "pan.___", state 1027, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1029, "(1)"
+       line 262, "pan.___", state 1030, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 262, "pan.___", state 1030, "else"
+       line 260, "pan.___", state 1035, "((i<2))"
+       line 260, "pan.___", state 1035, "((i>=2))"
+       line 227, "pan.___", state 1043, "(1)"
+       line 231, "pan.___", state 1051, "(1)"
+       line 231, "pan.___", state 1052, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 1052, "else"
+       line 229, "pan.___", state 1057, "((i<1))"
+       line 229, "pan.___", state 1057, "((i>=1))"
+       line 235, "pan.___", state 1063, "(1)"
+       line 235, "pan.___", state 1064, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 1064, "else"
+       line 239, "pan.___", state 1071, "(1)"
+       line 239, "pan.___", state 1072, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 1072, "else"
+       line 244, "pan.___", state 1081, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 1081, "else"
+       line 277, "pan.___", state 1083, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 277, "pan.___", state 1083, "else"
+       line 254, "pan.___", state 1096, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1109, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1118, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1134, "(1)"
+       line 231, "pan.___", state 1142, "(1)"
+       line 235, "pan.___", state 1154, "(1)"
+       line 239, "pan.___", state 1162, "(1)"
+       line 250, "pan.___", state 1178, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 250, "pan.___", state 1180, "(1)"
+       line 254, "pan.___", state 1187, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1189, "(1)"
+       line 254, "pan.___", state 1190, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 254, "pan.___", state 1190, "else"
+       line 252, "pan.___", state 1195, "((i<1))"
+       line 252, "pan.___", state 1195, "((i>=1))"
+       line 258, "pan.___", state 1200, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1202, "(1)"
+       line 258, "pan.___", state 1203, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 1203, "else"
+       line 262, "pan.___", state 1209, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1211, "(1)"
+       line 262, "pan.___", state 1212, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 262, "pan.___", state 1212, "else"
+       line 260, "pan.___", state 1217, "((i<2))"
+       line 260, "pan.___", state 1217, "((i>=2))"
+       line 227, "pan.___", state 1225, "(1)"
+       line 231, "pan.___", state 1233, "(1)"
+       line 231, "pan.___", state 1234, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 1234, "else"
+       line 229, "pan.___", state 1239, "((i<1))"
+       line 229, "pan.___", state 1239, "((i>=1))"
+       line 235, "pan.___", state 1245, "(1)"
+       line 235, "pan.___", state 1246, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 1246, "else"
+       line 239, "pan.___", state 1253, "(1)"
+       line 239, "pan.___", state 1254, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 1254, "else"
+       line 244, "pan.___", state 1263, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 1263, "else"
+       line 277, "pan.___", state 1265, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 277, "pan.___", state 1265, "else"
+       line 1204, "pan.___", state 1268, "-end-"
+       (226 of 1268 states)
+unreached in proctype :init:
+       line 1215, "pan.___", state 9, "((j<2))"
+       line 1215, "pan.___", state 9, "((j>=2))"
+       line 1216, "pan.___", state 20, "((j<2))"
+       line 1216, "pan.___", state 20, "((j>=2))"
+       line 1221, "pan.___", state 33, "((j<2))"
+       line 1221, "pan.___", state 33, "((j>=2))"
+       line 1219, "pan.___", state 43, "((i<1))"
+       line 1219, "pan.___", state 43, "((i>=1))"
+       line 1229, "pan.___", state 54, "((j<2))"
+       line 1229, "pan.___", state 54, "((j>=2))"
+       line 1233, "pan.___", state 67, "((j<2))"
+       line 1233, "pan.___", state 67, "((j>=2))"
+       (6 of 78 states)
+unreached in proctype :never:
+       line 1263, "pan.___", state 8, "-end-"
+       (1 of 8 states)
+
+pan: elapsed time 632 seconds
+pan: rate  2628.547 states/second
+pan: avg transition delay 1.2347e-06 usec
+cp .input.spin urcu_free_no_mb.spin.input
+cp .input.spin.trail urcu_free_no_mb.spin.input.trail
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_mb.spin.input b/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_mb.spin.input
new file mode 100644 (file)
index 0000000..77b6cf8
--- /dev/null
@@ -0,0 +1,1240 @@
+#define NO_MB
+
+// Poison value for freed memory
+#define POISON 1
+// Memory with correct data
+#define WINE 0
+#define SLAB_SIZE 2
+
+#define read_poison    (data_read_first[0] == POISON || data_read_second[0] == POISON)
+
+#define RCU_GP_CTR_BIT (1 << 7)
+#define RCU_GP_CTR_NEST_MASK (RCU_GP_CTR_BIT - 1)
+
+//disabled
+//#define REMOTE_BARRIERS
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+typedef per_proc_bit {
+       bit val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bitfield {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bitfield cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               /*
+                * 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, j);
+               reader_barrier[get_readerid()] = 0;
+       :: 1 ->
+               /*
+                * 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)
+//#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);                                                           \
+       i = 0;                                                                  \
+       do                                                                      \
+       :: i < NR_READERS ->                                                    \
+               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.                                            \
+                */                                                             \
+               do                                                              \
+               :: (reader_barrier[i] == 1) ->                                  \
+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(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, smp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only one reader */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* RCU data */
+DECLARE_CACHED_VAR(bit, rcu_data[SLAB_SIZE]);
+
+/* RCU pointer */
+#if (SLAB_SIZE == 2)
+DECLARE_CACHED_VAR(bit, rcu_ptr);
+bit ptr_read_first[NR_READERS];
+bit ptr_read_second[NR_READERS];
+#else
+DECLARE_CACHED_VAR(byte, rcu_ptr);
+byte ptr_read_first[NR_READERS];
+byte ptr_read_second[NR_READERS];
+#endif
+
+bit data_read_first[NR_READERS];
+bit data_read_second[NR_READERS];
+
+bit init_done = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               ptr_read_first[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb1;
+rmb1_end:
+                               data_read_first[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_first[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               ptr_read_second[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb2;
+rmb2_end:
+                               data_read_second[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_second[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+rmb1:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb1_end;
+rmb2:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_DATA                     (1 << 1)
+#define WRITE_PROC_WMB                 (1 << 2)
+#define WRITE_XCHG_PTR                 (1 << 3)
+
+#define WRITE_PROC_FIRST_MB            (1 << 4)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 5)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 6)
+#define WRITE_PROC_FIRST_WAIT          (1 << 7)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 8)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 9)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 10)
+#define WRITE_PROC_SECOND_WAIT         (1 << 11)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 12)
+
+#define WRITE_PROC_SECOND_MB           (1 << 13)
+
+#define WRITE_FREE                     (1 << 14)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_DATA                    \
+                                       | WRITE_PROC_WMB                \
+                                       | WRITE_XCHG_PTR                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB          \
+                                       | WRITE_FREE)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 15) - 1)
+
+/*
+ * Mutexes are implied around writer execution. A single writer at a time.
+ */
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte cur_data = 0, old_data, loop_nr = 0;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (loop_nr < 3) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               loop_nr = loop_nr + 1;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_WMB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+#endif
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_DATA) ->
+                       ooo_mem(i);
+                       cur_data = (cur_data + 1) % SLAB_SIZE;
+                       WRITE_CACHED_VAR(rcu_data[cur_data], WINE);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_DATA);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA,
+                                 WRITE_PROC_WMB) ->
+                       smp_wmb(i, j);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_WMB,
+                                 WRITE_XCHG_PTR) ->
+                       /* rcu_xchg_pointer() */
+                       atomic {
+                               old_data = READ_CACHED_VAR(rcu_ptr);
+                               WRITE_CACHED_VAR(rcu_ptr, cur_data);
+                       }
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_XCHG_PTR);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_WMB      /* No dependency on
+                                                        * WRITE_DATA because we
+                                                        * write to a
+                                                        * different location. */
+                                 | WRITE_PROC_SECOND_MB
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_FREE) ->
+                       WRITE_CACHED_VAR(rcu_data[old_data], POISON);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_FREE);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+               /*
+                * Note : Promela model adds implicit serialization of the
+                * WRITE_FREE instruction. Normally, it would be permitted to
+                * spill on the next loop execution. Given the validation we do
+                * checks for the data entry read to be poisoned, it's ok if
+                * we do not check "late arriving" memory poisoning.
+                */
+       :: 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
+#ifdef READER_PROGRESS
+               /*
+                * Make sure we don't block the reader's progress.
+                */
+               smp_mb_send(i, j, 5);
+#endif
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(rcu_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       ptr_read_first[i] = 1;
+                       ptr_read_second[i] = 1;
+                       data_read_first[i] = WINE;
+                       data_read_second[i] = WINE;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               INIT_CACHED_VAR(rcu_data[0], WINE, j);
+               i = 1;
+               do
+               :: i < SLAB_SIZE ->
+                       INIT_CACHED_VAR(rcu_data[i], POISON, j);
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_mb.spin.input.trail b/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_mb.spin.input.trail
new file mode 100644 (file)
index 0000000..ea8ed03
--- /dev/null
@@ -0,0 +1,1227 @@
+-2:3:-2
+-4:-4:-4
+1:0:4467
+2:3:4387
+3:3:4390
+4:3:4390
+5:3:4393
+6:3:4401
+7:3:4401
+8:3:4404
+9:3:4410
+10:3:4414
+11:3:4414
+12:3:4417
+13:3:4427
+14:3:4435
+15:3:4435
+16:3:4438
+17:3:4444
+18:3:4448
+19:3:4448
+20:3:4451
+21:3:4457
+22:3:4461
+23:3:4462
+24:0:4467
+25:3:4464
+26:0:4467
+27:2:3121
+28:0:4467
+29:2:3127
+30:0:4467
+31:2:3128
+32:0:4467
+33:2:3130
+34:0:4467
+35:2:3131
+36:0:4467
+37:2:3132
+38:0:4467
+39:2:3133
+40:0:4467
+41:2:3134
+42:2:3135
+43:2:3139
+44:2:3140
+45:2:3148
+46:2:3149
+47:2:3153
+48:2:3154
+49:2:3162
+50:2:3167
+51:2:3171
+52:2:3172
+53:2:3180
+54:2:3181
+55:2:3185
+56:2:3186
+57:2:3180
+58:2:3181
+59:2:3185
+60:2:3186
+61:2:3194
+62:2:3199
+63:2:3200
+64:2:3211
+65:2:3212
+66:2:3213
+67:2:3224
+68:2:3229
+69:2:3230
+70:2:3241
+71:2:3242
+72:2:3243
+73:2:3241
+74:2:3242
+75:2:3243
+76:2:3254
+77:2:3262
+78:0:4467
+79:2:3133
+80:0:4467
+81:2:3266
+82:2:3270
+83:2:3271
+84:2:3275
+85:2:3279
+86:2:3280
+87:2:3284
+88:2:3292
+89:2:3293
+90:2:3297
+91:2:3301
+92:2:3302
+93:2:3297
+94:2:3298
+95:2:3306
+96:0:4467
+97:2:3133
+98:0:4467
+99:2:3314
+100:2:3315
+101:2:3316
+102:0:4467
+103:2:3133
+104:0:4467
+105:2:3324
+106:0:4467
+107:2:3133
+108:0:4467
+109:2:3327
+110:2:3328
+111:2:3332
+112:2:3333
+113:2:3341
+114:2:3342
+115:2:3346
+116:2:3347
+117:2:3355
+118:2:3360
+119:2:3361
+120:2:3373
+121:2:3374
+122:2:3378
+123:2:3379
+124:2:3373
+125:2:3374
+126:2:3378
+127:2:3379
+128:2:3387
+129:2:3392
+130:2:3393
+131:2:3404
+132:2:3405
+133:2:3406
+134:2:3417
+135:2:3422
+136:2:3423
+137:2:3434
+138:2:3435
+139:2:3436
+140:2:3434
+141:2:3435
+142:2:3436
+143:2:3447
+144:2:3454
+145:0:4467
+146:2:3133
+147:0:4467
+148:2:3458
+149:2:3459
+150:2:3460
+151:2:3472
+152:2:3473
+153:2:3477
+154:2:3478
+155:2:3486
+156:2:3491
+157:2:3495
+158:2:3496
+159:2:3504
+160:2:3505
+161:2:3509
+162:2:3510
+163:2:3504
+164:2:3505
+165:2:3509
+166:2:3510
+167:2:3518
+168:2:3523
+169:2:3524
+170:2:3535
+171:2:3536
+172:2:3537
+173:2:3548
+174:2:3553
+175:2:3554
+176:2:3565
+177:2:3566
+178:2:3567
+179:2:3565
+180:2:3566
+181:2:3567
+182:2:3578
+183:2:3589
+184:2:3590
+185:0:4467
+186:2:3133
+187:0:4467
+188:2:3596
+189:2:3597
+190:2:3601
+191:2:3602
+192:2:3610
+193:2:3611
+194:2:3615
+195:2:3616
+196:2:3624
+197:2:3629
+198:2:3633
+199:2:3634
+200:2:3642
+201:2:3643
+202:2:3647
+203:2:3648
+204:2:3642
+205:2:3643
+206:2:3647
+207:2:3648
+208:2:3656
+209:2:3661
+210:2:3662
+211:2:3673
+212:2:3674
+213:2:3675
+214:2:3686
+215:2:3691
+216:2:3692
+217:2:3703
+218:2:3704
+219:2:3705
+220:2:3703
+221:2:3704
+222:2:3705
+223:2:3716
+224:0:4467
+225:2:3133
+226:0:4467
+227:2:3725
+228:2:3726
+229:2:3730
+230:2:3731
+231:2:3739
+232:2:3740
+233:2:3744
+234:2:3745
+235:2:3753
+236:2:3758
+237:2:3762
+238:2:3763
+239:2:3771
+240:2:3772
+241:2:3776
+242:2:3777
+243:2:3771
+244:2:3772
+245:2:3776
+246:2:3777
+247:2:3785
+248:2:3790
+249:2:3791
+250:2:3802
+251:2:3803
+252:2:3804
+253:2:3815
+254:2:3820
+255:2:3821
+256:2:3832
+257:2:3833
+258:2:3834
+259:2:3832
+260:2:3833
+261:2:3834
+262:2:3845
+263:2:3852
+264:0:4467
+265:2:3133
+266:0:4467
+267:2:3856
+268:2:3857
+269:2:3858
+270:2:3870
+271:2:3871
+272:2:3875
+273:2:3876
+274:2:3884
+275:2:3889
+276:2:3893
+277:2:3894
+278:2:3902
+279:2:3903
+280:2:3907
+281:2:3908
+282:2:3902
+283:2:3903
+284:2:3907
+285:2:3908
+286:2:3916
+287:2:3921
+288:2:3922
+289:2:3933
+290:2:3934
+291:2:3935
+292:2:3946
+293:2:3951
+294:2:3952
+295:2:3963
+296:2:3964
+297:2:3965
+298:2:3963
+299:2:3964
+300:2:3965
+301:2:3976
+302:2:3986
+303:2:3987
+304:0:4467
+305:2:3133
+306:0:4467
+307:2:3996
+308:2:3997
+309:0:4467
+310:2:3133
+311:0:4467
+312:2:4001
+313:0:4467
+314:2:4009
+315:0:4467
+316:2:3128
+317:0:4467
+318:2:3130
+319:0:4467
+320:2:3131
+321:0:4467
+322:2:3132
+323:0:4467
+324:2:3133
+325:0:4467
+326:2:3134
+327:2:3135
+328:2:3139
+329:2:3140
+330:2:3148
+331:2:3149
+332:2:3153
+333:2:3154
+334:2:3162
+335:2:3167
+336:2:3171
+337:2:3172
+338:2:3180
+339:2:3181
+340:2:3182
+341:2:3180
+342:2:3181
+343:2:3185
+344:2:3186
+345:2:3194
+346:2:3199
+347:2:3200
+348:2:3211
+349:2:3212
+350:2:3213
+351:2:3224
+352:2:3229
+353:2:3230
+354:2:3241
+355:2:3242
+356:2:3243
+357:2:3241
+358:2:3242
+359:2:3243
+360:2:3254
+361:2:3262
+362:0:4467
+363:2:3133
+364:0:4467
+365:2:3266
+366:2:3270
+367:2:3271
+368:2:3275
+369:2:3279
+370:2:3280
+371:2:3284
+372:2:3292
+373:2:3293
+374:2:3297
+375:2:3298
+376:2:3297
+377:2:3301
+378:2:3302
+379:2:3306
+380:0:4467
+381:2:3133
+382:0:4467
+383:2:3314
+384:2:3315
+385:2:3316
+386:0:4467
+387:2:3133
+388:0:4467
+389:2:3324
+390:0:4467
+391:2:3133
+392:0:4467
+393:2:3327
+394:2:3328
+395:2:3332
+396:2:3333
+397:2:3341
+398:2:3342
+399:2:3346
+400:2:3347
+401:2:3355
+402:2:3360
+403:2:3361
+404:2:3373
+405:2:3374
+406:2:3378
+407:2:3379
+408:2:3373
+409:2:3374
+410:2:3378
+411:2:3379
+412:2:3387
+413:2:3392
+414:2:3393
+415:2:3404
+416:2:3405
+417:2:3406
+418:2:3417
+419:2:3422
+420:2:3423
+421:2:3434
+422:2:3435
+423:2:3436
+424:2:3434
+425:2:3435
+426:2:3436
+427:2:3447
+428:2:3454
+429:0:4467
+430:2:3133
+431:0:4467
+432:2:3458
+433:2:3459
+434:2:3460
+435:2:3472
+436:2:3473
+437:2:3477
+438:2:3478
+439:2:3486
+440:2:3491
+441:2:3495
+442:2:3496
+443:2:3504
+444:2:3505
+445:2:3509
+446:2:3510
+447:2:3504
+448:2:3505
+449:2:3509
+450:2:3510
+451:2:3518
+452:2:3523
+453:2:3524
+454:2:3535
+455:2:3536
+456:2:3537
+457:2:3548
+458:2:3553
+459:2:3554
+460:2:3565
+461:2:3566
+462:2:3567
+463:2:3565
+464:2:3566
+465:2:3567
+466:2:3578
+467:2:3589
+468:2:3590
+469:0:4467
+470:2:3133
+471:0:4467
+472:2:3596
+473:2:3597
+474:2:3601
+475:2:3602
+476:2:3610
+477:2:3611
+478:2:3615
+479:2:3616
+480:2:3624
+481:2:3629
+482:2:3633
+483:2:3634
+484:2:3642
+485:2:3643
+486:2:3647
+487:2:3648
+488:2:3642
+489:2:3643
+490:2:3647
+491:2:3648
+492:2:3656
+493:2:3661
+494:2:3662
+495:2:3673
+496:2:3674
+497:2:3675
+498:2:3686
+499:2:3691
+500:2:3692
+501:2:3703
+502:2:3704
+503:2:3705
+504:2:3703
+505:2:3704
+506:2:3705
+507:2:3716
+508:0:4467
+509:2:3133
+510:0:4467
+511:2:3725
+512:2:3726
+513:2:3730
+514:2:3731
+515:2:3739
+516:2:3740
+517:2:3744
+518:2:3745
+519:2:3753
+520:2:3758
+521:2:3762
+522:2:3763
+523:2:3771
+524:2:3772
+525:2:3776
+526:2:3777
+527:2:3771
+528:2:3772
+529:2:3776
+530:2:3777
+531:2:3785
+532:2:3790
+533:2:3791
+534:2:3802
+535:2:3803
+536:2:3804
+537:2:3815
+538:2:3820
+539:2:3821
+540:2:3832
+541:2:3833
+542:2:3834
+543:2:3832
+544:2:3833
+545:2:3834
+546:2:3845
+547:2:3852
+548:0:4467
+549:2:3133
+550:0:4467
+551:2:3856
+552:2:3857
+553:2:3858
+554:2:3870
+555:2:3871
+556:2:3875
+557:2:3876
+558:2:3884
+559:2:3889
+560:2:3893
+561:2:3894
+562:2:3902
+563:2:3903
+564:2:3907
+565:2:3908
+566:2:3902
+567:2:3903
+568:2:3907
+569:2:3908
+570:2:3916
+571:2:3921
+572:2:3922
+573:2:3933
+574:2:3934
+575:2:3935
+576:2:3946
+577:2:3951
+578:2:3952
+579:2:3963
+580:2:3964
+581:2:3965
+582:2:3963
+583:2:3964
+584:2:3965
+585:2:3976
+586:2:3986
+587:2:3987
+588:0:4467
+589:2:3133
+590:0:4467
+591:2:3996
+592:2:3997
+593:0:4467
+594:2:3133
+595:0:4467
+596:2:4001
+597:0:4467
+598:2:4009
+599:0:4467
+600:2:3128
+601:0:4467
+602:2:3130
+603:0:4467
+604:2:3131
+605:0:4467
+606:2:3132
+607:0:4467
+608:2:3133
+609:0:4467
+610:2:3134
+611:2:3135
+612:2:3139
+613:2:3140
+614:2:3148
+615:2:3149
+616:2:3153
+617:2:3154
+618:2:3162
+619:2:3167
+620:2:3171
+621:2:3172
+622:2:3180
+623:2:3181
+624:2:3185
+625:2:3186
+626:2:3180
+627:2:3181
+628:2:3182
+629:2:3194
+630:2:3199
+631:2:3200
+632:2:3211
+633:2:3212
+634:2:3213
+635:2:3224
+636:2:3229
+637:2:3230
+638:2:3241
+639:2:3242
+640:2:3243
+641:2:3241
+642:2:3242
+643:2:3243
+644:2:3254
+645:2:3262
+646:0:4467
+647:2:3133
+648:0:4467
+649:2:3266
+650:2:3270
+651:2:3271
+652:2:3275
+653:2:3279
+654:2:3280
+655:2:3284
+656:2:3292
+657:2:3293
+658:2:3297
+659:2:3301
+660:2:3302
+661:2:3297
+662:2:3298
+663:2:3306
+664:0:4467
+665:2:3133
+666:0:4467
+667:2:3314
+668:2:3315
+669:2:3316
+670:0:4467
+671:2:3133
+672:0:4467
+673:2:3324
+674:0:4467
+675:2:3133
+676:0:4467
+677:2:3327
+678:2:3328
+679:2:3332
+680:2:3333
+681:2:3341
+682:2:3342
+683:2:3346
+684:2:3347
+685:2:3355
+686:2:3360
+687:2:3361
+688:2:3373
+689:2:3374
+690:2:3378
+691:2:3379
+692:2:3373
+693:2:3374
+694:2:3378
+695:2:3379
+696:2:3387
+697:2:3392
+698:2:3393
+699:2:3404
+700:2:3405
+701:2:3406
+702:2:3417
+703:2:3422
+704:2:3423
+705:2:3434
+706:2:3435
+707:2:3436
+708:2:3434
+709:2:3435
+710:2:3436
+711:2:3447
+712:2:3454
+713:0:4467
+714:2:3133
+715:0:4467
+716:2:3458
+717:2:3459
+718:2:3460
+719:2:3472
+720:2:3473
+721:2:3477
+722:2:3478
+723:2:3486
+724:2:3491
+725:2:3495
+726:2:3496
+727:2:3504
+728:2:3505
+729:2:3509
+730:2:3510
+731:2:3504
+732:2:3505
+733:2:3509
+734:2:3510
+735:2:3518
+736:2:3523
+737:2:3524
+738:2:3535
+739:2:3536
+740:2:3537
+741:2:3548
+742:2:3553
+743:2:3554
+744:2:3565
+745:2:3566
+746:2:3567
+747:2:3565
+748:2:3566
+749:2:3567
+750:2:3578
+751:2:3589
+752:2:3590
+753:0:4467
+754:2:3133
+755:0:4467
+756:2:3596
+757:2:3597
+758:2:3601
+759:2:3602
+760:2:3610
+761:2:3611
+762:2:3615
+763:2:3616
+764:2:3624
+765:2:3629
+766:2:3633
+767:2:3634
+768:2:3642
+769:2:3643
+770:2:3647
+771:2:3648
+772:2:3642
+773:2:3643
+774:2:3647
+775:2:3648
+776:2:3656
+777:2:3661
+778:2:3662
+779:2:3673
+780:2:3674
+781:2:3675
+782:2:3686
+783:2:3691
+784:2:3692
+785:2:3703
+786:2:3704
+787:2:3705
+788:2:3703
+789:2:3704
+790:2:3705
+791:2:3716
+792:0:4467
+793:2:3133
+794:0:4467
+795:2:3856
+796:2:3857
+797:2:3861
+798:2:3862
+799:2:3870
+800:2:3871
+801:2:3875
+802:2:3876
+803:2:3884
+804:2:3889
+805:2:3893
+806:2:3894
+807:2:3902
+808:2:3903
+809:2:3907
+810:2:3908
+811:2:3902
+812:2:3903
+813:2:3907
+814:2:3908
+815:2:3916
+816:2:3921
+817:2:3922
+818:2:3933
+819:2:3934
+820:2:3935
+821:2:3946
+822:2:3951
+823:2:3952
+824:2:3963
+825:2:3964
+826:2:3965
+827:2:3963
+828:2:3964
+829:2:3965
+830:2:3976
+831:2:3986
+832:2:3987
+833:0:4467
+834:2:3133
+835:0:4467
+836:2:3996
+837:2:3997
+838:0:4467
+839:2:3133
+840:0:4467
+841:2:3725
+842:2:3726
+843:2:3730
+844:2:3731
+845:2:3739
+846:2:3740
+847:2:3744
+848:2:3745
+849:2:3753
+850:2:3758
+851:2:3762
+852:2:3763
+853:2:3771
+854:2:3772
+855:2:3773
+856:2:3771
+857:2:3772
+858:2:3776
+859:2:3777
+860:2:3785
+861:2:3790
+862:2:3791
+863:2:3802
+864:2:3803
+865:2:3804
+866:2:3815
+867:2:3820
+868:2:3821
+869:2:3832
+870:2:3833
+871:2:3834
+872:2:3832
+873:2:3833
+874:2:3834
+875:2:3845
+876:2:3852
+877:0:4467
+878:2:3133
+879:0:4467
+880:2:4001
+881:0:4467
+882:2:4009
+883:0:4467
+884:2:4010
+885:0:4467
+886:2:4015
+887:0:4467
+888:1:2
+889:0:4467
+890:2:4016
+891:0:4467
+892:1:8
+893:0:4467
+894:2:4015
+895:0:4467
+896:1:9
+897:0:4467
+898:2:4016
+899:0:4467
+900:1:10
+901:0:4467
+902:2:4015
+903:0:4467
+904:1:11
+905:0:4467
+906:2:4016
+907:0:4467
+908:1:12
+909:0:4467
+910:2:4015
+911:0:4467
+912:1:13
+913:0:4467
+914:2:4016
+915:0:4467
+916:1:14
+917:0:4467
+918:2:4015
+919:0:4467
+920:1:15
+921:0:4467
+922:2:4016
+923:0:4467
+924:1:16
+925:1:17
+926:1:21
+927:1:22
+928:1:30
+929:1:31
+930:1:35
+931:1:36
+932:1:44
+933:1:49
+934:1:53
+935:1:54
+936:1:62
+937:1:63
+938:1:67
+939:1:68
+940:1:62
+941:1:63
+942:1:67
+943:1:68
+944:1:76
+945:1:81
+946:1:82
+947:1:93
+948:1:94
+949:1:95
+950:1:106
+951:1:118
+952:1:119
+953:1:123
+954:1:124
+955:1:125
+956:1:123
+957:1:124
+958:1:125
+959:1:136
+960:0:4467
+961:2:4015
+962:0:4467
+963:1:15
+964:0:4467
+965:2:4016
+966:0:4467
+967:1:145
+968:1:146
+969:0:4467
+970:2:4015
+971:0:4467
+972:1:15
+973:0:4467
+974:2:4016
+975:0:4467
+976:1:152
+977:1:153
+978:1:157
+979:1:158
+980:1:166
+981:1:167
+982:1:171
+983:1:172
+984:1:180
+985:1:185
+986:1:189
+987:1:190
+988:1:198
+989:1:199
+990:1:203
+991:1:204
+992:1:198
+993:1:199
+994:1:203
+995:1:204
+996:1:212
+997:1:217
+998:1:218
+999:1:229
+1000:1:230
+1001:1:231
+1002:1:242
+1003:1:254
+1004:1:255
+1005:1:259
+1006:1:260
+1007:1:261
+1008:1:259
+1009:1:260
+1010:1:261
+1011:1:272
+1012:0:4467
+1013:2:4015
+1014:0:4467
+1015:1:15
+1016:0:4467
+1017:2:4016
+1018:0:4467
+1019:1:281
+1020:1:282
+1021:1:286
+1022:1:287
+1023:1:295
+1024:1:296
+1025:1:300
+1026:1:301
+1027:1:309
+1028:1:314
+1029:1:318
+1030:1:319
+1031:1:327
+1032:1:328
+1033:1:332
+1034:1:333
+1035:1:327
+1036:1:328
+1037:1:332
+1038:1:333
+1039:1:341
+1040:1:346
+1041:1:347
+1042:1:358
+1043:1:359
+1044:1:360
+1045:1:371
+1046:1:383
+1047:1:384
+1048:1:388
+1049:1:389
+1050:1:390
+1051:1:388
+1052:1:389
+1053:1:390
+1054:1:401
+1055:1:408
+1056:0:4467
+1057:2:4015
+1058:0:4467
+1059:1:15
+1060:0:4467
+1061:2:4016
+1062:0:4467
+1063:1:636
+1064:1:637
+1065:1:641
+1066:1:642
+1067:1:650
+1068:1:651
+1069:1:652
+1070:1:664
+1071:1:669
+1072:1:673
+1073:1:674
+1074:1:682
+1075:1:683
+1076:1:687
+1077:1:688
+1078:1:682
+1079:1:683
+1080:1:687
+1081:1:688
+1082:1:696
+1083:1:701
+1084:1:702
+1085:1:713
+1086:1:714
+1087:1:715
+1088:1:726
+1089:1:738
+1090:1:739
+1091:1:743
+1092:1:744
+1093:1:745
+1094:1:743
+1095:1:744
+1096:1:745
+1097:1:756
+1098:0:4467
+1099:2:4015
+1100:0:4467
+1101:1:15
+1102:0:4467
+1103:2:4016
+1104:0:4467
+1105:1:765
+1106:1:768
+1107:1:769
+1108:0:4467
+1109:2:4015
+1110:0:4467
+1111:1:15
+1112:0:4467
+1113:2:4016
+1114:0:4467
+1115:1:1032
+1116:1:1033
+1117:1:1037
+1118:1:1038
+1119:1:1046
+1120:1:1047
+1121:1:1051
+1122:1:1052
+1123:1:1060
+1124:1:1065
+1125:1:1069
+1126:1:1070
+1127:1:1078
+1128:1:1079
+1129:1:1083
+1130:1:1084
+1131:1:1078
+1132:1:1079
+1133:1:1083
+1134:1:1084
+1135:1:1092
+1136:1:1097
+1137:1:1098
+1138:1:1109
+1139:1:1110
+1140:1:1111
+1141:1:1122
+1142:1:1134
+1143:1:1135
+1144:1:1139
+1145:1:1140
+1146:1:1141
+1147:1:1139
+1148:1:1140
+1149:1:1141
+1150:1:1152
+1151:1:1159
+1152:1:1163
+1153:0:4467
+1154:2:4015
+1155:0:4467
+1156:1:15
+1157:0:4467
+1158:2:4016
+1159:0:4467
+1160:1:1164
+1161:1:1165
+1162:1:1169
+1163:1:1170
+1164:1:1178
+1165:1:1179
+1166:1:1180
+1167:1:1192
+1168:1:1197
+1169:1:1201
+1170:1:1202
+1171:1:1210
+1172:1:1211
+1173:1:1215
+1174:1:1216
+1175:1:1210
+1176:1:1211
+1177:1:1215
+1178:1:1216
+1179:1:1224
+1180:1:1229
+1181:1:1230
+1182:1:1241
+1183:1:1242
+1184:1:1243
+1185:1:1254
+1186:1:1266
+1187:1:1267
+1188:1:1271
+1189:1:1272
+1190:1:1273
+1191:1:1271
+1192:1:1272
+1193:1:1273
+1194:1:1284
+1195:0:4467
+1196:2:4015
+1197:0:4467
+1198:1:15
+1199:0:4467
+1200:2:4016
+1201:0:4467
+1202:1:1293
+1203:0:4467
+1204:2:4015
+1205:0:4467
+1206:1:3027
+1207:1:3034
+1208:1:3035
+1209:1:3042
+1210:1:3047
+1211:1:3054
+1212:1:3055
+1213:1:3054
+1214:1:3055
+1215:1:3062
+1216:1:3066
+1217:0:4467
+1218:2:4016
+1219:0:4467
+1220:1:1295
+1221:1:1296
+1222:0:4465
+1223:2:4015
+1224:0:4471
+1225:1:1135
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_rmb.define b/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_rmb.define
new file mode 100644 (file)
index 0000000..73e61a4
--- /dev/null
@@ -0,0 +1 @@
+#define NO_RMB
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_rmb.log b/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_rmb.log
new file mode 100644 (file)
index 0000000..c1be1de
--- /dev/null
@@ -0,0 +1,588 @@
+rm -f pan* trail.out .input.spin* *.spin.trail .input.define
+touch .input.define
+cat .input.define >> pan.ltl
+cat DEFINES >> pan.ltl
+spin -f "!(`cat urcu_free.ltl | grep -v ^//`)" >> pan.ltl
+cp urcu_free_no_rmb.define .input.define
+cat .input.define > .input.spin
+cat DEFINES >> .input.spin
+cat urcu.spin >> .input.spin
+rm -f .input.spin.trail
+spin -a -X -N pan.ltl .input.spin
+Exit-Status 0
+gcc -O2 -w -DHASH64 -o pan pan.c
+./pan -a -v -c1 -X -m10000000 -w20
+warning: for p.o. reduction to be valid the never claim must be stutter-invariant
+(never claims generated from LTL formulae are stutter-invariant)
+depth 0: Claim reached state 5 (line 1258)
+pan: claim violated! (at depth 1714)
+pan: wrote .input.spin.trail
+
+(Spin Version 5.1.7 -- 23 December 2008)
+Warning: Search not completed
+       + Partial Order Reduction
+
+Full statespace search for:
+       never claim             +
+       assertion violations    + (if within scope of claim)
+       acceptance   cycles     + (fairness disabled)
+       invalid end states      - (disabled by never claim)
+
+State-vector 88 byte, depth reached 4557, errors: 1
+   191938 states, stored
+ 81734116 states, matched
+ 81926054 transitions (= stored+matched)
+4.8026893e+08 atomic steps
+hash conflicts:   5624584 (resolved)
+
+Stats on memory usage (in Megabytes):
+   21.233      equivalent memory usage for states (stored*(State-vector + overhead))
+   16.849      actual memory usage for states (compression: 79.35%)
+               state-vector as stored = 64 byte + 28 byte overhead
+    8.000      memory used for hash table (-w20)
+  457.764      memory used for DFS stack (-m10000000)
+  482.561      total actual memory usage
+
+unreached in proctype urcu_reader
+       line 395, "pan.___", state 17, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 49, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 63, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 82, "(1)"
+       line 421, "pan.___", state 112, "(1)"
+       line 425, "pan.___", state 125, "(1)"
+       line 576, "pan.___", state 146, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<1))"
+       line 395, "pan.___", state 153, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 185, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 199, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 218, "(1)"
+       line 421, "pan.___", state 248, "(1)"
+       line 425, "pan.___", state 261, "(1)"
+       line 395, "pan.___", state 282, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 314, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 328, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 347, "(1)"
+       line 421, "pan.___", state 377, "(1)"
+       line 425, "pan.___", state 390, "(1)"
+       line 395, "pan.___", state 413, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 415, "(1)"
+       line 395, "pan.___", state 416, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 416, "else"
+       line 395, "pan.___", state 419, "(1)"
+       line 399, "pan.___", state 427, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 429, "(1)"
+       line 399, "pan.___", state 430, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 430, "else"
+       line 399, "pan.___", state 433, "(1)"
+       line 399, "pan.___", state 434, "(1)"
+       line 399, "pan.___", state 434, "(1)"
+       line 397, "pan.___", state 439, "((i<1))"
+       line 397, "pan.___", state 439, "((i>=1))"
+       line 404, "pan.___", state 445, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 447, "(1)"
+       line 404, "pan.___", state 448, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 448, "else"
+       line 404, "pan.___", state 451, "(1)"
+       line 404, "pan.___", state 452, "(1)"
+       line 404, "pan.___", state 452, "(1)"
+       line 408, "pan.___", state 459, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 461, "(1)"
+       line 408, "pan.___", state 462, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 462, "else"
+       line 408, "pan.___", state 465, "(1)"
+       line 408, "pan.___", state 466, "(1)"
+       line 408, "pan.___", state 466, "(1)"
+       line 406, "pan.___", state 471, "((i<2))"
+       line 406, "pan.___", state 471, "((i>=2))"
+       line 412, "pan.___", state 478, "(1)"
+       line 412, "pan.___", state 479, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 479, "else"
+       line 412, "pan.___", state 482, "(1)"
+       line 412, "pan.___", state 483, "(1)"
+       line 412, "pan.___", state 483, "(1)"
+       line 416, "pan.___", state 491, "(1)"
+       line 416, "pan.___", state 492, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 492, "else"
+       line 416, "pan.___", state 495, "(1)"
+       line 416, "pan.___", state 496, "(1)"
+       line 416, "pan.___", state 496, "(1)"
+       line 414, "pan.___", state 501, "((i<1))"
+       line 414, "pan.___", state 501, "((i>=1))"
+       line 421, "pan.___", state 508, "(1)"
+       line 421, "pan.___", state 509, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 509, "else"
+       line 421, "pan.___", state 512, "(1)"
+       line 421, "pan.___", state 513, "(1)"
+       line 421, "pan.___", state 513, "(1)"
+       line 425, "pan.___", state 521, "(1)"
+       line 425, "pan.___", state 522, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 522, "else"
+       line 425, "pan.___", state 525, "(1)"
+       line 425, "pan.___", state 526, "(1)"
+       line 425, "pan.___", state 526, "(1)"
+       line 423, "pan.___", state 531, "((i<2))"
+       line 423, "pan.___", state 531, "((i>=2))"
+       line 430, "pan.___", state 535, "(1)"
+       line 430, "pan.___", state 535, "(1)"
+       line 576, "pan.___", state 538, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 576, "pan.___", state 539, "_proc_urcu_reader = (_proc_urcu_reader|(1<<5))"
+       line 576, "pan.___", state 540, "(1)"
+       line 250, "pan.___", state 544, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 555, "(1)"
+       line 258, "pan.___", state 566, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 575, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 591, "(1)"
+       line 231, "pan.___", state 599, "(1)"
+       line 235, "pan.___", state 611, "(1)"
+       line 239, "pan.___", state 619, "(1)"
+       line 395, "pan.___", state 637, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 651, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 669, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 683, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 702, "(1)"
+       line 416, "pan.___", state 715, "(1)"
+       line 421, "pan.___", state 732, "(1)"
+       line 425, "pan.___", state 745, "(1)"
+       line 395, "pan.___", state 773, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 775, "(1)"
+       line 395, "pan.___", state 776, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 776, "else"
+       line 395, "pan.___", state 779, "(1)"
+       line 399, "pan.___", state 787, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 789, "(1)"
+       line 399, "pan.___", state 790, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 790, "else"
+       line 399, "pan.___", state 793, "(1)"
+       line 399, "pan.___", state 794, "(1)"
+       line 399, "pan.___", state 794, "(1)"
+       line 397, "pan.___", state 799, "((i<1))"
+       line 397, "pan.___", state 799, "((i>=1))"
+       line 404, "pan.___", state 805, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 807, "(1)"
+       line 404, "pan.___", state 808, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 808, "else"
+       line 404, "pan.___", state 811, "(1)"
+       line 404, "pan.___", state 812, "(1)"
+       line 404, "pan.___", state 812, "(1)"
+       line 408, "pan.___", state 819, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 821, "(1)"
+       line 408, "pan.___", state 822, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 822, "else"
+       line 408, "pan.___", state 825, "(1)"
+       line 408, "pan.___", state 826, "(1)"
+       line 408, "pan.___", state 826, "(1)"
+       line 406, "pan.___", state 831, "((i<2))"
+       line 406, "pan.___", state 831, "((i>=2))"
+       line 412, "pan.___", state 838, "(1)"
+       line 412, "pan.___", state 839, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 839, "else"
+       line 412, "pan.___", state 842, "(1)"
+       line 412, "pan.___", state 843, "(1)"
+       line 412, "pan.___", state 843, "(1)"
+       line 416, "pan.___", state 851, "(1)"
+       line 416, "pan.___", state 852, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 852, "else"
+       line 416, "pan.___", state 855, "(1)"
+       line 416, "pan.___", state 856, "(1)"
+       line 416, "pan.___", state 856, "(1)"
+       line 414, "pan.___", state 861, "((i<1))"
+       line 414, "pan.___", state 861, "((i>=1))"
+       line 421, "pan.___", state 868, "(1)"
+       line 421, "pan.___", state 869, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 869, "else"
+       line 421, "pan.___", state 872, "(1)"
+       line 421, "pan.___", state 873, "(1)"
+       line 421, "pan.___", state 873, "(1)"
+       line 425, "pan.___", state 881, "(1)"
+       line 425, "pan.___", state 882, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 882, "else"
+       line 425, "pan.___", state 885, "(1)"
+       line 425, "pan.___", state 886, "(1)"
+       line 425, "pan.___", state 886, "(1)"
+       line 430, "pan.___", state 895, "(1)"
+       line 430, "pan.___", state 895, "(1)"
+       line 395, "pan.___", state 902, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 904, "(1)"
+       line 395, "pan.___", state 905, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 905, "else"
+       line 395, "pan.___", state 908, "(1)"
+       line 399, "pan.___", state 916, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 918, "(1)"
+       line 399, "pan.___", state 919, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 919, "else"
+       line 399, "pan.___", state 922, "(1)"
+       line 399, "pan.___", state 923, "(1)"
+       line 399, "pan.___", state 923, "(1)"
+       line 397, "pan.___", state 928, "((i<1))"
+       line 397, "pan.___", state 928, "((i>=1))"
+       line 404, "pan.___", state 934, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 936, "(1)"
+       line 404, "pan.___", state 937, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 937, "else"
+       line 404, "pan.___", state 940, "(1)"
+       line 404, "pan.___", state 941, "(1)"
+       line 404, "pan.___", state 941, "(1)"
+       line 408, "pan.___", state 948, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 950, "(1)"
+       line 408, "pan.___", state 951, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 951, "else"
+       line 408, "pan.___", state 954, "(1)"
+       line 408, "pan.___", state 955, "(1)"
+       line 408, "pan.___", state 955, "(1)"
+       line 406, "pan.___", state 960, "((i<2))"
+       line 406, "pan.___", state 960, "((i>=2))"
+       line 412, "pan.___", state 967, "(1)"
+       line 412, "pan.___", state 968, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 968, "else"
+       line 412, "pan.___", state 971, "(1)"
+       line 412, "pan.___", state 972, "(1)"
+       line 412, "pan.___", state 972, "(1)"
+       line 416, "pan.___", state 980, "(1)"
+       line 416, "pan.___", state 981, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 981, "else"
+       line 416, "pan.___", state 984, "(1)"
+       line 416, "pan.___", state 985, "(1)"
+       line 416, "pan.___", state 985, "(1)"
+       line 414, "pan.___", state 990, "((i<1))"
+       line 414, "pan.___", state 990, "((i>=1))"
+       line 421, "pan.___", state 997, "(1)"
+       line 421, "pan.___", state 998, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 998, "else"
+       line 421, "pan.___", state 1001, "(1)"
+       line 421, "pan.___", state 1002, "(1)"
+       line 421, "pan.___", state 1002, "(1)"
+       line 425, "pan.___", state 1010, "(1)"
+       line 425, "pan.___", state 1011, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 1011, "else"
+       line 425, "pan.___", state 1014, "(1)"
+       line 425, "pan.___", state 1015, "(1)"
+       line 425, "pan.___", state 1015, "(1)"
+       line 423, "pan.___", state 1020, "((i<2))"
+       line 423, "pan.___", state 1020, "((i>=2))"
+       line 430, "pan.___", state 1024, "(1)"
+       line 430, "pan.___", state 1024, "(1)"
+       line 584, "pan.___", state 1028, "_proc_urcu_reader = (_proc_urcu_reader|(1<<11))"
+       line 395, "pan.___", state 1033, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 1047, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1065, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1079, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1098, "(1)"
+       line 416, "pan.___", state 1111, "(1)"
+       line 421, "pan.___", state 1128, "(1)"
+       line 425, "pan.___", state 1141, "(1)"
+       line 395, "pan.___", state 1165, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1197, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1211, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1230, "(1)"
+       line 421, "pan.___", state 1260, "(1)"
+       line 425, "pan.___", state 1273, "(1)"
+       line 395, "pan.___", state 1298, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1330, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1344, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1363, "(1)"
+       line 421, "pan.___", state 1393, "(1)"
+       line 425, "pan.___", state 1406, "(1)"
+       line 395, "pan.___", state 1427, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1459, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1473, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1492, "(1)"
+       line 421, "pan.___", state 1522, "(1)"
+       line 425, "pan.___", state 1535, "(1)"
+       line 250, "pan.___", state 1558, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1580, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1589, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1605, "(1)"
+       line 231, "pan.___", state 1613, "(1)"
+       line 235, "pan.___", state 1625, "(1)"
+       line 239, "pan.___", state 1633, "(1)"
+       line 395, "pan.___", state 1651, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 1665, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1683, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1697, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1716, "(1)"
+       line 416, "pan.___", state 1729, "(1)"
+       line 421, "pan.___", state 1746, "(1)"
+       line 425, "pan.___", state 1759, "(1)"
+       line 395, "pan.___", state 1780, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 1794, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1812, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1826, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1845, "(1)"
+       line 416, "pan.___", state 1858, "(1)"
+       line 421, "pan.___", state 1875, "(1)"
+       line 425, "pan.___", state 1888, "(1)"
+       line 395, "pan.___", state 1912, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 1928, "(1)"
+       line 404, "pan.___", state 1944, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1958, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1977, "(1)"
+       line 421, "pan.___", state 2007, "(1)"
+       line 425, "pan.___", state 2020, "(1)"
+       line 623, "pan.___", state 2041, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<19))"
+       line 395, "pan.___", state 2048, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2080, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2094, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2113, "(1)"
+       line 421, "pan.___", state 2143, "(1)"
+       line 425, "pan.___", state 2156, "(1)"
+       line 395, "pan.___", state 2177, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2209, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2223, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2242, "(1)"
+       line 421, "pan.___", state 2272, "(1)"
+       line 425, "pan.___", state 2285, "(1)"
+       line 395, "pan.___", state 2308, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 2310, "(1)"
+       line 395, "pan.___", state 2311, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 2311, "else"
+       line 395, "pan.___", state 2314, "(1)"
+       line 399, "pan.___", state 2322, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 2324, "(1)"
+       line 399, "pan.___", state 2325, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 2325, "else"
+       line 399, "pan.___", state 2328, "(1)"
+       line 399, "pan.___", state 2329, "(1)"
+       line 399, "pan.___", state 2329, "(1)"
+       line 397, "pan.___", state 2334, "((i<1))"
+       line 397, "pan.___", state 2334, "((i>=1))"
+       line 404, "pan.___", state 2340, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2342, "(1)"
+       line 404, "pan.___", state 2343, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 2343, "else"
+       line 404, "pan.___", state 2346, "(1)"
+       line 404, "pan.___", state 2347, "(1)"
+       line 404, "pan.___", state 2347, "(1)"
+       line 408, "pan.___", state 2354, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2356, "(1)"
+       line 408, "pan.___", state 2357, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 2357, "else"
+       line 408, "pan.___", state 2360, "(1)"
+       line 408, "pan.___", state 2361, "(1)"
+       line 408, "pan.___", state 2361, "(1)"
+       line 406, "pan.___", state 2366, "((i<2))"
+       line 406, "pan.___", state 2366, "((i>=2))"
+       line 412, "pan.___", state 2373, "(1)"
+       line 412, "pan.___", state 2374, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 2374, "else"
+       line 412, "pan.___", state 2377, "(1)"
+       line 412, "pan.___", state 2378, "(1)"
+       line 412, "pan.___", state 2378, "(1)"
+       line 416, "pan.___", state 2386, "(1)"
+       line 416, "pan.___", state 2387, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 2387, "else"
+       line 416, "pan.___", state 2390, "(1)"
+       line 416, "pan.___", state 2391, "(1)"
+       line 416, "pan.___", state 2391, "(1)"
+       line 414, "pan.___", state 2396, "((i<1))"
+       line 414, "pan.___", state 2396, "((i>=1))"
+       line 421, "pan.___", state 2403, "(1)"
+       line 421, "pan.___", state 2404, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 2404, "else"
+       line 421, "pan.___", state 2407, "(1)"
+       line 421, "pan.___", state 2408, "(1)"
+       line 421, "pan.___", state 2408, "(1)"
+       line 425, "pan.___", state 2416, "(1)"
+       line 425, "pan.___", state 2417, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 2417, "else"
+       line 425, "pan.___", state 2420, "(1)"
+       line 425, "pan.___", state 2421, "(1)"
+       line 425, "pan.___", state 2421, "(1)"
+       line 423, "pan.___", state 2426, "((i<2))"
+       line 423, "pan.___", state 2426, "((i>=2))"
+       line 430, "pan.___", state 2430, "(1)"
+       line 430, "pan.___", state 2430, "(1)"
+       line 623, "pan.___", state 2433, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 623, "pan.___", state 2434, "_proc_urcu_reader = (_proc_urcu_reader|(1<<23))"
+       line 623, "pan.___", state 2435, "(1)"
+       line 250, "pan.___", state 2439, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 2450, "(1)"
+       line 258, "pan.___", state 2461, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 2470, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 2486, "(1)"
+       line 231, "pan.___", state 2494, "(1)"
+       line 235, "pan.___", state 2506, "(1)"
+       line 239, "pan.___", state 2514, "(1)"
+       line 395, "pan.___", state 2532, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 2546, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2564, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2578, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2597, "(1)"
+       line 416, "pan.___", state 2610, "(1)"
+       line 421, "pan.___", state 2627, "(1)"
+       line 425, "pan.___", state 2640, "(1)"
+       line 250, "pan.___", state 2664, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 2673, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 2686, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 2695, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 2711, "(1)"
+       line 231, "pan.___", state 2719, "(1)"
+       line 235, "pan.___", state 2731, "(1)"
+       line 239, "pan.___", state 2739, "(1)"
+       line 395, "pan.___", state 2757, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 2771, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2789, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2803, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2822, "(1)"
+       line 416, "pan.___", state 2835, "(1)"
+       line 421, "pan.___", state 2852, "(1)"
+       line 425, "pan.___", state 2865, "(1)"
+       line 395, "pan.___", state 2886, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 2900, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2918, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2932, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2951, "(1)"
+       line 416, "pan.___", state 2964, "(1)"
+       line 421, "pan.___", state 2981, "(1)"
+       line 425, "pan.___", state 2994, "(1)"
+       line 395, "pan.___", state 3027, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 3059, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 3073, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 3092, "(1)"
+       line 421, "pan.___", state 3122, "(1)"
+       line 425, "pan.___", state 3135, "(1)"
+       line 395, "pan.___", state 3154, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 3168, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 3186, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 3200, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 3219, "(1)"
+       line 416, "pan.___", state 3232, "(1)"
+       line 421, "pan.___", state 3249, "(1)"
+       line 425, "pan.___", state 3262, "(1)"
+       line 877, "pan.___", state 3283, "-end-"
+       (325 of 3283 states)
+unreached in proctype urcu_writer
+       line 395, "pan.___", state 18, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 24, "(1)"
+       line 399, "pan.___", state 32, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 38, "(1)"
+       line 399, "pan.___", state 39, "(1)"
+       line 399, "pan.___", state 39, "(1)"
+       line 397, "pan.___", state 44, "((i<1))"
+       line 397, "pan.___", state 44, "((i>=1))"
+       line 404, "pan.___", state 50, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 56, "(1)"
+       line 404, "pan.___", state 57, "(1)"
+       line 404, "pan.___", state 57, "(1)"
+       line 408, "pan.___", state 70, "(1)"
+       line 408, "pan.___", state 71, "(1)"
+       line 408, "pan.___", state 71, "(1)"
+       line 406, "pan.___", state 76, "((i<2))"
+       line 406, "pan.___", state 76, "((i>=2))"
+       line 412, "pan.___", state 83, "(1)"
+       line 412, "pan.___", state 84, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 84, "else"
+       line 412, "pan.___", state 87, "(1)"
+       line 412, "pan.___", state 88, "(1)"
+       line 412, "pan.___", state 88, "(1)"
+       line 416, "pan.___", state 96, "(1)"
+       line 416, "pan.___", state 97, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 97, "else"
+       line 416, "pan.___", state 100, "(1)"
+       line 416, "pan.___", state 101, "(1)"
+       line 416, "pan.___", state 101, "(1)"
+       line 414, "pan.___", state 106, "((i<1))"
+       line 414, "pan.___", state 106, "((i>=1))"
+       line 421, "pan.___", state 113, "(1)"
+       line 421, "pan.___", state 114, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 114, "else"
+       line 421, "pan.___", state 117, "(1)"
+       line 421, "pan.___", state 118, "(1)"
+       line 421, "pan.___", state 118, "(1)"
+       line 425, "pan.___", state 126, "(1)"
+       line 425, "pan.___", state 127, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 127, "else"
+       line 425, "pan.___", state 130, "(1)"
+       line 425, "pan.___", state 131, "(1)"
+       line 425, "pan.___", state 131, "(1)"
+       line 423, "pan.___", state 136, "((i<2))"
+       line 423, "pan.___", state 136, "((i>=2))"
+       line 430, "pan.___", state 140, "(1)"
+       line 430, "pan.___", state 140, "(1)"
+       line 250, "pan.___", state 149, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 158, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 171, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 211, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 225, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 243, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 257, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 276, "(1)"
+       line 416, "pan.___", state 289, "(1)"
+       line 421, "pan.___", state 306, "(1)"
+       line 425, "pan.___", state 319, "(1)"
+       line 399, "pan.___", state 356, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 374, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 388, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 420, "(1)"
+       line 421, "pan.___", state 437, "(1)"
+       line 425, "pan.___", state 450, "(1)"
+       line 399, "pan.___", state 494, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 512, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 526, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 558, "(1)"
+       line 421, "pan.___", state 575, "(1)"
+       line 425, "pan.___", state 588, "(1)"
+       line 399, "pan.___", state 623, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 641, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 655, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 687, "(1)"
+       line 421, "pan.___", state 704, "(1)"
+       line 425, "pan.___", state 717, "(1)"
+       line 399, "pan.___", state 754, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 772, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 786, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 818, "(1)"
+       line 421, "pan.___", state 835, "(1)"
+       line 425, "pan.___", state 848, "(1)"
+       line 250, "pan.___", state 903, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 912, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 927, "(1)"
+       line 262, "pan.___", state 934, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 950, "(1)"
+       line 231, "pan.___", state 958, "(1)"
+       line 235, "pan.___", state 970, "(1)"
+       line 239, "pan.___", state 978, "(1)"
+       line 254, "pan.___", state 1003, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1016, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1025, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1041, "(1)"
+       line 231, "pan.___", state 1049, "(1)"
+       line 235, "pan.___", state 1061, "(1)"
+       line 239, "pan.___", state 1069, "(1)"
+       line 254, "pan.___", state 1094, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1107, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1116, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1132, "(1)"
+       line 231, "pan.___", state 1140, "(1)"
+       line 235, "pan.___", state 1152, "(1)"
+       line 239, "pan.___", state 1160, "(1)"
+       line 254, "pan.___", state 1185, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1198, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1207, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1223, "(1)"
+       line 231, "pan.___", state 1231, "(1)"
+       line 235, "pan.___", state 1243, "(1)"
+       line 239, "pan.___", state 1251, "(1)"
+       line 1204, "pan.___", state 1266, "-end-"
+       (96 of 1266 states)
+unreached in proctype :init:
+       line 1215, "pan.___", state 9, "((j<2))"
+       line 1215, "pan.___", state 9, "((j>=2))"
+       line 1216, "pan.___", state 20, "((j<2))"
+       line 1216, "pan.___", state 20, "((j>=2))"
+       line 1221, "pan.___", state 33, "((j<2))"
+       line 1221, "pan.___", state 33, "((j>=2))"
+       line 1219, "pan.___", state 43, "((i<1))"
+       line 1219, "pan.___", state 43, "((i>=1))"
+       line 1229, "pan.___", state 54, "((j<2))"
+       line 1229, "pan.___", state 54, "((j>=2))"
+       line 1233, "pan.___", state 67, "((j<2))"
+       line 1233, "pan.___", state 67, "((j>=2))"
+       (6 of 78 states)
+unreached in proctype :never:
+       line 1263, "pan.___", state 8, "-end-"
+       (1 of 8 states)
+
+pan: elapsed time 102 seconds
+pan: rate 1874.9438 states/second
+pan: avg transition delay 1.2495e-06 usec
+cp .input.spin urcu_free_no_rmb.spin.input
+cp .input.spin.trail urcu_free_no_rmb.spin.input.trail
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_rmb.spin.input b/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_rmb.spin.input
new file mode 100644 (file)
index 0000000..2d07e51
--- /dev/null
@@ -0,0 +1,1240 @@
+#define NO_RMB
+
+// Poison value for freed memory
+#define POISON 1
+// Memory with correct data
+#define WINE 0
+#define SLAB_SIZE 2
+
+#define read_poison    (data_read_first[0] == POISON || data_read_second[0] == POISON)
+
+#define RCU_GP_CTR_BIT (1 << 7)
+#define RCU_GP_CTR_NEST_MASK (RCU_GP_CTR_BIT - 1)
+
+//disabled
+//#define REMOTE_BARRIERS
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+typedef per_proc_bit {
+       bit val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bitfield {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bitfield cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               /*
+                * 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, j);
+               reader_barrier[get_readerid()] = 0;
+       :: 1 ->
+               /*
+                * 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)
+//#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);                                                           \
+       i = 0;                                                                  \
+       do                                                                      \
+       :: i < NR_READERS ->                                                    \
+               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.                                            \
+                */                                                             \
+               do                                                              \
+               :: (reader_barrier[i] == 1) ->                                  \
+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(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, smp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only one reader */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* RCU data */
+DECLARE_CACHED_VAR(bit, rcu_data[SLAB_SIZE]);
+
+/* RCU pointer */
+#if (SLAB_SIZE == 2)
+DECLARE_CACHED_VAR(bit, rcu_ptr);
+bit ptr_read_first[NR_READERS];
+bit ptr_read_second[NR_READERS];
+#else
+DECLARE_CACHED_VAR(byte, rcu_ptr);
+byte ptr_read_first[NR_READERS];
+byte ptr_read_second[NR_READERS];
+#endif
+
+bit data_read_first[NR_READERS];
+bit data_read_second[NR_READERS];
+
+bit init_done = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               ptr_read_first[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb1;
+rmb1_end:
+                               data_read_first[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_first[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               ptr_read_second[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb2;
+rmb2_end:
+                               data_read_second[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_second[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+rmb1:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb1_end;
+rmb2:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_DATA                     (1 << 1)
+#define WRITE_PROC_WMB                 (1 << 2)
+#define WRITE_XCHG_PTR                 (1 << 3)
+
+#define WRITE_PROC_FIRST_MB            (1 << 4)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 5)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 6)
+#define WRITE_PROC_FIRST_WAIT          (1 << 7)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 8)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 9)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 10)
+#define WRITE_PROC_SECOND_WAIT         (1 << 11)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 12)
+
+#define WRITE_PROC_SECOND_MB           (1 << 13)
+
+#define WRITE_FREE                     (1 << 14)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_DATA                    \
+                                       | WRITE_PROC_WMB                \
+                                       | WRITE_XCHG_PTR                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB          \
+                                       | WRITE_FREE)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 15) - 1)
+
+/*
+ * Mutexes are implied around writer execution. A single writer at a time.
+ */
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte cur_data = 0, old_data, loop_nr = 0;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (loop_nr < 3) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               loop_nr = loop_nr + 1;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_WMB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+#endif
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_DATA) ->
+                       ooo_mem(i);
+                       cur_data = (cur_data + 1) % SLAB_SIZE;
+                       WRITE_CACHED_VAR(rcu_data[cur_data], WINE);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_DATA);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA,
+                                 WRITE_PROC_WMB) ->
+                       smp_wmb(i, j);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_WMB,
+                                 WRITE_XCHG_PTR) ->
+                       /* rcu_xchg_pointer() */
+                       atomic {
+                               old_data = READ_CACHED_VAR(rcu_ptr);
+                               WRITE_CACHED_VAR(rcu_ptr, cur_data);
+                       }
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_XCHG_PTR);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_WMB      /* No dependency on
+                                                        * WRITE_DATA because we
+                                                        * write to a
+                                                        * different location. */
+                                 | WRITE_PROC_SECOND_MB
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_FREE) ->
+                       WRITE_CACHED_VAR(rcu_data[old_data], POISON);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_FREE);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+               /*
+                * Note : Promela model adds implicit serialization of the
+                * WRITE_FREE instruction. Normally, it would be permitted to
+                * spill on the next loop execution. Given the validation we do
+                * checks for the data entry read to be poisoned, it's ok if
+                * we do not check "late arriving" memory poisoning.
+                */
+       :: 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
+#ifdef READER_PROGRESS
+               /*
+                * Make sure we don't block the reader's progress.
+                */
+               smp_mb_send(i, j, 5);
+#endif
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(rcu_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       ptr_read_first[i] = 1;
+                       ptr_read_second[i] = 1;
+                       data_read_first[i] = WINE;
+                       data_read_second[i] = WINE;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               INIT_CACHED_VAR(rcu_data[0], WINE, j);
+               i = 1;
+               do
+               :: i < SLAB_SIZE ->
+                       INIT_CACHED_VAR(rcu_data[i], POISON, j);
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_rmb.spin.input.trail b/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_rmb.spin.input.trail
new file mode 100644 (file)
index 0000000..e179cd5
--- /dev/null
@@ -0,0 +1,1717 @@
+-2:3:-2
+-4:-4:-4
+1:0:4629
+2:3:4549
+3:3:4552
+4:3:4552
+5:3:4555
+6:3:4563
+7:3:4563
+8:3:4566
+9:3:4572
+10:3:4576
+11:3:4576
+12:3:4579
+13:3:4589
+14:3:4597
+15:3:4597
+16:3:4600
+17:3:4606
+18:3:4610
+19:3:4610
+20:3:4613
+21:3:4619
+22:3:4623
+23:3:4624
+24:0:4629
+25:3:4626
+26:0:4629
+27:2:3285
+28:0:4629
+29:2:3291
+30:0:4629
+31:2:3292
+32:0:4629
+33:2:3294
+34:0:4629
+35:2:3295
+36:0:4629
+37:2:3296
+38:2:3297
+39:2:3301
+40:2:3302
+41:2:3310
+42:2:3311
+43:2:3315
+44:2:3316
+45:2:3324
+46:2:3329
+47:2:3333
+48:2:3334
+49:2:3342
+50:2:3343
+51:2:3347
+52:2:3348
+53:2:3342
+54:2:3343
+55:2:3347
+56:2:3348
+57:2:3356
+58:2:3361
+59:2:3362
+60:2:3373
+61:2:3374
+62:2:3375
+63:2:3386
+64:2:3391
+65:2:3392
+66:2:3403
+67:2:3404
+68:2:3405
+69:2:3403
+70:2:3404
+71:2:3405
+72:2:3416
+73:2:3424
+74:0:4629
+75:2:3295
+76:0:4629
+77:2:3428
+78:2:3432
+79:2:3433
+80:2:3437
+81:2:3441
+82:2:3442
+83:2:3446
+84:2:3454
+85:2:3455
+86:2:3459
+87:2:3463
+88:2:3464
+89:2:3459
+90:2:3460
+91:2:3468
+92:0:4629
+93:2:3295
+94:0:4629
+95:2:3476
+96:2:3477
+97:2:3478
+98:0:4629
+99:2:3295
+100:0:4629
+101:2:3483
+102:0:4629
+103:2:4186
+104:2:4187
+105:2:4191
+106:2:4195
+107:2:4196
+108:2:4200
+109:2:4205
+110:2:4213
+111:2:4217
+112:2:4218
+113:2:4213
+114:2:4217
+115:2:4218
+116:2:4222
+117:2:4229
+118:2:4236
+119:2:4237
+120:2:4244
+121:2:4249
+122:2:4256
+123:2:4257
+124:2:4256
+125:2:4257
+126:2:4264
+127:2:4268
+128:0:4629
+129:2:3485
+130:2:4167
+131:0:4629
+132:2:3295
+133:0:4629
+134:2:3486
+135:0:4629
+136:2:3295
+137:0:4629
+138:2:3489
+139:2:3490
+140:2:3494
+141:2:3495
+142:2:3503
+143:2:3504
+144:2:3508
+145:2:3509
+146:2:3517
+147:2:3522
+148:2:3526
+149:2:3527
+150:2:3535
+151:2:3536
+152:2:3540
+153:2:3541
+154:2:3535
+155:2:3536
+156:2:3540
+157:2:3541
+158:2:3549
+159:2:3554
+160:2:3555
+161:2:3566
+162:2:3567
+163:2:3568
+164:2:3579
+165:2:3584
+166:2:3585
+167:2:3596
+168:2:3597
+169:2:3598
+170:2:3596
+171:2:3597
+172:2:3598
+173:2:3609
+174:2:3616
+175:0:4629
+176:2:3295
+177:0:4629
+178:2:3620
+179:2:3621
+180:2:3622
+181:2:3634
+182:2:3635
+183:2:3639
+184:2:3640
+185:2:3648
+186:2:3653
+187:2:3657
+188:2:3658
+189:2:3666
+190:2:3667
+191:2:3671
+192:2:3672
+193:2:3666
+194:2:3667
+195:2:3671
+196:2:3672
+197:2:3680
+198:2:3685
+199:2:3686
+200:2:3697
+201:2:3698
+202:2:3699
+203:2:3710
+204:2:3715
+205:2:3716
+206:2:3727
+207:2:3728
+208:2:3729
+209:2:3727
+210:2:3728
+211:2:3729
+212:2:3740
+213:2:3751
+214:2:3752
+215:0:4629
+216:2:3295
+217:0:4629
+218:2:3758
+219:2:3759
+220:2:3763
+221:2:3764
+222:2:3772
+223:2:3773
+224:2:3777
+225:2:3778
+226:2:3786
+227:2:3791
+228:2:3795
+229:2:3796
+230:2:3804
+231:2:3805
+232:2:3809
+233:2:3810
+234:2:3804
+235:2:3805
+236:2:3809
+237:2:3810
+238:2:3818
+239:2:3823
+240:2:3824
+241:2:3835
+242:2:3836
+243:2:3837
+244:2:3848
+245:2:3853
+246:2:3854
+247:2:3865
+248:2:3866
+249:2:3867
+250:2:3865
+251:2:3866
+252:2:3867
+253:2:3878
+254:0:4629
+255:2:3295
+256:0:4629
+257:2:3887
+258:2:3888
+259:2:3892
+260:2:3893
+261:2:3901
+262:2:3902
+263:2:3906
+264:2:3907
+265:2:3915
+266:2:3920
+267:2:3924
+268:2:3925
+269:2:3933
+270:2:3934
+271:2:3938
+272:2:3939
+273:2:3933
+274:2:3934
+275:2:3938
+276:2:3939
+277:2:3947
+278:2:3952
+279:2:3953
+280:2:3964
+281:2:3965
+282:2:3966
+283:2:3977
+284:2:3982
+285:2:3983
+286:2:3994
+287:2:3995
+288:2:3996
+289:2:3994
+290:2:3995
+291:2:3996
+292:2:4007
+293:2:4014
+294:0:4629
+295:2:3295
+296:0:4629
+297:2:4018
+298:2:4019
+299:2:4020
+300:2:4032
+301:2:4033
+302:2:4037
+303:2:4038
+304:2:4046
+305:2:4051
+306:2:4055
+307:2:4056
+308:2:4064
+309:2:4065
+310:2:4069
+311:2:4070
+312:2:4064
+313:2:4065
+314:2:4069
+315:2:4070
+316:2:4078
+317:2:4083
+318:2:4084
+319:2:4095
+320:2:4096
+321:2:4097
+322:2:4108
+323:2:4113
+324:2:4114
+325:2:4125
+326:2:4126
+327:2:4127
+328:2:4125
+329:2:4126
+330:2:4127
+331:2:4138
+332:2:4148
+333:2:4149
+334:0:4629
+335:2:3295
+336:0:4629
+337:2:4155
+338:0:4629
+339:2:4459
+340:2:4460
+341:2:4464
+342:2:4468
+343:2:4469
+344:2:4473
+345:2:4481
+346:2:4482
+347:2:4486
+348:2:4490
+349:2:4491
+350:2:4486
+351:2:4490
+352:2:4491
+353:2:4495
+354:2:4502
+355:2:4509
+356:2:4510
+357:2:4517
+358:2:4522
+359:2:4529
+360:2:4530
+361:2:4529
+362:2:4530
+363:2:4537
+364:2:4541
+365:0:4629
+366:2:4157
+367:2:4167
+368:0:4629
+369:2:3295
+370:0:4629
+371:2:4158
+372:2:4159
+373:0:4629
+374:2:3295
+375:0:4629
+376:2:4163
+377:0:4629
+378:2:4171
+379:0:4629
+380:2:3292
+381:0:4629
+382:2:3294
+383:0:4629
+384:2:3295
+385:0:4629
+386:2:3296
+387:2:3297
+388:2:3301
+389:2:3302
+390:2:3310
+391:2:3311
+392:2:3315
+393:2:3316
+394:2:3324
+395:2:3329
+396:2:3333
+397:2:3334
+398:2:3342
+399:2:3343
+400:2:3344
+401:2:3342
+402:2:3343
+403:2:3347
+404:2:3348
+405:2:3356
+406:2:3361
+407:2:3362
+408:2:3373
+409:2:3374
+410:2:3375
+411:2:3386
+412:2:3391
+413:2:3392
+414:2:3403
+415:2:3404
+416:2:3405
+417:2:3403
+418:2:3404
+419:2:3405
+420:2:3416
+421:2:3424
+422:0:4629
+423:2:3295
+424:0:4629
+425:2:3428
+426:2:3432
+427:2:3433
+428:2:3437
+429:2:3441
+430:2:3442
+431:2:3446
+432:2:3454
+433:2:3455
+434:2:3459
+435:2:3460
+436:2:3459
+437:2:3463
+438:2:3464
+439:2:3468
+440:0:4629
+441:2:3295
+442:0:4629
+443:2:3476
+444:2:3477
+445:2:3478
+446:0:4629
+447:2:3295
+448:0:4629
+449:2:3483
+450:0:4629
+451:2:4186
+452:2:4187
+453:2:4191
+454:2:4195
+455:2:4196
+456:2:4200
+457:2:4205
+458:2:4213
+459:2:4217
+460:2:4218
+461:2:4213
+462:2:4217
+463:2:4218
+464:2:4222
+465:2:4229
+466:2:4236
+467:2:4237
+468:2:4244
+469:2:4249
+470:2:4256
+471:2:4257
+472:2:4256
+473:2:4257
+474:2:4264
+475:2:4268
+476:0:4629
+477:2:3485
+478:2:4167
+479:0:4629
+480:2:3295
+481:0:4629
+482:2:3486
+483:0:4629
+484:2:3295
+485:0:4629
+486:2:3489
+487:2:3490
+488:2:3494
+489:2:3495
+490:2:3503
+491:2:3504
+492:2:3508
+493:2:3509
+494:2:3517
+495:2:3522
+496:2:3526
+497:2:3527
+498:2:3535
+499:2:3536
+500:2:3540
+501:2:3541
+502:2:3535
+503:2:3536
+504:2:3540
+505:2:3541
+506:2:3549
+507:2:3554
+508:2:3555
+509:2:3566
+510:2:3567
+511:2:3568
+512:2:3579
+513:2:3584
+514:2:3585
+515:2:3596
+516:2:3597
+517:2:3598
+518:2:3596
+519:2:3597
+520:2:3598
+521:2:3609
+522:2:3616
+523:0:4629
+524:2:3295
+525:0:4629
+526:2:3620
+527:2:3621
+528:2:3622
+529:2:3634
+530:2:3635
+531:2:3639
+532:2:3640
+533:2:3648
+534:2:3653
+535:2:3657
+536:2:3658
+537:2:3666
+538:2:3667
+539:2:3671
+540:2:3672
+541:2:3666
+542:2:3667
+543:2:3671
+544:2:3672
+545:2:3680
+546:2:3685
+547:2:3686
+548:2:3697
+549:2:3698
+550:2:3699
+551:2:3710
+552:2:3715
+553:2:3716
+554:2:3727
+555:2:3728
+556:2:3729
+557:2:3727
+558:2:3728
+559:2:3729
+560:2:3740
+561:2:3751
+562:2:3752
+563:0:4629
+564:2:3295
+565:0:4629
+566:2:3758
+567:2:3759
+568:2:3763
+569:2:3764
+570:2:3772
+571:2:3773
+572:2:3777
+573:2:3778
+574:2:3786
+575:2:3791
+576:2:3795
+577:2:3796
+578:2:3804
+579:2:3805
+580:2:3809
+581:2:3810
+582:2:3804
+583:2:3805
+584:2:3809
+585:2:3810
+586:2:3818
+587:2:3823
+588:2:3824
+589:2:3835
+590:2:3836
+591:2:3837
+592:2:3848
+593:2:3853
+594:2:3854
+595:2:3865
+596:2:3866
+597:2:3867
+598:2:3865
+599:2:3866
+600:2:3867
+601:2:3878
+602:0:4629
+603:2:3295
+604:0:4629
+605:2:3887
+606:2:3888
+607:2:3892
+608:2:3893
+609:2:3901
+610:2:3902
+611:2:3906
+612:2:3907
+613:2:3915
+614:2:3920
+615:2:3924
+616:2:3925
+617:2:3933
+618:2:3934
+619:2:3938
+620:2:3939
+621:2:3933
+622:2:3934
+623:2:3938
+624:2:3939
+625:2:3947
+626:2:3952
+627:2:3953
+628:2:3964
+629:2:3965
+630:2:3966
+631:2:3977
+632:2:3982
+633:2:3983
+634:2:3994
+635:2:3995
+636:2:3996
+637:2:3994
+638:2:3995
+639:2:3996
+640:2:4007
+641:2:4014
+642:0:4629
+643:2:3295
+644:0:4629
+645:2:4018
+646:2:4019
+647:2:4020
+648:2:4032
+649:2:4033
+650:2:4037
+651:2:4038
+652:2:4046
+653:2:4051
+654:2:4055
+655:2:4056
+656:2:4064
+657:2:4065
+658:2:4069
+659:2:4070
+660:2:4064
+661:2:4065
+662:2:4069
+663:2:4070
+664:2:4078
+665:2:4083
+666:2:4084
+667:2:4095
+668:2:4096
+669:2:4097
+670:2:4108
+671:2:4113
+672:2:4114
+673:2:4125
+674:2:4126
+675:2:4127
+676:2:4125
+677:2:4126
+678:2:4127
+679:2:4138
+680:2:4148
+681:2:4149
+682:0:4629
+683:2:3295
+684:0:4629
+685:2:4155
+686:0:4629
+687:2:4459
+688:2:4460
+689:2:4464
+690:2:4468
+691:2:4469
+692:2:4473
+693:2:4481
+694:2:4482
+695:2:4486
+696:2:4490
+697:2:4491
+698:2:4486
+699:2:4490
+700:2:4491
+701:2:4495
+702:2:4502
+703:2:4509
+704:2:4510
+705:2:4517
+706:2:4522
+707:2:4529
+708:2:4530
+709:2:4529
+710:2:4530
+711:2:4537
+712:2:4541
+713:0:4629
+714:2:4157
+715:2:4167
+716:0:4629
+717:2:3295
+718:0:4629
+719:2:4158
+720:2:4159
+721:0:4629
+722:2:3295
+723:0:4629
+724:2:4163
+725:0:4629
+726:2:4171
+727:0:4629
+728:2:3292
+729:0:4629
+730:2:3294
+731:0:4629
+732:2:3295
+733:0:4629
+734:2:3296
+735:2:3297
+736:2:3301
+737:2:3302
+738:2:3310
+739:2:3311
+740:2:3315
+741:2:3316
+742:2:3324
+743:2:3329
+744:2:3333
+745:2:3334
+746:2:3342
+747:2:3343
+748:2:3347
+749:2:3348
+750:2:3342
+751:2:3343
+752:2:3344
+753:2:3356
+754:2:3361
+755:2:3362
+756:2:3373
+757:2:3374
+758:2:3375
+759:2:3386
+760:2:3391
+761:2:3392
+762:2:3403
+763:2:3404
+764:2:3405
+765:2:3403
+766:2:3404
+767:2:3405
+768:2:3416
+769:2:3424
+770:0:4629
+771:2:3295
+772:0:4629
+773:1:2
+774:0:4629
+775:1:8
+776:0:4629
+777:1:9
+778:0:4629
+779:1:10
+780:0:4629
+781:1:11
+782:0:4629
+783:1:12
+784:1:13
+785:1:17
+786:1:18
+787:1:26
+788:1:27
+789:1:31
+790:1:32
+791:1:40
+792:1:45
+793:1:49
+794:1:50
+795:1:58
+796:1:59
+797:1:63
+798:1:64
+799:1:58
+800:1:59
+801:1:63
+802:1:64
+803:1:72
+804:1:77
+805:1:78
+806:1:89
+807:1:90
+808:1:91
+809:1:102
+810:1:107
+811:1:108
+812:1:119
+813:1:120
+814:1:121
+815:1:119
+816:1:120
+817:1:121
+818:1:132
+819:0:4629
+820:1:11
+821:0:4629
+822:1:141
+823:1:142
+824:0:4629
+825:1:11
+826:0:4629
+827:1:148
+828:1:149
+829:1:153
+830:1:154
+831:1:162
+832:1:163
+833:1:167
+834:1:168
+835:1:176
+836:1:181
+837:1:185
+838:1:186
+839:1:194
+840:1:195
+841:1:199
+842:1:200
+843:1:194
+844:1:195
+845:1:199
+846:1:200
+847:1:208
+848:1:213
+849:1:214
+850:1:225
+851:1:226
+852:1:227
+853:1:238
+854:1:243
+855:1:244
+856:1:255
+857:1:256
+858:1:257
+859:1:255
+860:1:256
+861:1:257
+862:1:268
+863:0:4629
+864:1:11
+865:0:4629
+866:1:277
+867:1:278
+868:1:282
+869:1:283
+870:1:291
+871:1:292
+872:1:296
+873:1:297
+874:1:305
+875:1:310
+876:1:314
+877:1:315
+878:1:323
+879:1:324
+880:1:328
+881:1:329
+882:1:323
+883:1:324
+884:1:328
+885:1:329
+886:1:337
+887:1:342
+888:1:343
+889:1:354
+890:1:355
+891:1:356
+892:1:367
+893:1:372
+894:1:373
+895:1:384
+896:1:385
+897:1:386
+898:1:384
+899:1:385
+900:1:386
+901:1:397
+902:1:404
+903:0:4629
+904:1:11
+905:0:4629
+906:1:540
+907:1:544
+908:1:545
+909:1:549
+910:1:550
+911:1:558
+912:1:566
+913:1:567
+914:1:571
+915:1:575
+916:1:576
+917:1:571
+918:1:575
+919:1:576
+920:1:580
+921:1:587
+922:1:594
+923:1:595
+924:1:602
+925:1:607
+926:1:614
+927:1:615
+928:1:614
+929:1:615
+930:1:622
+931:0:4629
+932:1:11
+933:0:4629
+934:2:3428
+935:2:3432
+936:2:3433
+937:2:3437
+938:2:3441
+939:2:3442
+940:2:3446
+941:2:3454
+942:2:3455
+943:2:3459
+944:2:3463
+945:2:3464
+946:2:3459
+947:2:3460
+948:2:3468
+949:0:4629
+950:2:3295
+951:0:4629
+952:2:3476
+953:2:3477
+954:2:3478
+955:0:4629
+956:2:3295
+957:0:4629
+958:2:3483
+959:0:4629
+960:2:4186
+961:2:4187
+962:2:4191
+963:2:4195
+964:2:4196
+965:2:4200
+966:2:4205
+967:2:4213
+968:2:4217
+969:2:4218
+970:2:4213
+971:2:4217
+972:2:4218
+973:2:4222
+974:2:4229
+975:2:4236
+976:2:4237
+977:2:4244
+978:2:4249
+979:2:4256
+980:2:4257
+981:2:4256
+982:2:4257
+983:2:4264
+984:2:4268
+985:0:4629
+986:2:3485
+987:2:4167
+988:0:4629
+989:2:3295
+990:0:4629
+991:2:3486
+992:0:4629
+993:2:3295
+994:0:4629
+995:2:3489
+996:2:3490
+997:2:3494
+998:2:3495
+999:2:3503
+1000:2:3504
+1001:2:3508
+1002:2:3509
+1003:2:3517
+1004:2:3522
+1005:2:3526
+1006:2:3527
+1007:2:3535
+1008:2:3536
+1009:2:3540
+1010:2:3541
+1011:2:3535
+1012:2:3536
+1013:2:3540
+1014:2:3541
+1015:2:3549
+1016:2:3554
+1017:2:3555
+1018:2:3566
+1019:2:3567
+1020:2:3568
+1021:2:3579
+1022:2:3584
+1023:2:3585
+1024:2:3596
+1025:2:3597
+1026:2:3598
+1027:2:3596
+1028:2:3597
+1029:2:3598
+1030:2:3609
+1031:2:3616
+1032:0:4629
+1033:2:3295
+1034:0:4629
+1035:2:3620
+1036:2:3621
+1037:2:3622
+1038:2:3634
+1039:2:3635
+1040:2:3639
+1041:2:3640
+1042:2:3648
+1043:2:3653
+1044:2:3657
+1045:2:3658
+1046:2:3666
+1047:2:3667
+1048:2:3671
+1049:2:3672
+1050:2:3666
+1051:2:3667
+1052:2:3671
+1053:2:3672
+1054:2:3680
+1055:2:3685
+1056:2:3686
+1057:2:3697
+1058:2:3698
+1059:2:3699
+1060:2:3710
+1061:2:3715
+1062:2:3716
+1063:2:3727
+1064:2:3728
+1065:2:3729
+1066:2:3727
+1067:2:3728
+1068:2:3729
+1069:2:3740
+1070:2:3749
+1071:0:4629
+1072:2:3295
+1073:0:4629
+1074:2:3755
+1075:0:4629
+1076:2:4277
+1077:2:4278
+1078:2:4282
+1079:2:4286
+1080:2:4287
+1081:2:4291
+1082:2:4299
+1083:2:4300
+1084:2:4304
+1085:2:4308
+1086:2:4309
+1087:2:4304
+1088:2:4308
+1089:2:4309
+1090:2:4313
+1091:2:4320
+1092:2:4327
+1093:2:4328
+1094:2:4335
+1095:2:4340
+1096:2:4347
+1097:2:4348
+1098:2:4347
+1099:2:4348
+1100:2:4355
+1101:2:4359
+1102:0:4629
+1103:2:3757
+1104:2:4167
+1105:0:4629
+1106:2:3295
+1107:0:4629
+1108:1:632
+1109:1:633
+1110:1:637
+1111:1:638
+1112:1:646
+1113:1:647
+1114:1:651
+1115:1:652
+1116:1:660
+1117:1:665
+1118:1:669
+1119:1:670
+1120:1:678
+1121:1:679
+1122:1:683
+1123:1:684
+1124:1:678
+1125:1:679
+1126:1:683
+1127:1:684
+1128:1:692
+1129:1:697
+1130:1:698
+1131:1:709
+1132:1:710
+1133:1:711
+1134:1:722
+1135:1:727
+1136:1:728
+1137:1:739
+1138:1:740
+1139:1:741
+1140:1:739
+1141:1:747
+1142:1:748
+1143:1:752
+1144:0:4629
+1145:1:11
+1146:0:4629
+1147:2:3620
+1148:2:3621
+1149:2:3625
+1150:2:3626
+1151:2:3634
+1152:2:3635
+1153:2:3639
+1154:2:3640
+1155:2:3648
+1156:2:3653
+1157:2:3657
+1158:2:3658
+1159:2:3666
+1160:2:3667
+1161:2:3671
+1162:2:3672
+1163:2:3666
+1164:2:3667
+1165:2:3671
+1166:2:3672
+1167:2:3680
+1168:2:3685
+1169:2:3686
+1170:2:3697
+1171:2:3698
+1172:2:3699
+1173:2:3710
+1174:2:3715
+1175:2:3716
+1176:2:3727
+1177:2:3728
+1178:2:3729
+1179:2:3727
+1180:2:3728
+1181:2:3729
+1182:2:3740
+1183:2:3749
+1184:0:4629
+1185:2:3295
+1186:0:4629
+1187:2:3755
+1188:0:4629
+1189:2:4277
+1190:2:4278
+1191:2:4282
+1192:2:4286
+1193:2:4287
+1194:2:4291
+1195:2:4299
+1196:2:4300
+1197:2:4304
+1198:2:4308
+1199:2:4309
+1200:2:4304
+1201:2:4308
+1202:2:4309
+1203:2:4313
+1204:2:4320
+1205:2:4327
+1206:2:4328
+1207:2:4335
+1208:2:4340
+1209:2:4347
+1210:2:4348
+1211:2:4347
+1212:2:4348
+1213:2:4355
+1214:2:4359
+1215:0:4629
+1216:2:3757
+1217:2:4167
+1218:0:4629
+1219:1:761
+1220:1:764
+1221:1:765
+1222:0:4629
+1223:2:3295
+1224:0:4629
+1225:1:11
+1226:0:4629
+1227:2:3620
+1228:2:3621
+1229:2:3625
+1230:2:3626
+1231:2:3634
+1232:2:3635
+1233:2:3639
+1234:2:3640
+1235:2:3648
+1236:2:3653
+1237:2:3657
+1238:2:3658
+1239:2:3666
+1240:2:3667
+1241:2:3671
+1242:2:3672
+1243:2:3666
+1244:2:3667
+1245:2:3671
+1246:2:3672
+1247:2:3680
+1248:2:3685
+1249:2:3686
+1250:2:3697
+1251:2:3698
+1252:2:3699
+1253:2:3710
+1254:2:3715
+1255:2:3716
+1256:2:3727
+1257:2:3728
+1258:2:3729
+1259:2:3727
+1260:2:3728
+1261:2:3729
+1262:2:3740
+1263:2:3749
+1264:0:4629
+1265:2:3295
+1266:0:4629
+1267:2:3755
+1268:0:4629
+1269:2:4277
+1270:2:4278
+1271:2:4282
+1272:2:4286
+1273:2:4287
+1274:2:4291
+1275:2:4299
+1276:2:4300
+1277:2:4304
+1278:2:4308
+1279:2:4309
+1280:2:4304
+1281:2:4308
+1282:2:4309
+1283:2:4313
+1284:2:4320
+1285:2:4327
+1286:2:4328
+1287:2:4335
+1288:2:4340
+1289:2:4347
+1290:2:4348
+1291:2:4347
+1292:2:4348
+1293:2:4355
+1294:2:4359
+1295:0:4629
+1296:2:3757
+1297:2:4167
+1298:0:4629
+1299:1:1028
+1300:1:1029
+1301:1:1033
+1302:1:1034
+1303:1:1042
+1304:1:1043
+1305:1:1047
+1306:1:1048
+1307:1:1056
+1308:1:1061
+1309:1:1065
+1310:1:1066
+1311:1:1074
+1312:1:1075
+1313:1:1079
+1314:1:1080
+1315:1:1074
+1316:1:1075
+1317:1:1079
+1318:1:1080
+1319:1:1088
+1320:1:1093
+1321:1:1094
+1322:1:1105
+1323:1:1106
+1324:1:1107
+1325:1:1118
+1326:1:1123
+1327:1:1124
+1328:1:1135
+1329:1:1136
+1330:1:1137
+1331:1:1135
+1332:1:1143
+1333:1:1144
+1334:1:1148
+1335:1:1155
+1336:1:1159
+1337:0:4629
+1338:2:3295
+1339:0:4629
+1340:1:11
+1341:0:4629
+1342:2:3620
+1343:2:3621
+1344:2:3625
+1345:2:3626
+1346:2:3634
+1347:2:3635
+1348:2:3639
+1349:2:3640
+1350:2:3648
+1351:2:3653
+1352:2:3657
+1353:2:3658
+1354:2:3666
+1355:2:3667
+1356:2:3671
+1357:2:3672
+1358:2:3666
+1359:2:3667
+1360:2:3671
+1361:2:3672
+1362:2:3680
+1363:2:3685
+1364:2:3686
+1365:2:3697
+1366:2:3698
+1367:2:3699
+1368:2:3710
+1369:2:3715
+1370:2:3716
+1371:2:3727
+1372:2:3728
+1373:2:3729
+1374:2:3727
+1375:2:3728
+1376:2:3729
+1377:2:3740
+1378:2:3749
+1379:0:4629
+1380:2:3295
+1381:0:4629
+1382:2:3755
+1383:0:4629
+1384:2:4277
+1385:2:4278
+1386:2:4282
+1387:2:4286
+1388:2:4287
+1389:2:4291
+1390:2:4299
+1391:2:4300
+1392:2:4304
+1393:2:4308
+1394:2:4309
+1395:2:4304
+1396:2:4308
+1397:2:4309
+1398:2:4313
+1399:2:4320
+1400:2:4327
+1401:2:4328
+1402:2:4335
+1403:2:4340
+1404:2:4347
+1405:2:4348
+1406:2:4347
+1407:2:4348
+1408:2:4355
+1409:2:4359
+1410:0:4629
+1411:2:3757
+1412:2:4167
+1413:0:4629
+1414:1:1160
+1415:1:1161
+1416:1:1165
+1417:1:1166
+1418:1:1174
+1419:1:1175
+1420:1:1176
+1421:1:1188
+1422:1:1193
+1423:1:1197
+1424:1:1198
+1425:1:1206
+1426:1:1207
+1427:1:1211
+1428:1:1212
+1429:1:1206
+1430:1:1207
+1431:1:1211
+1432:1:1212
+1433:1:1220
+1434:1:1225
+1435:1:1226
+1436:1:1237
+1437:1:1238
+1438:1:1239
+1439:1:1250
+1440:1:1255
+1441:1:1256
+1442:1:1267
+1443:1:1268
+1444:1:1269
+1445:1:1267
+1446:1:1275
+1447:1:1276
+1448:1:1280
+1449:0:4629
+1450:2:3295
+1451:0:4629
+1452:1:11
+1453:0:4629
+1454:2:3620
+1455:2:3621
+1456:2:3625
+1457:2:3626
+1458:2:3634
+1459:2:3635
+1460:2:3639
+1461:2:3640
+1462:2:3648
+1463:2:3653
+1464:2:3657
+1465:2:3658
+1466:2:3666
+1467:2:3667
+1468:2:3671
+1469:2:3672
+1470:2:3666
+1471:2:3667
+1472:2:3671
+1473:2:3672
+1474:2:3680
+1475:2:3685
+1476:2:3686
+1477:2:3697
+1478:2:3698
+1479:2:3699
+1480:2:3710
+1481:2:3715
+1482:2:3716
+1483:2:3727
+1484:2:3728
+1485:2:3729
+1486:2:3727
+1487:2:3728
+1488:2:3729
+1489:2:3740
+1490:2:3749
+1491:0:4629
+1492:2:3295
+1493:0:4629
+1494:2:3755
+1495:0:4629
+1496:2:4277
+1497:2:4278
+1498:2:4282
+1499:2:4286
+1500:2:4287
+1501:2:4291
+1502:2:4299
+1503:2:4300
+1504:2:4304
+1505:2:4308
+1506:2:4309
+1507:2:4304
+1508:2:4308
+1509:2:4309
+1510:2:4313
+1511:2:4320
+1512:2:4327
+1513:2:4328
+1514:2:4335
+1515:2:4340
+1516:2:4347
+1517:2:4348
+1518:2:4347
+1519:2:4348
+1520:2:4355
+1521:2:4359
+1522:0:4629
+1523:2:3757
+1524:2:4167
+1525:0:4629
+1526:2:3295
+1527:0:4629
+1528:1:1289
+1529:0:4629
+1530:2:3620
+1531:2:3621
+1532:2:3625
+1533:2:3626
+1534:2:3634
+1535:2:3635
+1536:2:3639
+1537:2:3640
+1538:2:3648
+1539:2:3653
+1540:2:3657
+1541:2:3658
+1542:2:3666
+1543:2:3667
+1544:2:3671
+1545:2:3672
+1546:2:3666
+1547:2:3667
+1548:2:3671
+1549:2:3672
+1550:2:3680
+1551:2:3685
+1552:2:3686
+1553:2:3697
+1554:2:3698
+1555:2:3699
+1556:2:3710
+1557:2:3715
+1558:2:3716
+1559:2:3727
+1560:2:3728
+1561:2:3729
+1562:2:3727
+1563:2:3728
+1564:2:3729
+1565:2:3740
+1566:2:3749
+1567:0:4629
+1568:2:3295
+1569:0:4629
+1570:2:3755
+1571:0:4629
+1572:2:4277
+1573:2:4278
+1574:2:4282
+1575:2:4286
+1576:2:4287
+1577:2:4291
+1578:2:4299
+1579:2:4300
+1580:2:4304
+1581:2:4308
+1582:2:4309
+1583:2:4304
+1584:2:4308
+1585:2:4309
+1586:2:4313
+1587:2:4320
+1588:2:4327
+1589:2:4328
+1590:2:4335
+1591:2:4340
+1592:2:4347
+1593:2:4348
+1594:2:4347
+1595:2:4348
+1596:2:4355
+1597:2:4359
+1598:0:4629
+1599:2:3757
+1600:2:4167
+1601:0:4629
+1602:1:3023
+1603:1:3027
+1604:1:3028
+1605:1:3036
+1606:1:3037
+1607:1:3041
+1608:1:3042
+1609:1:3050
+1610:1:3055
+1611:1:3059
+1612:1:3060
+1613:1:3068
+1614:1:3069
+1615:1:3073
+1616:1:3074
+1617:1:3068
+1618:1:3069
+1619:1:3073
+1620:1:3074
+1621:1:3082
+1622:1:3087
+1623:1:3088
+1624:1:3099
+1625:1:3100
+1626:1:3101
+1627:1:3112
+1628:1:3117
+1629:1:3118
+1630:1:3129
+1631:1:3130
+1632:1:3131
+1633:1:3129
+1634:1:3137
+1635:1:3138
+1636:1:3142
+1637:1:3146
+1638:0:4629
+1639:2:3295
+1640:0:4629
+1641:2:3620
+1642:2:3621
+1643:2:3625
+1644:2:3626
+1645:2:3634
+1646:2:3635
+1647:2:3639
+1648:2:3640
+1649:2:3648
+1650:2:3653
+1651:2:3657
+1652:2:3658
+1653:2:3666
+1654:2:3667
+1655:2:3671
+1656:2:3672
+1657:2:3666
+1658:2:3667
+1659:2:3671
+1660:2:3672
+1661:2:3680
+1662:2:3685
+1663:2:3686
+1664:2:3697
+1665:2:3698
+1666:2:3699
+1667:2:3710
+1668:2:3715
+1669:2:3716
+1670:2:3727
+1671:2:3728
+1672:2:3729
+1673:2:3727
+1674:2:3728
+1675:2:3729
+1676:2:3740
+1677:2:3749
+1678:0:4629
+1679:2:3295
+1680:0:4629
+1681:2:3755
+1682:0:4629
+1683:2:4277
+1684:2:4278
+1685:2:4282
+1686:2:4286
+1687:2:4287
+1688:2:4291
+1689:2:4299
+1690:2:4300
+1691:2:4304
+1692:2:4308
+1693:2:4309
+1694:2:4304
+1695:2:4308
+1696:2:4309
+1697:2:4313
+1698:2:4320
+1699:2:4327
+1700:2:4328
+1701:2:4335
+1702:2:4340
+1703:2:4347
+1704:2:4348
+1705:2:4347
+1706:2:4348
+1707:2:4355
+1708:2:4359
+1709:0:4629
+1710:1:1291
+1711:1:1292
+1712:0:4627
+1713:1:11
+1714:0:4633
+1715:1:208
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_wmb.define b/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_wmb.define
new file mode 100644 (file)
index 0000000..710f29d
--- /dev/null
@@ -0,0 +1 @@
+#define NO_WMB
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_wmb.log b/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_wmb.log
new file mode 100644 (file)
index 0000000..4f2bfe6
--- /dev/null
@@ -0,0 +1,552 @@
+rm -f pan* trail.out .input.spin* *.spin.trail .input.define
+touch .input.define
+cat .input.define >> pan.ltl
+cat DEFINES >> pan.ltl
+spin -f "!(`cat urcu_free.ltl | grep -v ^//`)" >> pan.ltl
+cp urcu_free_no_wmb.define .input.define
+cat .input.define > .input.spin
+cat DEFINES >> .input.spin
+cat urcu.spin >> .input.spin
+rm -f .input.spin.trail
+spin -a -X -N pan.ltl .input.spin
+Exit-Status 0
+gcc -O2 -w -DHASH64 -o pan pan.c
+./pan -a -v -c1 -X -m10000000 -w20
+warning: for p.o. reduction to be valid the never claim must be stutter-invariant
+(never claims generated from LTL formulae are stutter-invariant)
+depth 0: Claim reached state 5 (line 1258)
+Depth=    4637 States=    1e+06 Transitions= 4.63e+08 Memory=   550.432        t=    580 R=   2e+03
+pan: claim violated! (at depth 1199)
+pan: wrote .input.spin.trail
+
+(Spin Version 5.1.7 -- 23 December 2008)
+Warning: Search not completed
+       + Partial Order Reduction
+
+Full statespace search for:
+       never claim             +
+       assertion violations    + (if within scope of claim)
+       acceptance   cycles     + (fairness disabled)
+       invalid end states      - (disabled by never claim)
+
+State-vector 88 byte, depth reached 4637, errors: 1
+  1676215 states, stored
+7.6378297e+08 states, matched
+7.6545918e+08 transitions (= stored+matched)
+4.5297646e+09 atomic steps
+hash conflicts: 3.184152e+08 (resolved)
+
+Stats on memory usage (in Megabytes):
+  185.433      equivalent memory usage for states (stored*(State-vector + overhead))
+  141.544      actual memory usage for states (compression: 76.33%)
+               state-vector as stored = 61 byte + 28 byte overhead
+    8.000      memory used for hash table (-w20)
+  457.764      memory used for DFS stack (-m10000000)
+  607.170      total actual memory usage
+
+unreached in proctype urcu_reader
+       line 395, "pan.___", state 17, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 49, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 63, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 82, "(1)"
+       line 421, "pan.___", state 112, "(1)"
+       line 425, "pan.___", state 125, "(1)"
+       line 576, "pan.___", state 146, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<1))"
+       line 395, "pan.___", state 153, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 185, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 199, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 218, "(1)"
+       line 421, "pan.___", state 248, "(1)"
+       line 425, "pan.___", state 261, "(1)"
+       line 395, "pan.___", state 282, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 314, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 328, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 347, "(1)"
+       line 421, "pan.___", state 377, "(1)"
+       line 425, "pan.___", state 390, "(1)"
+       line 395, "pan.___", state 413, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 415, "(1)"
+       line 395, "pan.___", state 416, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 416, "else"
+       line 395, "pan.___", state 419, "(1)"
+       line 399, "pan.___", state 427, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 429, "(1)"
+       line 399, "pan.___", state 430, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 430, "else"
+       line 399, "pan.___", state 433, "(1)"
+       line 399, "pan.___", state 434, "(1)"
+       line 399, "pan.___", state 434, "(1)"
+       line 397, "pan.___", state 439, "((i<1))"
+       line 397, "pan.___", state 439, "((i>=1))"
+       line 404, "pan.___", state 445, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 447, "(1)"
+       line 404, "pan.___", state 448, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 448, "else"
+       line 404, "pan.___", state 451, "(1)"
+       line 404, "pan.___", state 452, "(1)"
+       line 404, "pan.___", state 452, "(1)"
+       line 408, "pan.___", state 459, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 461, "(1)"
+       line 408, "pan.___", state 462, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 462, "else"
+       line 408, "pan.___", state 465, "(1)"
+       line 408, "pan.___", state 466, "(1)"
+       line 408, "pan.___", state 466, "(1)"
+       line 406, "pan.___", state 471, "((i<2))"
+       line 406, "pan.___", state 471, "((i>=2))"
+       line 412, "pan.___", state 478, "(1)"
+       line 412, "pan.___", state 479, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 479, "else"
+       line 412, "pan.___", state 482, "(1)"
+       line 412, "pan.___", state 483, "(1)"
+       line 412, "pan.___", state 483, "(1)"
+       line 416, "pan.___", state 491, "(1)"
+       line 416, "pan.___", state 492, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 492, "else"
+       line 416, "pan.___", state 495, "(1)"
+       line 416, "pan.___", state 496, "(1)"
+       line 416, "pan.___", state 496, "(1)"
+       line 414, "pan.___", state 501, "((i<1))"
+       line 414, "pan.___", state 501, "((i>=1))"
+       line 421, "pan.___", state 508, "(1)"
+       line 421, "pan.___", state 509, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 509, "else"
+       line 421, "pan.___", state 512, "(1)"
+       line 421, "pan.___", state 513, "(1)"
+       line 421, "pan.___", state 513, "(1)"
+       line 425, "pan.___", state 521, "(1)"
+       line 425, "pan.___", state 522, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 522, "else"
+       line 425, "pan.___", state 525, "(1)"
+       line 425, "pan.___", state 526, "(1)"
+       line 425, "pan.___", state 526, "(1)"
+       line 423, "pan.___", state 531, "((i<2))"
+       line 423, "pan.___", state 531, "((i>=2))"
+       line 430, "pan.___", state 535, "(1)"
+       line 430, "pan.___", state 535, "(1)"
+       line 576, "pan.___", state 538, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 576, "pan.___", state 539, "_proc_urcu_reader = (_proc_urcu_reader|(1<<5))"
+       line 576, "pan.___", state 540, "(1)"
+       line 250, "pan.___", state 544, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 555, "(1)"
+       line 258, "pan.___", state 566, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 575, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 591, "(1)"
+       line 231, "pan.___", state 599, "(1)"
+       line 235, "pan.___", state 611, "(1)"
+       line 239, "pan.___", state 619, "(1)"
+       line 395, "pan.___", state 637, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 651, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 669, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 683, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 702, "(1)"
+       line 416, "pan.___", state 715, "(1)"
+       line 421, "pan.___", state 732, "(1)"
+       line 425, "pan.___", state 745, "(1)"
+       line 395, "pan.___", state 773, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 775, "(1)"
+       line 395, "pan.___", state 776, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 776, "else"
+       line 395, "pan.___", state 779, "(1)"
+       line 399, "pan.___", state 787, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 789, "(1)"
+       line 399, "pan.___", state 790, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 790, "else"
+       line 399, "pan.___", state 793, "(1)"
+       line 399, "pan.___", state 794, "(1)"
+       line 399, "pan.___", state 794, "(1)"
+       line 397, "pan.___", state 799, "((i<1))"
+       line 397, "pan.___", state 799, "((i>=1))"
+       line 404, "pan.___", state 805, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 807, "(1)"
+       line 404, "pan.___", state 808, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 808, "else"
+       line 404, "pan.___", state 811, "(1)"
+       line 404, "pan.___", state 812, "(1)"
+       line 404, "pan.___", state 812, "(1)"
+       line 408, "pan.___", state 819, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 821, "(1)"
+       line 408, "pan.___", state 822, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 822, "else"
+       line 408, "pan.___", state 825, "(1)"
+       line 408, "pan.___", state 826, "(1)"
+       line 408, "pan.___", state 826, "(1)"
+       line 406, "pan.___", state 831, "((i<2))"
+       line 406, "pan.___", state 831, "((i>=2))"
+       line 412, "pan.___", state 838, "(1)"
+       line 412, "pan.___", state 839, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 839, "else"
+       line 412, "pan.___", state 842, "(1)"
+       line 412, "pan.___", state 843, "(1)"
+       line 412, "pan.___", state 843, "(1)"
+       line 416, "pan.___", state 851, "(1)"
+       line 416, "pan.___", state 852, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 852, "else"
+       line 416, "pan.___", state 855, "(1)"
+       line 416, "pan.___", state 856, "(1)"
+       line 416, "pan.___", state 856, "(1)"
+       line 414, "pan.___", state 861, "((i<1))"
+       line 414, "pan.___", state 861, "((i>=1))"
+       line 421, "pan.___", state 868, "(1)"
+       line 421, "pan.___", state 869, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 869, "else"
+       line 421, "pan.___", state 872, "(1)"
+       line 421, "pan.___", state 873, "(1)"
+       line 421, "pan.___", state 873, "(1)"
+       line 425, "pan.___", state 881, "(1)"
+       line 425, "pan.___", state 882, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 882, "else"
+       line 425, "pan.___", state 885, "(1)"
+       line 425, "pan.___", state 886, "(1)"
+       line 425, "pan.___", state 886, "(1)"
+       line 430, "pan.___", state 895, "(1)"
+       line 430, "pan.___", state 895, "(1)"
+       line 395, "pan.___", state 902, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 904, "(1)"
+       line 395, "pan.___", state 905, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 905, "else"
+       line 395, "pan.___", state 908, "(1)"
+       line 399, "pan.___", state 916, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 918, "(1)"
+       line 399, "pan.___", state 919, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 919, "else"
+       line 399, "pan.___", state 922, "(1)"
+       line 399, "pan.___", state 923, "(1)"
+       line 399, "pan.___", state 923, "(1)"
+       line 397, "pan.___", state 928, "((i<1))"
+       line 397, "pan.___", state 928, "((i>=1))"
+       line 404, "pan.___", state 934, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 936, "(1)"
+       line 404, "pan.___", state 937, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 937, "else"
+       line 404, "pan.___", state 940, "(1)"
+       line 404, "pan.___", state 941, "(1)"
+       line 404, "pan.___", state 941, "(1)"
+       line 408, "pan.___", state 948, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 950, "(1)"
+       line 408, "pan.___", state 951, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 951, "else"
+       line 408, "pan.___", state 954, "(1)"
+       line 408, "pan.___", state 955, "(1)"
+       line 408, "pan.___", state 955, "(1)"
+       line 406, "pan.___", state 960, "((i<2))"
+       line 406, "pan.___", state 960, "((i>=2))"
+       line 412, "pan.___", state 967, "(1)"
+       line 412, "pan.___", state 968, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 968, "else"
+       line 412, "pan.___", state 971, "(1)"
+       line 412, "pan.___", state 972, "(1)"
+       line 412, "pan.___", state 972, "(1)"
+       line 416, "pan.___", state 980, "(1)"
+       line 416, "pan.___", state 981, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 981, "else"
+       line 416, "pan.___", state 984, "(1)"
+       line 416, "pan.___", state 985, "(1)"
+       line 416, "pan.___", state 985, "(1)"
+       line 414, "pan.___", state 990, "((i<1))"
+       line 414, "pan.___", state 990, "((i>=1))"
+       line 421, "pan.___", state 997, "(1)"
+       line 421, "pan.___", state 998, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 998, "else"
+       line 421, "pan.___", state 1001, "(1)"
+       line 421, "pan.___", state 1002, "(1)"
+       line 421, "pan.___", state 1002, "(1)"
+       line 425, "pan.___", state 1010, "(1)"
+       line 425, "pan.___", state 1011, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 1011, "else"
+       line 425, "pan.___", state 1014, "(1)"
+       line 425, "pan.___", state 1015, "(1)"
+       line 425, "pan.___", state 1015, "(1)"
+       line 423, "pan.___", state 1020, "((i<2))"
+       line 423, "pan.___", state 1020, "((i>=2))"
+       line 430, "pan.___", state 1024, "(1)"
+       line 430, "pan.___", state 1024, "(1)"
+       line 584, "pan.___", state 1028, "_proc_urcu_reader = (_proc_urcu_reader|(1<<11))"
+       line 395, "pan.___", state 1033, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 1047, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1065, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1079, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1098, "(1)"
+       line 416, "pan.___", state 1111, "(1)"
+       line 421, "pan.___", state 1128, "(1)"
+       line 425, "pan.___", state 1141, "(1)"
+       line 395, "pan.___", state 1165, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1197, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1211, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1230, "(1)"
+       line 421, "pan.___", state 1260, "(1)"
+       line 425, "pan.___", state 1273, "(1)"
+       line 395, "pan.___", state 1298, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1330, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1344, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1363, "(1)"
+       line 421, "pan.___", state 1393, "(1)"
+       line 425, "pan.___", state 1406, "(1)"
+       line 395, "pan.___", state 1427, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1459, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1473, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1492, "(1)"
+       line 421, "pan.___", state 1522, "(1)"
+       line 425, "pan.___", state 1535, "(1)"
+       line 250, "pan.___", state 1558, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1580, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1589, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1605, "(1)"
+       line 231, "pan.___", state 1613, "(1)"
+       line 235, "pan.___", state 1625, "(1)"
+       line 239, "pan.___", state 1633, "(1)"
+       line 395, "pan.___", state 1651, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 1665, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1683, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1697, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1716, "(1)"
+       line 416, "pan.___", state 1729, "(1)"
+       line 421, "pan.___", state 1746, "(1)"
+       line 425, "pan.___", state 1759, "(1)"
+       line 395, "pan.___", state 1780, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 1794, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1812, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1826, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1845, "(1)"
+       line 416, "pan.___", state 1858, "(1)"
+       line 421, "pan.___", state 1875, "(1)"
+       line 425, "pan.___", state 1888, "(1)"
+       line 395, "pan.___", state 1912, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 1928, "(1)"
+       line 404, "pan.___", state 1944, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1958, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1977, "(1)"
+       line 421, "pan.___", state 2007, "(1)"
+       line 425, "pan.___", state 2020, "(1)"
+       line 623, "pan.___", state 2041, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<19))"
+       line 395, "pan.___", state 2048, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2080, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2094, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2113, "(1)"
+       line 421, "pan.___", state 2143, "(1)"
+       line 425, "pan.___", state 2156, "(1)"
+       line 395, "pan.___", state 2177, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2209, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2223, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2242, "(1)"
+       line 421, "pan.___", state 2272, "(1)"
+       line 425, "pan.___", state 2285, "(1)"
+       line 395, "pan.___", state 2308, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 2310, "(1)"
+       line 395, "pan.___", state 2311, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 2311, "else"
+       line 395, "pan.___", state 2314, "(1)"
+       line 399, "pan.___", state 2322, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 2324, "(1)"
+       line 399, "pan.___", state 2325, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 2325, "else"
+       line 399, "pan.___", state 2328, "(1)"
+       line 399, "pan.___", state 2329, "(1)"
+       line 399, "pan.___", state 2329, "(1)"
+       line 397, "pan.___", state 2334, "((i<1))"
+       line 397, "pan.___", state 2334, "((i>=1))"
+       line 404, "pan.___", state 2340, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2342, "(1)"
+       line 404, "pan.___", state 2343, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 2343, "else"
+       line 404, "pan.___", state 2346, "(1)"
+       line 404, "pan.___", state 2347, "(1)"
+       line 404, "pan.___", state 2347, "(1)"
+       line 408, "pan.___", state 2354, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2356, "(1)"
+       line 408, "pan.___", state 2357, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 2357, "else"
+       line 408, "pan.___", state 2360, "(1)"
+       line 408, "pan.___", state 2361, "(1)"
+       line 408, "pan.___", state 2361, "(1)"
+       line 406, "pan.___", state 2366, "((i<2))"
+       line 406, "pan.___", state 2366, "((i>=2))"
+       line 412, "pan.___", state 2373, "(1)"
+       line 412, "pan.___", state 2374, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 2374, "else"
+       line 412, "pan.___", state 2377, "(1)"
+       line 412, "pan.___", state 2378, "(1)"
+       line 412, "pan.___", state 2378, "(1)"
+       line 416, "pan.___", state 2386, "(1)"
+       line 416, "pan.___", state 2387, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 2387, "else"
+       line 416, "pan.___", state 2390, "(1)"
+       line 416, "pan.___", state 2391, "(1)"
+       line 416, "pan.___", state 2391, "(1)"
+       line 414, "pan.___", state 2396, "((i<1))"
+       line 414, "pan.___", state 2396, "((i>=1))"
+       line 421, "pan.___", state 2403, "(1)"
+       line 421, "pan.___", state 2404, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 2404, "else"
+       line 421, "pan.___", state 2407, "(1)"
+       line 421, "pan.___", state 2408, "(1)"
+       line 421, "pan.___", state 2408, "(1)"
+       line 425, "pan.___", state 2416, "(1)"
+       line 425, "pan.___", state 2417, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 2417, "else"
+       line 425, "pan.___", state 2420, "(1)"
+       line 425, "pan.___", state 2421, "(1)"
+       line 425, "pan.___", state 2421, "(1)"
+       line 423, "pan.___", state 2426, "((i<2))"
+       line 423, "pan.___", state 2426, "((i>=2))"
+       line 430, "pan.___", state 2430, "(1)"
+       line 430, "pan.___", state 2430, "(1)"
+       line 623, "pan.___", state 2433, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 623, "pan.___", state 2434, "_proc_urcu_reader = (_proc_urcu_reader|(1<<23))"
+       line 623, "pan.___", state 2435, "(1)"
+       line 250, "pan.___", state 2439, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 2450, "(1)"
+       line 258, "pan.___", state 2461, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 2470, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 2486, "(1)"
+       line 231, "pan.___", state 2494, "(1)"
+       line 235, "pan.___", state 2506, "(1)"
+       line 239, "pan.___", state 2514, "(1)"
+       line 395, "pan.___", state 2532, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 2546, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2564, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2578, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2597, "(1)"
+       line 416, "pan.___", state 2610, "(1)"
+       line 421, "pan.___", state 2627, "(1)"
+       line 425, "pan.___", state 2640, "(1)"
+       line 250, "pan.___", state 2664, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 2673, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 2686, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 2695, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 2711, "(1)"
+       line 231, "pan.___", state 2719, "(1)"
+       line 235, "pan.___", state 2731, "(1)"
+       line 239, "pan.___", state 2739, "(1)"
+       line 395, "pan.___", state 2757, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 2771, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2789, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2803, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2822, "(1)"
+       line 416, "pan.___", state 2835, "(1)"
+       line 421, "pan.___", state 2852, "(1)"
+       line 425, "pan.___", state 2865, "(1)"
+       line 395, "pan.___", state 2886, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 2900, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2918, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2932, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2951, "(1)"
+       line 416, "pan.___", state 2964, "(1)"
+       line 421, "pan.___", state 2981, "(1)"
+       line 425, "pan.___", state 2994, "(1)"
+       line 227, "pan.___", state 3027, "(1)"
+       line 235, "pan.___", state 3047, "(1)"
+       line 239, "pan.___", state 3055, "(1)"
+       line 227, "pan.___", state 3070, "(1)"
+       line 231, "pan.___", state 3078, "(1)"
+       line 235, "pan.___", state 3090, "(1)"
+       line 239, "pan.___", state 3098, "(1)"
+       line 877, "pan.___", state 3115, "-end-"
+       (318 of 3115 states)
+unreached in proctype urcu_writer
+       line 395, "pan.___", state 19, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 33, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 84, "(1)"
+       line 416, "pan.___", state 97, "(1)"
+       line 250, "pan.___", state 150, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 250, "pan.___", state 152, "(1)"
+       line 254, "pan.___", state 159, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 161, "(1)"
+       line 254, "pan.___", state 162, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 254, "pan.___", state 162, "else"
+       line 252, "pan.___", state 167, "((i<1))"
+       line 252, "pan.___", state 167, "((i>=1))"
+       line 258, "pan.___", state 172, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 174, "(1)"
+       line 258, "pan.___", state 175, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 175, "else"
+       line 262, "pan.___", state 181, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 183, "(1)"
+       line 262, "pan.___", state 184, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 262, "pan.___", state 184, "else"
+       line 267, "pan.___", state 193, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 267, "pan.___", state 193, "else"
+       line 395, "pan.___", state 212, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 226, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 244, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 258, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 277, "(1)"
+       line 416, "pan.___", state 290, "(1)"
+       line 421, "pan.___", state 307, "(1)"
+       line 425, "pan.___", state 320, "(1)"
+       line 399, "pan.___", state 357, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 375, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 389, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 421, "(1)"
+       line 421, "pan.___", state 438, "(1)"
+       line 425, "pan.___", state 451, "(1)"
+       line 399, "pan.___", state 495, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 513, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 527, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 559, "(1)"
+       line 421, "pan.___", state 576, "(1)"
+       line 425, "pan.___", state 589, "(1)"
+       line 399, "pan.___", state 624, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 642, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 656, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 688, "(1)"
+       line 421, "pan.___", state 705, "(1)"
+       line 425, "pan.___", state 718, "(1)"
+       line 399, "pan.___", state 755, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 773, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 787, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 819, "(1)"
+       line 421, "pan.___", state 836, "(1)"
+       line 425, "pan.___", state 849, "(1)"
+       line 250, "pan.___", state 904, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 913, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 951, "(1)"
+       line 231, "pan.___", state 959, "(1)"
+       line 235, "pan.___", state 971, "(1)"
+       line 239, "pan.___", state 979, "(1)"
+       line 254, "pan.___", state 1004, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1017, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1026, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1042, "(1)"
+       line 231, "pan.___", state 1050, "(1)"
+       line 235, "pan.___", state 1062, "(1)"
+       line 239, "pan.___", state 1070, "(1)"
+       line 254, "pan.___", state 1095, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1108, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1117, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1133, "(1)"
+       line 231, "pan.___", state 1141, "(1)"
+       line 235, "pan.___", state 1153, "(1)"
+       line 239, "pan.___", state 1161, "(1)"
+       line 254, "pan.___", state 1186, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1199, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1208, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1224, "(1)"
+       line 231, "pan.___", state 1232, "(1)"
+       line 235, "pan.___", state 1244, "(1)"
+       line 239, "pan.___", state 1252, "(1)"
+       line 1204, "pan.___", state 1267, "-end-"
+       (77 of 1267 states)
+unreached in proctype :init:
+       line 1215, "pan.___", state 9, "((j<2))"
+       line 1215, "pan.___", state 9, "((j>=2))"
+       line 1216, "pan.___", state 20, "((j<2))"
+       line 1216, "pan.___", state 20, "((j>=2))"
+       line 1221, "pan.___", state 33, "((j<2))"
+       line 1221, "pan.___", state 33, "((j>=2))"
+       line 1219, "pan.___", state 43, "((i<1))"
+       line 1219, "pan.___", state 43, "((i>=1))"
+       line 1229, "pan.___", state 54, "((j<2))"
+       line 1229, "pan.___", state 54, "((j>=2))"
+       line 1233, "pan.___", state 67, "((j<2))"
+       line 1233, "pan.___", state 67, "((j>=2))"
+       (6 of 78 states)
+unreached in proctype :never:
+       line 1263, "pan.___", state 8, "-end-"
+       (1 of 8 states)
+
+pan: elapsed time 966 seconds
+pan: rate 1735.7692 states/second
+pan: avg transition delay 1.2616e-06 usec
+cp .input.spin urcu_free_no_wmb.spin.input
+cp .input.spin.trail urcu_free_no_wmb.spin.input.trail
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_wmb.spin.input b/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_wmb.spin.input
new file mode 100644 (file)
index 0000000..e552903
--- /dev/null
@@ -0,0 +1,1240 @@
+#define NO_WMB
+
+// Poison value for freed memory
+#define POISON 1
+// Memory with correct data
+#define WINE 0
+#define SLAB_SIZE 2
+
+#define read_poison    (data_read_first[0] == POISON || data_read_second[0] == POISON)
+
+#define RCU_GP_CTR_BIT (1 << 7)
+#define RCU_GP_CTR_NEST_MASK (RCU_GP_CTR_BIT - 1)
+
+//disabled
+//#define REMOTE_BARRIERS
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+typedef per_proc_bit {
+       bit val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bitfield {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bitfield cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               /*
+                * 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, j);
+               reader_barrier[get_readerid()] = 0;
+       :: 1 ->
+               /*
+                * 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)
+//#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);                                                           \
+       i = 0;                                                                  \
+       do                                                                      \
+       :: i < NR_READERS ->                                                    \
+               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.                                            \
+                */                                                             \
+               do                                                              \
+               :: (reader_barrier[i] == 1) ->                                  \
+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(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, smp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only one reader */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* RCU data */
+DECLARE_CACHED_VAR(bit, rcu_data[SLAB_SIZE]);
+
+/* RCU pointer */
+#if (SLAB_SIZE == 2)
+DECLARE_CACHED_VAR(bit, rcu_ptr);
+bit ptr_read_first[NR_READERS];
+bit ptr_read_second[NR_READERS];
+#else
+DECLARE_CACHED_VAR(byte, rcu_ptr);
+byte ptr_read_first[NR_READERS];
+byte ptr_read_second[NR_READERS];
+#endif
+
+bit data_read_first[NR_READERS];
+bit data_read_second[NR_READERS];
+
+bit init_done = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               ptr_read_first[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb1;
+rmb1_end:
+                               data_read_first[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_first[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               ptr_read_second[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb2;
+rmb2_end:
+                               data_read_second[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_second[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+rmb1:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb1_end;
+rmb2:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_DATA                     (1 << 1)
+#define WRITE_PROC_WMB                 (1 << 2)
+#define WRITE_XCHG_PTR                 (1 << 3)
+
+#define WRITE_PROC_FIRST_MB            (1 << 4)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 5)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 6)
+#define WRITE_PROC_FIRST_WAIT          (1 << 7)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 8)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 9)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 10)
+#define WRITE_PROC_SECOND_WAIT         (1 << 11)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 12)
+
+#define WRITE_PROC_SECOND_MB           (1 << 13)
+
+#define WRITE_FREE                     (1 << 14)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_DATA                    \
+                                       | WRITE_PROC_WMB                \
+                                       | WRITE_XCHG_PTR                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB          \
+                                       | WRITE_FREE)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 15) - 1)
+
+/*
+ * Mutexes are implied around writer execution. A single writer at a time.
+ */
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte cur_data = 0, old_data, loop_nr = 0;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (loop_nr < 3) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               loop_nr = loop_nr + 1;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_WMB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+#endif
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_DATA) ->
+                       ooo_mem(i);
+                       cur_data = (cur_data + 1) % SLAB_SIZE;
+                       WRITE_CACHED_VAR(rcu_data[cur_data], WINE);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_DATA);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA,
+                                 WRITE_PROC_WMB) ->
+                       smp_wmb(i, j);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_WMB,
+                                 WRITE_XCHG_PTR) ->
+                       /* rcu_xchg_pointer() */
+                       atomic {
+                               old_data = READ_CACHED_VAR(rcu_ptr);
+                               WRITE_CACHED_VAR(rcu_ptr, cur_data);
+                       }
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_XCHG_PTR);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_WMB      /* No dependency on
+                                                        * WRITE_DATA because we
+                                                        * write to a
+                                                        * different location. */
+                                 | WRITE_PROC_SECOND_MB
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_FREE) ->
+                       WRITE_CACHED_VAR(rcu_data[old_data], POISON);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_FREE);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+               /*
+                * Note : Promela model adds implicit serialization of the
+                * WRITE_FREE instruction. Normally, it would be permitted to
+                * spill on the next loop execution. Given the validation we do
+                * checks for the data entry read to be poisoned, it's ok if
+                * we do not check "late arriving" memory poisoning.
+                */
+       :: 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
+#ifdef READER_PROGRESS
+               /*
+                * Make sure we don't block the reader's progress.
+                */
+               smp_mb_send(i, j, 5);
+#endif
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(rcu_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       ptr_read_first[i] = 1;
+                       ptr_read_second[i] = 1;
+                       data_read_first[i] = WINE;
+                       data_read_second[i] = WINE;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               INIT_CACHED_VAR(rcu_data[0], WINE, j);
+               i = 1;
+               do
+               :: i < SLAB_SIZE ->
+                       INIT_CACHED_VAR(rcu_data[i], POISON, j);
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_wmb.spin.input.trail b/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_no_wmb.spin.input.trail
new file mode 100644 (file)
index 0000000..0908988
--- /dev/null
@@ -0,0 +1,1202 @@
+-2:3:-2
+-4:-4:-4
+1:0:4462
+2:3:4382
+3:3:4385
+4:3:4385
+5:3:4388
+6:3:4396
+7:3:4396
+8:3:4399
+9:3:4405
+10:3:4409
+11:3:4409
+12:3:4412
+13:3:4422
+14:3:4430
+15:3:4430
+16:3:4433
+17:3:4439
+18:3:4443
+19:3:4443
+20:3:4446
+21:3:4452
+22:3:4456
+23:3:4457
+24:0:4462
+25:3:4459
+26:0:4462
+27:2:3117
+28:0:4462
+29:2:3123
+30:0:4462
+31:2:3124
+32:0:4462
+33:2:3126
+34:0:4462
+35:2:3127
+36:0:4462
+37:2:3128
+38:0:4462
+39:2:3129
+40:2:3130
+41:2:3134
+42:2:3135
+43:2:3143
+44:2:3144
+45:2:3148
+46:2:3149
+47:2:3157
+48:2:3162
+49:2:3166
+50:2:3167
+51:2:3175
+52:2:3176
+53:2:3180
+54:2:3181
+55:2:3175
+56:2:3176
+57:2:3180
+58:2:3181
+59:2:3189
+60:2:3194
+61:2:3195
+62:2:3206
+63:2:3207
+64:2:3208
+65:2:3219
+66:2:3224
+67:2:3225
+68:2:3236
+69:2:3237
+70:2:3238
+71:2:3236
+72:2:3237
+73:2:3238
+74:2:3249
+75:2:3257
+76:0:4462
+77:2:3128
+78:0:4462
+79:2:3309
+80:2:3310
+81:2:3311
+82:0:4462
+83:2:3128
+84:0:4462
+85:2:3316
+86:0:4462
+87:2:4019
+88:2:4020
+89:2:4024
+90:2:4028
+91:2:4029
+92:2:4033
+93:2:4038
+94:2:4046
+95:2:4050
+96:2:4051
+97:2:4046
+98:2:4047
+99:2:4055
+100:2:4062
+101:2:4069
+102:2:4070
+103:2:4077
+104:2:4082
+105:2:4089
+106:2:4090
+107:2:4089
+108:2:4090
+109:2:4097
+110:2:4101
+111:0:4462
+112:2:3318
+113:2:4000
+114:0:4462
+115:2:3128
+116:0:4462
+117:2:3319
+118:0:4462
+119:2:3128
+120:0:4462
+121:2:3322
+122:2:3323
+123:2:3327
+124:2:3328
+125:2:3336
+126:2:3337
+127:2:3341
+128:2:3342
+129:2:3350
+130:2:3355
+131:2:3359
+132:2:3360
+133:2:3368
+134:2:3369
+135:2:3373
+136:2:3374
+137:2:3368
+138:2:3369
+139:2:3373
+140:2:3374
+141:2:3382
+142:2:3387
+143:2:3388
+144:2:3399
+145:2:3400
+146:2:3401
+147:2:3412
+148:2:3417
+149:2:3418
+150:2:3429
+151:2:3430
+152:2:3431
+153:2:3429
+154:2:3430
+155:2:3431
+156:2:3442
+157:2:3449
+158:0:4462
+159:2:3128
+160:0:4462
+161:2:3453
+162:2:3454
+163:2:3455
+164:2:3467
+165:2:3468
+166:2:3472
+167:2:3473
+168:2:3481
+169:2:3486
+170:2:3490
+171:2:3491
+172:2:3499
+173:2:3500
+174:2:3504
+175:2:3505
+176:2:3499
+177:2:3500
+178:2:3504
+179:2:3505
+180:2:3513
+181:2:3518
+182:2:3519
+183:2:3530
+184:2:3531
+185:2:3532
+186:2:3543
+187:2:3548
+188:2:3549
+189:2:3560
+190:2:3561
+191:2:3562
+192:2:3560
+193:2:3561
+194:2:3562
+195:2:3573
+196:2:3584
+197:2:3585
+198:0:4462
+199:2:3128
+200:0:4462
+201:2:3591
+202:2:3592
+203:2:3596
+204:2:3597
+205:2:3605
+206:2:3606
+207:2:3610
+208:2:3611
+209:2:3619
+210:2:3624
+211:2:3628
+212:2:3629
+213:2:3637
+214:2:3638
+215:2:3642
+216:2:3643
+217:2:3637
+218:2:3638
+219:2:3642
+220:2:3643
+221:2:3651
+222:2:3656
+223:2:3657
+224:2:3668
+225:2:3669
+226:2:3670
+227:2:3681
+228:2:3686
+229:2:3687
+230:2:3698
+231:2:3699
+232:2:3700
+233:2:3698
+234:2:3699
+235:2:3700
+236:2:3711
+237:0:4462
+238:2:3128
+239:0:4462
+240:2:3720
+241:2:3721
+242:2:3725
+243:2:3726
+244:2:3734
+245:2:3735
+246:2:3739
+247:2:3740
+248:2:3748
+249:2:3753
+250:2:3757
+251:2:3758
+252:2:3766
+253:2:3767
+254:2:3771
+255:2:3772
+256:2:3766
+257:2:3767
+258:2:3771
+259:2:3772
+260:2:3780
+261:2:3785
+262:2:3786
+263:2:3797
+264:2:3798
+265:2:3799
+266:2:3810
+267:2:3815
+268:2:3816
+269:2:3827
+270:2:3828
+271:2:3829
+272:2:3827
+273:2:3828
+274:2:3829
+275:2:3840
+276:2:3847
+277:0:4462
+278:2:3128
+279:0:4462
+280:2:3851
+281:2:3852
+282:2:3853
+283:2:3865
+284:2:3866
+285:2:3870
+286:2:3871
+287:2:3879
+288:2:3884
+289:2:3888
+290:2:3889
+291:2:3897
+292:2:3898
+293:2:3902
+294:2:3903
+295:2:3897
+296:2:3898
+297:2:3902
+298:2:3903
+299:2:3911
+300:2:3916
+301:2:3917
+302:2:3928
+303:2:3929
+304:2:3930
+305:2:3941
+306:2:3946
+307:2:3947
+308:2:3958
+309:2:3959
+310:2:3960
+311:2:3958
+312:2:3959
+313:2:3960
+314:2:3971
+315:2:3981
+316:2:3982
+317:0:4462
+318:2:3128
+319:0:4462
+320:2:3988
+321:0:4462
+322:2:4292
+323:2:4293
+324:2:4297
+325:2:4301
+326:2:4302
+327:2:4306
+328:2:4314
+329:2:4315
+330:2:4319
+331:2:4323
+332:2:4324
+333:2:4319
+334:2:4323
+335:2:4324
+336:2:4328
+337:2:4335
+338:2:4342
+339:2:4343
+340:2:4350
+341:2:4355
+342:2:4362
+343:2:4363
+344:2:4362
+345:2:4363
+346:2:4370
+347:2:4374
+348:0:4462
+349:2:3990
+350:2:4000
+351:0:4462
+352:2:3128
+353:0:4462
+354:2:3991
+355:2:3992
+356:0:4462
+357:2:3128
+358:0:4462
+359:2:3996
+360:0:4462
+361:2:4004
+362:0:4462
+363:2:3124
+364:0:4462
+365:2:3126
+366:0:4462
+367:2:3127
+368:0:4462
+369:2:3128
+370:0:4462
+371:2:3309
+372:2:3310
+373:2:3311
+374:0:4462
+375:2:3128
+376:0:4462
+377:2:3129
+378:2:3130
+379:2:3134
+380:2:3135
+381:2:3143
+382:2:3144
+383:2:3148
+384:2:3149
+385:2:3157
+386:2:3162
+387:2:3163
+388:2:3175
+389:2:3176
+390:2:3177
+391:2:3175
+392:2:3176
+393:2:3180
+394:2:3181
+395:2:3189
+396:2:3194
+397:2:3195
+398:2:3206
+399:2:3207
+400:2:3208
+401:2:3219
+402:2:3224
+403:2:3225
+404:2:3236
+405:2:3237
+406:2:3238
+407:2:3236
+408:2:3237
+409:2:3238
+410:2:3249
+411:2:3257
+412:0:4462
+413:2:3128
+414:0:4462
+415:2:3316
+416:0:4462
+417:2:4019
+418:2:4020
+419:2:4024
+420:2:4028
+421:2:4029
+422:2:4033
+423:2:4041
+424:2:4042
+425:2:4046
+426:2:4047
+427:2:4046
+428:2:4050
+429:2:4051
+430:2:4055
+431:2:4062
+432:2:4069
+433:2:4070
+434:2:4077
+435:2:4082
+436:2:4089
+437:2:4090
+438:2:4089
+439:2:4090
+440:2:4097
+441:2:4101
+442:0:4462
+443:2:3318
+444:2:4000
+445:0:4462
+446:2:3128
+447:0:4462
+448:2:3319
+449:0:4462
+450:2:3128
+451:0:4462
+452:2:3322
+453:2:3323
+454:2:3327
+455:2:3328
+456:2:3336
+457:2:3337
+458:2:3341
+459:2:3342
+460:2:3350
+461:2:3355
+462:2:3359
+463:2:3360
+464:2:3368
+465:2:3369
+466:2:3373
+467:2:3374
+468:2:3368
+469:2:3369
+470:2:3373
+471:2:3374
+472:2:3382
+473:2:3387
+474:2:3388
+475:2:3399
+476:2:3400
+477:2:3401
+478:2:3412
+479:2:3417
+480:2:3418
+481:2:3429
+482:2:3430
+483:2:3431
+484:2:3429
+485:2:3430
+486:2:3431
+487:2:3442
+488:2:3449
+489:0:4462
+490:2:3128
+491:0:4462
+492:2:3453
+493:2:3454
+494:2:3455
+495:2:3467
+496:2:3468
+497:2:3472
+498:2:3473
+499:2:3481
+500:2:3486
+501:2:3490
+502:2:3491
+503:2:3499
+504:2:3500
+505:2:3504
+506:2:3505
+507:2:3499
+508:2:3500
+509:2:3504
+510:2:3505
+511:2:3513
+512:2:3518
+513:2:3519
+514:2:3530
+515:2:3531
+516:2:3532
+517:2:3543
+518:2:3548
+519:2:3549
+520:2:3560
+521:2:3561
+522:2:3562
+523:2:3560
+524:2:3561
+525:2:3562
+526:2:3573
+527:2:3584
+528:2:3585
+529:0:4462
+530:2:3128
+531:0:4462
+532:2:3591
+533:2:3592
+534:2:3596
+535:2:3597
+536:2:3605
+537:2:3606
+538:2:3610
+539:2:3611
+540:2:3619
+541:2:3624
+542:2:3628
+543:2:3629
+544:2:3637
+545:2:3638
+546:2:3642
+547:2:3643
+548:2:3637
+549:2:3638
+550:2:3642
+551:2:3643
+552:2:3651
+553:2:3656
+554:2:3657
+555:2:3668
+556:2:3669
+557:2:3670
+558:2:3681
+559:2:3686
+560:2:3687
+561:2:3698
+562:2:3699
+563:2:3700
+564:2:3698
+565:2:3699
+566:2:3700
+567:2:3711
+568:0:4462
+569:2:3128
+570:0:4462
+571:2:3720
+572:2:3721
+573:2:3725
+574:2:3726
+575:2:3734
+576:2:3735
+577:2:3739
+578:2:3740
+579:2:3748
+580:2:3753
+581:2:3757
+582:2:3758
+583:2:3766
+584:2:3767
+585:2:3771
+586:2:3772
+587:2:3766
+588:2:3767
+589:2:3771
+590:2:3772
+591:2:3780
+592:2:3785
+593:2:3786
+594:2:3797
+595:2:3798
+596:2:3799
+597:2:3810
+598:2:3815
+599:2:3816
+600:2:3827
+601:2:3828
+602:2:3829
+603:2:3827
+604:2:3828
+605:2:3829
+606:2:3840
+607:2:3847
+608:0:4462
+609:2:3128
+610:0:4462
+611:2:3851
+612:2:3852
+613:2:3853
+614:2:3865
+615:2:3866
+616:2:3870
+617:2:3871
+618:2:3879
+619:2:3884
+620:2:3888
+621:2:3889
+622:2:3897
+623:2:3898
+624:2:3902
+625:2:3903
+626:2:3897
+627:2:3898
+628:2:3902
+629:2:3903
+630:2:3911
+631:2:3916
+632:2:3917
+633:2:3928
+634:2:3929
+635:2:3930
+636:2:3941
+637:2:3946
+638:2:3947
+639:2:3958
+640:2:3959
+641:2:3960
+642:2:3958
+643:2:3959
+644:2:3960
+645:2:3971
+646:2:3981
+647:2:3982
+648:0:4462
+649:2:3128
+650:0:4462
+651:2:3988
+652:0:4462
+653:2:4292
+654:2:4293
+655:2:4297
+656:2:4301
+657:2:4302
+658:2:4306
+659:2:4314
+660:2:4315
+661:2:4319
+662:2:4323
+663:2:4324
+664:2:4319
+665:2:4323
+666:2:4324
+667:2:4328
+668:2:4335
+669:2:4342
+670:2:4343
+671:2:4350
+672:2:4355
+673:2:4362
+674:2:4363
+675:2:4362
+676:2:4363
+677:2:4370
+678:2:4374
+679:0:4462
+680:2:3990
+681:2:4000
+682:0:4462
+683:2:3128
+684:0:4462
+685:2:3991
+686:2:3992
+687:0:4462
+688:2:3128
+689:0:4462
+690:2:3996
+691:0:4462
+692:2:4004
+693:0:4462
+694:2:3124
+695:0:4462
+696:2:3126
+697:0:4462
+698:2:3127
+699:0:4462
+700:2:3128
+701:0:4462
+702:2:3129
+703:2:3130
+704:2:3134
+705:2:3135
+706:2:3143
+707:2:3144
+708:2:3148
+709:2:3149
+710:2:3157
+711:2:3162
+712:2:3166
+713:2:3167
+714:2:3175
+715:2:3176
+716:2:3180
+717:2:3181
+718:2:3175
+719:2:3176
+720:2:3177
+721:2:3189
+722:2:3194
+723:2:3195
+724:2:3206
+725:2:3207
+726:2:3208
+727:2:3219
+728:2:3224
+729:2:3225
+730:2:3236
+731:2:3237
+732:2:3238
+733:2:3236
+734:2:3237
+735:2:3238
+736:2:3249
+737:2:3257
+738:0:4462
+739:2:3128
+740:0:4462
+741:2:3309
+742:2:3310
+743:2:3311
+744:0:4462
+745:2:3128
+746:0:4462
+747:2:3316
+748:0:4462
+749:1:2
+750:0:4462
+751:1:8
+752:0:4462
+753:1:9
+754:0:4462
+755:1:10
+756:0:4462
+757:1:11
+758:0:4462
+759:1:12
+760:1:13
+761:1:17
+762:1:18
+763:1:26
+764:1:27
+765:1:31
+766:1:32
+767:1:40
+768:1:45
+769:1:49
+770:1:50
+771:1:58
+772:1:59
+773:1:63
+774:1:64
+775:1:58
+776:1:59
+777:1:63
+778:1:64
+779:1:72
+780:1:77
+781:1:78
+782:1:89
+783:1:90
+784:1:91
+785:1:102
+786:1:107
+787:1:108
+788:1:119
+789:1:120
+790:1:121
+791:1:119
+792:1:120
+793:1:121
+794:1:132
+795:0:4462
+796:1:11
+797:0:4462
+798:1:141
+799:1:142
+800:0:4462
+801:1:11
+802:0:4462
+803:1:148
+804:1:149
+805:1:153
+806:1:154
+807:1:162
+808:1:163
+809:1:167
+810:1:168
+811:1:176
+812:1:181
+813:1:185
+814:1:186
+815:1:194
+816:1:195
+817:1:199
+818:1:200
+819:1:194
+820:1:195
+821:1:199
+822:1:200
+823:1:208
+824:1:213
+825:1:214
+826:1:225
+827:1:226
+828:1:227
+829:1:238
+830:1:243
+831:1:244
+832:1:255
+833:1:256
+834:1:257
+835:1:255
+836:1:256
+837:1:257
+838:1:268
+839:0:4462
+840:1:11
+841:0:4462
+842:1:277
+843:1:278
+844:1:282
+845:1:283
+846:1:291
+847:1:292
+848:1:296
+849:1:297
+850:1:305
+851:1:310
+852:1:314
+853:1:315
+854:1:323
+855:1:324
+856:1:328
+857:1:329
+858:1:323
+859:1:324
+860:1:328
+861:1:329
+862:1:337
+863:1:342
+864:1:343
+865:1:354
+866:1:355
+867:1:356
+868:1:367
+869:1:372
+870:1:373
+871:1:384
+872:1:385
+873:1:386
+874:1:384
+875:1:385
+876:1:386
+877:1:397
+878:1:404
+879:0:4462
+880:1:11
+881:0:4462
+882:1:540
+883:1:544
+884:1:545
+885:1:549
+886:1:550
+887:1:558
+888:1:566
+889:1:567
+890:1:571
+891:1:575
+892:1:576
+893:1:571
+894:1:575
+895:1:576
+896:1:580
+897:1:587
+898:1:594
+899:1:595
+900:1:602
+901:1:607
+902:1:614
+903:1:615
+904:1:614
+905:1:615
+906:1:622
+907:0:4462
+908:1:11
+909:0:4462
+910:1:632
+911:1:633
+912:1:637
+913:1:638
+914:1:646
+915:1:647
+916:1:651
+917:1:652
+918:1:660
+919:1:665
+920:1:669
+921:1:670
+922:1:678
+923:1:679
+924:1:683
+925:1:684
+926:1:678
+927:1:679
+928:1:683
+929:1:684
+930:1:692
+931:1:697
+932:1:698
+933:1:709
+934:1:710
+935:1:711
+936:1:722
+937:1:727
+938:1:728
+939:1:739
+940:1:740
+941:1:741
+942:1:739
+943:1:740
+944:1:741
+945:1:752
+946:0:4462
+947:1:11
+948:0:4462
+949:1:761
+950:1:764
+951:1:765
+952:0:4462
+953:1:11
+954:0:4462
+955:1:1028
+956:1:1029
+957:1:1033
+958:1:1034
+959:1:1042
+960:1:1043
+961:1:1047
+962:1:1048
+963:1:1056
+964:1:1061
+965:1:1065
+966:1:1066
+967:1:1074
+968:1:1075
+969:1:1079
+970:1:1080
+971:1:1074
+972:1:1075
+973:1:1079
+974:1:1080
+975:1:1088
+976:1:1093
+977:1:1094
+978:1:1105
+979:1:1106
+980:1:1107
+981:1:1118
+982:1:1123
+983:1:1124
+984:1:1135
+985:1:1136
+986:1:1137
+987:1:1135
+988:1:1136
+989:1:1137
+990:1:1148
+991:1:1155
+992:1:1159
+993:0:4462
+994:1:11
+995:0:4462
+996:1:1160
+997:1:1161
+998:1:1165
+999:1:1166
+1000:1:1174
+1001:1:1175
+1002:1:1176
+1003:1:1188
+1004:1:1193
+1005:1:1197
+1006:1:1198
+1007:1:1206
+1008:1:1207
+1009:1:1211
+1010:1:1212
+1011:1:1206
+1012:1:1207
+1013:1:1211
+1014:1:1212
+1015:1:1220
+1016:1:1225
+1017:1:1226
+1018:1:1237
+1019:1:1238
+1020:1:1239
+1021:1:1250
+1022:1:1255
+1023:1:1256
+1024:1:1267
+1025:1:1268
+1026:1:1269
+1027:1:1267
+1028:1:1268
+1029:1:1269
+1030:1:1280
+1031:0:4462
+1032:1:11
+1033:0:4462
+1034:1:1289
+1035:0:4462
+1036:1:3023
+1037:1:3030
+1038:1:3031
+1039:1:3038
+1040:1:3043
+1041:1:3050
+1042:1:3051
+1043:1:3050
+1044:1:3051
+1045:1:3058
+1046:1:3062
+1047:0:4462
+1048:2:4019
+1049:2:4020
+1050:2:4024
+1051:2:4028
+1052:2:4029
+1053:2:4033
+1054:2:4038
+1055:2:4046
+1056:2:4050
+1057:2:4051
+1058:2:4046
+1059:2:4047
+1060:2:4055
+1061:2:4062
+1062:2:4069
+1063:2:4070
+1064:2:4077
+1065:2:4082
+1066:2:4089
+1067:2:4090
+1068:2:4089
+1069:2:4090
+1070:2:4097
+1071:2:4101
+1072:0:4462
+1073:2:3318
+1074:2:4000
+1075:0:4462
+1076:2:3128
+1077:0:4462
+1078:2:3319
+1079:0:4462
+1080:2:3128
+1081:0:4462
+1082:2:3322
+1083:2:3323
+1084:2:3327
+1085:2:3328
+1086:2:3336
+1087:2:3337
+1088:2:3341
+1089:2:3342
+1090:2:3350
+1091:2:3355
+1092:2:3359
+1093:2:3360
+1094:2:3368
+1095:2:3369
+1096:2:3373
+1097:2:3374
+1098:2:3368
+1099:2:3369
+1100:2:3373
+1101:2:3374
+1102:2:3382
+1103:2:3387
+1104:2:3388
+1105:2:3399
+1106:2:3400
+1107:2:3401
+1108:2:3412
+1109:2:3417
+1110:2:3418
+1111:2:3429
+1112:2:3430
+1113:2:3431
+1114:2:3429
+1115:2:3430
+1116:2:3431
+1117:2:3442
+1118:2:3449
+1119:0:4462
+1120:2:3128
+1121:0:4462
+1122:2:3453
+1123:2:3454
+1124:2:3455
+1125:2:3467
+1126:2:3468
+1127:2:3472
+1128:2:3473
+1129:2:3481
+1130:2:3486
+1131:2:3490
+1132:2:3491
+1133:2:3499
+1134:2:3500
+1135:2:3504
+1136:2:3505
+1137:2:3499
+1138:2:3500
+1139:2:3504
+1140:2:3505
+1141:2:3513
+1142:2:3518
+1143:2:3519
+1144:2:3530
+1145:2:3531
+1146:2:3532
+1147:2:3543
+1148:2:3548
+1149:2:3549
+1150:2:3560
+1151:2:3561
+1152:2:3562
+1153:2:3560
+1154:2:3561
+1155:2:3562
+1156:2:3573
+1157:2:3582
+1158:0:4462
+1159:2:3128
+1160:0:4462
+1161:2:3588
+1162:0:4462
+1163:2:4110
+1164:2:4111
+1165:2:4115
+1166:2:4119
+1167:2:4120
+1168:2:4124
+1169:2:4132
+1170:2:4133
+1171:2:4137
+1172:2:4141
+1173:2:4142
+1174:2:4137
+1175:2:4141
+1176:2:4142
+1177:2:4146
+1178:2:4153
+1179:2:4160
+1180:2:4161
+1181:2:4168
+1182:2:4173
+1183:2:4180
+1184:2:4181
+1185:2:4180
+1186:2:4181
+1187:2:4188
+1188:2:4192
+1189:0:4462
+1190:2:3590
+1191:2:4000
+1192:0:4462
+1193:2:3128
+1194:0:4462
+1195:1:1291
+1196:1:1292
+1197:0:4460
+1198:1:11
+1199:0:4466
+1200:2:3477
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_single_flip.define b/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_single_flip.define
new file mode 100644 (file)
index 0000000..5e642ef
--- /dev/null
@@ -0,0 +1 @@
+#define SINGLE_FLIP
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_single_flip.log b/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_single_flip.log
new file mode 100644 (file)
index 0000000..e414670
--- /dev/null
@@ -0,0 +1,732 @@
+rm -f pan* trail.out .input.spin* *.spin.trail .input.define
+touch .input.define
+cat .input.define >> pan.ltl
+cat DEFINES >> pan.ltl
+spin -f "!(`cat urcu_free.ltl | grep -v ^//`)" >> pan.ltl
+cp urcu_free_single_flip.define .input.define
+cat .input.define > .input.spin
+cat DEFINES >> .input.spin
+cat urcu.spin >> .input.spin
+rm -f .input.spin.trail
+spin -a -X -N pan.ltl .input.spin
+Exit-Status 0
+gcc -O2 -w -DHASH64 -o pan pan.c
+./pan -a -v -c1 -X -m10000000 -w20
+warning: for p.o. reduction to be valid the never claim must be stutter-invariant
+(never claims generated from LTL formulae are stutter-invariant)
+depth 0: Claim reached state 5 (line 1258)
+pan: claim violated! (at depth 1036)
+pan: wrote .input.spin.trail
+
+(Spin Version 5.1.7 -- 23 December 2008)
+Warning: Search not completed
+       + Partial Order Reduction
+
+Full statespace search for:
+       never claim             +
+       assertion violations    + (if within scope of claim)
+       acceptance   cycles     + (fairness disabled)
+       invalid end states      - (disabled by never claim)
+
+State-vector 88 byte, depth reached 4474, errors: 1
+   607250 states, stored
+2.1024134e+08 states, matched
+2.1084859e+08 transitions (= stored+matched)
+1.2498522e+09 atomic steps
+hash conflicts:  36422558 (resolved)
+
+Stats on memory usage (in Megabytes):
+   67.178      equivalent memory usage for states (stored*(State-vector + overhead))
+   51.749      actual memory usage for states (compression: 77.03%)
+               state-vector as stored = 61 byte + 28 byte overhead
+    8.000      memory used for hash table (-w20)
+  457.764      memory used for DFS stack (-m10000000)
+  517.424      total actual memory usage
+
+unreached in proctype urcu_reader
+       line 395, "pan.___", state 17, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 49, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 63, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 82, "(1)"
+       line 421, "pan.___", state 112, "(1)"
+       line 425, "pan.___", state 125, "(1)"
+       line 576, "pan.___", state 146, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<1))"
+       line 395, "pan.___", state 153, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 185, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 199, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 218, "(1)"
+       line 421, "pan.___", state 248, "(1)"
+       line 425, "pan.___", state 261, "(1)"
+       line 395, "pan.___", state 282, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 314, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 328, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 347, "(1)"
+       line 421, "pan.___", state 377, "(1)"
+       line 425, "pan.___", state 390, "(1)"
+       line 395, "pan.___", state 413, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 415, "(1)"
+       line 395, "pan.___", state 416, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 416, "else"
+       line 395, "pan.___", state 419, "(1)"
+       line 399, "pan.___", state 427, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 429, "(1)"
+       line 399, "pan.___", state 430, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 430, "else"
+       line 399, "pan.___", state 433, "(1)"
+       line 399, "pan.___", state 434, "(1)"
+       line 399, "pan.___", state 434, "(1)"
+       line 397, "pan.___", state 439, "((i<1))"
+       line 397, "pan.___", state 439, "((i>=1))"
+       line 404, "pan.___", state 445, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 447, "(1)"
+       line 404, "pan.___", state 448, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 448, "else"
+       line 404, "pan.___", state 451, "(1)"
+       line 404, "pan.___", state 452, "(1)"
+       line 404, "pan.___", state 452, "(1)"
+       line 408, "pan.___", state 459, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 461, "(1)"
+       line 408, "pan.___", state 462, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 462, "else"
+       line 408, "pan.___", state 465, "(1)"
+       line 408, "pan.___", state 466, "(1)"
+       line 408, "pan.___", state 466, "(1)"
+       line 406, "pan.___", state 471, "((i<2))"
+       line 406, "pan.___", state 471, "((i>=2))"
+       line 412, "pan.___", state 478, "(1)"
+       line 412, "pan.___", state 479, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 479, "else"
+       line 412, "pan.___", state 482, "(1)"
+       line 412, "pan.___", state 483, "(1)"
+       line 412, "pan.___", state 483, "(1)"
+       line 416, "pan.___", state 491, "(1)"
+       line 416, "pan.___", state 492, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 492, "else"
+       line 416, "pan.___", state 495, "(1)"
+       line 416, "pan.___", state 496, "(1)"
+       line 416, "pan.___", state 496, "(1)"
+       line 414, "pan.___", state 501, "((i<1))"
+       line 414, "pan.___", state 501, "((i>=1))"
+       line 421, "pan.___", state 508, "(1)"
+       line 421, "pan.___", state 509, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 509, "else"
+       line 421, "pan.___", state 512, "(1)"
+       line 421, "pan.___", state 513, "(1)"
+       line 421, "pan.___", state 513, "(1)"
+       line 425, "pan.___", state 521, "(1)"
+       line 425, "pan.___", state 522, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 522, "else"
+       line 425, "pan.___", state 525, "(1)"
+       line 425, "pan.___", state 526, "(1)"
+       line 425, "pan.___", state 526, "(1)"
+       line 423, "pan.___", state 531, "((i<2))"
+       line 423, "pan.___", state 531, "((i>=2))"
+       line 430, "pan.___", state 535, "(1)"
+       line 430, "pan.___", state 535, "(1)"
+       line 576, "pan.___", state 538, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 576, "pan.___", state 539, "_proc_urcu_reader = (_proc_urcu_reader|(1<<5))"
+       line 576, "pan.___", state 540, "(1)"
+       line 250, "pan.___", state 544, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 555, "(1)"
+       line 258, "pan.___", state 566, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 575, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 591, "(1)"
+       line 231, "pan.___", state 599, "(1)"
+       line 235, "pan.___", state 611, "(1)"
+       line 239, "pan.___", state 619, "(1)"
+       line 395, "pan.___", state 637, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 651, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 669, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 683, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 702, "(1)"
+       line 416, "pan.___", state 715, "(1)"
+       line 421, "pan.___", state 732, "(1)"
+       line 425, "pan.___", state 745, "(1)"
+       line 395, "pan.___", state 773, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 775, "(1)"
+       line 395, "pan.___", state 776, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 776, "else"
+       line 395, "pan.___", state 779, "(1)"
+       line 399, "pan.___", state 787, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 789, "(1)"
+       line 399, "pan.___", state 790, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 790, "else"
+       line 399, "pan.___", state 793, "(1)"
+       line 399, "pan.___", state 794, "(1)"
+       line 399, "pan.___", state 794, "(1)"
+       line 397, "pan.___", state 799, "((i<1))"
+       line 397, "pan.___", state 799, "((i>=1))"
+       line 404, "pan.___", state 805, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 807, "(1)"
+       line 404, "pan.___", state 808, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 808, "else"
+       line 404, "pan.___", state 811, "(1)"
+       line 404, "pan.___", state 812, "(1)"
+       line 404, "pan.___", state 812, "(1)"
+       line 408, "pan.___", state 819, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 821, "(1)"
+       line 408, "pan.___", state 822, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 822, "else"
+       line 408, "pan.___", state 825, "(1)"
+       line 408, "pan.___", state 826, "(1)"
+       line 408, "pan.___", state 826, "(1)"
+       line 406, "pan.___", state 831, "((i<2))"
+       line 406, "pan.___", state 831, "((i>=2))"
+       line 412, "pan.___", state 838, "(1)"
+       line 412, "pan.___", state 839, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 839, "else"
+       line 412, "pan.___", state 842, "(1)"
+       line 412, "pan.___", state 843, "(1)"
+       line 412, "pan.___", state 843, "(1)"
+       line 416, "pan.___", state 851, "(1)"
+       line 416, "pan.___", state 852, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 852, "else"
+       line 416, "pan.___", state 855, "(1)"
+       line 416, "pan.___", state 856, "(1)"
+       line 416, "pan.___", state 856, "(1)"
+       line 414, "pan.___", state 861, "((i<1))"
+       line 414, "pan.___", state 861, "((i>=1))"
+       line 421, "pan.___", state 868, "(1)"
+       line 421, "pan.___", state 869, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 869, "else"
+       line 421, "pan.___", state 872, "(1)"
+       line 421, "pan.___", state 873, "(1)"
+       line 421, "pan.___", state 873, "(1)"
+       line 425, "pan.___", state 881, "(1)"
+       line 425, "pan.___", state 882, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 882, "else"
+       line 425, "pan.___", state 885, "(1)"
+       line 425, "pan.___", state 886, "(1)"
+       line 425, "pan.___", state 886, "(1)"
+       line 430, "pan.___", state 895, "(1)"
+       line 430, "pan.___", state 895, "(1)"
+       line 395, "pan.___", state 902, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 904, "(1)"
+       line 395, "pan.___", state 905, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 905, "else"
+       line 395, "pan.___", state 908, "(1)"
+       line 399, "pan.___", state 916, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 918, "(1)"
+       line 399, "pan.___", state 919, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 919, "else"
+       line 399, "pan.___", state 922, "(1)"
+       line 399, "pan.___", state 923, "(1)"
+       line 399, "pan.___", state 923, "(1)"
+       line 397, "pan.___", state 928, "((i<1))"
+       line 397, "pan.___", state 928, "((i>=1))"
+       line 404, "pan.___", state 934, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 936, "(1)"
+       line 404, "pan.___", state 937, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 937, "else"
+       line 404, "pan.___", state 940, "(1)"
+       line 404, "pan.___", state 941, "(1)"
+       line 404, "pan.___", state 941, "(1)"
+       line 408, "pan.___", state 948, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 950, "(1)"
+       line 408, "pan.___", state 951, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 951, "else"
+       line 408, "pan.___", state 954, "(1)"
+       line 408, "pan.___", state 955, "(1)"
+       line 408, "pan.___", state 955, "(1)"
+       line 406, "pan.___", state 960, "((i<2))"
+       line 406, "pan.___", state 960, "((i>=2))"
+       line 412, "pan.___", state 967, "(1)"
+       line 412, "pan.___", state 968, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 968, "else"
+       line 412, "pan.___", state 971, "(1)"
+       line 412, "pan.___", state 972, "(1)"
+       line 412, "pan.___", state 972, "(1)"
+       line 416, "pan.___", state 980, "(1)"
+       line 416, "pan.___", state 981, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 981, "else"
+       line 416, "pan.___", state 984, "(1)"
+       line 416, "pan.___", state 985, "(1)"
+       line 416, "pan.___", state 985, "(1)"
+       line 414, "pan.___", state 990, "((i<1))"
+       line 414, "pan.___", state 990, "((i>=1))"
+       line 421, "pan.___", state 997, "(1)"
+       line 421, "pan.___", state 998, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 998, "else"
+       line 421, "pan.___", state 1001, "(1)"
+       line 421, "pan.___", state 1002, "(1)"
+       line 421, "pan.___", state 1002, "(1)"
+       line 425, "pan.___", state 1010, "(1)"
+       line 425, "pan.___", state 1011, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 1011, "else"
+       line 425, "pan.___", state 1014, "(1)"
+       line 425, "pan.___", state 1015, "(1)"
+       line 425, "pan.___", state 1015, "(1)"
+       line 423, "pan.___", state 1020, "((i<2))"
+       line 423, "pan.___", state 1020, "((i>=2))"
+       line 430, "pan.___", state 1024, "(1)"
+       line 430, "pan.___", state 1024, "(1)"
+       line 584, "pan.___", state 1028, "_proc_urcu_reader = (_proc_urcu_reader|(1<<11))"
+       line 395, "pan.___", state 1033, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 1047, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1065, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1079, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1098, "(1)"
+       line 416, "pan.___", state 1111, "(1)"
+       line 421, "pan.___", state 1128, "(1)"
+       line 425, "pan.___", state 1141, "(1)"
+       line 395, "pan.___", state 1165, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1197, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1211, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1230, "(1)"
+       line 421, "pan.___", state 1260, "(1)"
+       line 425, "pan.___", state 1273, "(1)"
+       line 395, "pan.___", state 1298, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1330, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1344, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1363, "(1)"
+       line 421, "pan.___", state 1393, "(1)"
+       line 425, "pan.___", state 1406, "(1)"
+       line 395, "pan.___", state 1427, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1459, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1473, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1492, "(1)"
+       line 421, "pan.___", state 1522, "(1)"
+       line 425, "pan.___", state 1535, "(1)"
+       line 250, "pan.___", state 1558, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1580, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1589, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1605, "(1)"
+       line 231, "pan.___", state 1613, "(1)"
+       line 235, "pan.___", state 1625, "(1)"
+       line 239, "pan.___", state 1633, "(1)"
+       line 395, "pan.___", state 1651, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 1665, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1683, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1697, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1716, "(1)"
+       line 416, "pan.___", state 1729, "(1)"
+       line 421, "pan.___", state 1746, "(1)"
+       line 425, "pan.___", state 1759, "(1)"
+       line 395, "pan.___", state 1780, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 1794, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1812, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1826, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1845, "(1)"
+       line 416, "pan.___", state 1858, "(1)"
+       line 421, "pan.___", state 1875, "(1)"
+       line 425, "pan.___", state 1888, "(1)"
+       line 395, "pan.___", state 1912, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 1928, "(1)"
+       line 404, "pan.___", state 1944, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1958, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1977, "(1)"
+       line 421, "pan.___", state 2007, "(1)"
+       line 425, "pan.___", state 2020, "(1)"
+       line 623, "pan.___", state 2041, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<19))"
+       line 395, "pan.___", state 2048, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2080, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2094, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2113, "(1)"
+       line 421, "pan.___", state 2143, "(1)"
+       line 425, "pan.___", state 2156, "(1)"
+       line 395, "pan.___", state 2177, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2209, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2223, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2242, "(1)"
+       line 421, "pan.___", state 2272, "(1)"
+       line 425, "pan.___", state 2285, "(1)"
+       line 395, "pan.___", state 2308, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 2310, "(1)"
+       line 395, "pan.___", state 2311, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 2311, "else"
+       line 395, "pan.___", state 2314, "(1)"
+       line 399, "pan.___", state 2322, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 2324, "(1)"
+       line 399, "pan.___", state 2325, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 2325, "else"
+       line 399, "pan.___", state 2328, "(1)"
+       line 399, "pan.___", state 2329, "(1)"
+       line 399, "pan.___", state 2329, "(1)"
+       line 397, "pan.___", state 2334, "((i<1))"
+       line 397, "pan.___", state 2334, "((i>=1))"
+       line 404, "pan.___", state 2340, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2342, "(1)"
+       line 404, "pan.___", state 2343, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 2343, "else"
+       line 404, "pan.___", state 2346, "(1)"
+       line 404, "pan.___", state 2347, "(1)"
+       line 404, "pan.___", state 2347, "(1)"
+       line 408, "pan.___", state 2354, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2356, "(1)"
+       line 408, "pan.___", state 2357, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 2357, "else"
+       line 408, "pan.___", state 2360, "(1)"
+       line 408, "pan.___", state 2361, "(1)"
+       line 408, "pan.___", state 2361, "(1)"
+       line 406, "pan.___", state 2366, "((i<2))"
+       line 406, "pan.___", state 2366, "((i>=2))"
+       line 412, "pan.___", state 2373, "(1)"
+       line 412, "pan.___", state 2374, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 2374, "else"
+       line 412, "pan.___", state 2377, "(1)"
+       line 412, "pan.___", state 2378, "(1)"
+       line 412, "pan.___", state 2378, "(1)"
+       line 416, "pan.___", state 2386, "(1)"
+       line 416, "pan.___", state 2387, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 2387, "else"
+       line 416, "pan.___", state 2390, "(1)"
+       line 416, "pan.___", state 2391, "(1)"
+       line 416, "pan.___", state 2391, "(1)"
+       line 414, "pan.___", state 2396, "((i<1))"
+       line 414, "pan.___", state 2396, "((i>=1))"
+       line 421, "pan.___", state 2403, "(1)"
+       line 421, "pan.___", state 2404, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 2404, "else"
+       line 421, "pan.___", state 2407, "(1)"
+       line 421, "pan.___", state 2408, "(1)"
+       line 421, "pan.___", state 2408, "(1)"
+       line 425, "pan.___", state 2416, "(1)"
+       line 425, "pan.___", state 2417, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 2417, "else"
+       line 425, "pan.___", state 2420, "(1)"
+       line 425, "pan.___", state 2421, "(1)"
+       line 425, "pan.___", state 2421, "(1)"
+       line 423, "pan.___", state 2426, "((i<2))"
+       line 423, "pan.___", state 2426, "((i>=2))"
+       line 430, "pan.___", state 2430, "(1)"
+       line 430, "pan.___", state 2430, "(1)"
+       line 623, "pan.___", state 2433, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 623, "pan.___", state 2434, "_proc_urcu_reader = (_proc_urcu_reader|(1<<23))"
+       line 623, "pan.___", state 2435, "(1)"
+       line 250, "pan.___", state 2439, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 2450, "(1)"
+       line 258, "pan.___", state 2461, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 2470, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 2486, "(1)"
+       line 231, "pan.___", state 2494, "(1)"
+       line 235, "pan.___", state 2506, "(1)"
+       line 239, "pan.___", state 2514, "(1)"
+       line 395, "pan.___", state 2532, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 2546, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2564, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2578, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2597, "(1)"
+       line 416, "pan.___", state 2610, "(1)"
+       line 421, "pan.___", state 2627, "(1)"
+       line 425, "pan.___", state 2640, "(1)"
+       line 250, "pan.___", state 2664, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 2673, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 2686, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 2695, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 2711, "(1)"
+       line 231, "pan.___", state 2719, "(1)"
+       line 235, "pan.___", state 2731, "(1)"
+       line 239, "pan.___", state 2739, "(1)"
+       line 395, "pan.___", state 2757, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 2771, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2789, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2803, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2822, "(1)"
+       line 416, "pan.___", state 2835, "(1)"
+       line 421, "pan.___", state 2852, "(1)"
+       line 425, "pan.___", state 2865, "(1)"
+       line 395, "pan.___", state 2886, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 2900, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2918, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2932, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2951, "(1)"
+       line 416, "pan.___", state 2964, "(1)"
+       line 421, "pan.___", state 2981, "(1)"
+       line 425, "pan.___", state 2994, "(1)"
+       line 227, "pan.___", state 3027, "(1)"
+       line 235, "pan.___", state 3047, "(1)"
+       line 239, "pan.___", state 3055, "(1)"
+       line 227, "pan.___", state 3070, "(1)"
+       line 231, "pan.___", state 3078, "(1)"
+       line 235, "pan.___", state 3090, "(1)"
+       line 239, "pan.___", state 3098, "(1)"
+       line 877, "pan.___", state 3115, "-end-"
+       (318 of 3115 states)
+unreached in proctype urcu_writer
+       line 395, "pan.___", state 22, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 36, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 54, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 87, "(1)"
+       line 416, "pan.___", state 100, "(1)"
+       line 421, "pan.___", state 117, "(1)"
+       line 250, "pan.___", state 153, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 162, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 175, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 215, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 229, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 247, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 261, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 280, "(1)"
+       line 416, "pan.___", state 293, "(1)"
+       line 421, "pan.___", state 310, "(1)"
+       line 425, "pan.___", state 323, "(1)"
+       line 399, "pan.___", state 360, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 378, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 392, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 424, "(1)"
+       line 421, "pan.___", state 441, "(1)"
+       line 425, "pan.___", state 454, "(1)"
+       line 395, "pan.___", state 483, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 485, "(1)"
+       line 395, "pan.___", state 486, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 486, "else"
+       line 395, "pan.___", state 489, "(1)"
+       line 399, "pan.___", state 497, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 499, "(1)"
+       line 399, "pan.___", state 500, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 500, "else"
+       line 399, "pan.___", state 503, "(1)"
+       line 399, "pan.___", state 504, "(1)"
+       line 399, "pan.___", state 504, "(1)"
+       line 397, "pan.___", state 509, "((i<1))"
+       line 397, "pan.___", state 509, "((i>=1))"
+       line 404, "pan.___", state 515, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 517, "(1)"
+       line 404, "pan.___", state 518, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 518, "else"
+       line 404, "pan.___", state 521, "(1)"
+       line 404, "pan.___", state 522, "(1)"
+       line 404, "pan.___", state 522, "(1)"
+       line 408, "pan.___", state 529, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 531, "(1)"
+       line 408, "pan.___", state 532, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 532, "else"
+       line 408, "pan.___", state 535, "(1)"
+       line 408, "pan.___", state 536, "(1)"
+       line 408, "pan.___", state 536, "(1)"
+       line 406, "pan.___", state 541, "((i<2))"
+       line 406, "pan.___", state 541, "((i>=2))"
+       line 412, "pan.___", state 548, "(1)"
+       line 412, "pan.___", state 549, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 549, "else"
+       line 412, "pan.___", state 552, "(1)"
+       line 412, "pan.___", state 553, "(1)"
+       line 412, "pan.___", state 553, "(1)"
+       line 416, "pan.___", state 561, "(1)"
+       line 416, "pan.___", state 562, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 562, "else"
+       line 416, "pan.___", state 565, "(1)"
+       line 416, "pan.___", state 566, "(1)"
+       line 416, "pan.___", state 566, "(1)"
+       line 414, "pan.___", state 571, "((i<1))"
+       line 414, "pan.___", state 571, "((i>=1))"
+       line 421, "pan.___", state 578, "(1)"
+       line 421, "pan.___", state 579, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 579, "else"
+       line 421, "pan.___", state 582, "(1)"
+       line 421, "pan.___", state 583, "(1)"
+       line 421, "pan.___", state 583, "(1)"
+       line 425, "pan.___", state 591, "(1)"
+       line 425, "pan.___", state 592, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 592, "else"
+       line 425, "pan.___", state 595, "(1)"
+       line 425, "pan.___", state 596, "(1)"
+       line 425, "pan.___", state 596, "(1)"
+       line 430, "pan.___", state 605, "(1)"
+       line 430, "pan.___", state 605, "(1)"
+       line 395, "pan.___", state 612, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 614, "(1)"
+       line 395, "pan.___", state 615, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 615, "else"
+       line 395, "pan.___", state 618, "(1)"
+       line 399, "pan.___", state 626, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 628, "(1)"
+       line 399, "pan.___", state 629, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 629, "else"
+       line 399, "pan.___", state 632, "(1)"
+       line 399, "pan.___", state 633, "(1)"
+       line 399, "pan.___", state 633, "(1)"
+       line 397, "pan.___", state 638, "((i<1))"
+       line 397, "pan.___", state 638, "((i>=1))"
+       line 404, "pan.___", state 644, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 646, "(1)"
+       line 404, "pan.___", state 647, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 647, "else"
+       line 404, "pan.___", state 650, "(1)"
+       line 404, "pan.___", state 651, "(1)"
+       line 404, "pan.___", state 651, "(1)"
+       line 408, "pan.___", state 658, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 660, "(1)"
+       line 408, "pan.___", state 661, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 661, "else"
+       line 408, "pan.___", state 664, "(1)"
+       line 408, "pan.___", state 665, "(1)"
+       line 408, "pan.___", state 665, "(1)"
+       line 406, "pan.___", state 670, "((i<2))"
+       line 406, "pan.___", state 670, "((i>=2))"
+       line 412, "pan.___", state 677, "(1)"
+       line 412, "pan.___", state 678, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 678, "else"
+       line 412, "pan.___", state 681, "(1)"
+       line 412, "pan.___", state 682, "(1)"
+       line 412, "pan.___", state 682, "(1)"
+       line 416, "pan.___", state 690, "(1)"
+       line 416, "pan.___", state 691, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 691, "else"
+       line 416, "pan.___", state 694, "(1)"
+       line 416, "pan.___", state 695, "(1)"
+       line 416, "pan.___", state 695, "(1)"
+       line 414, "pan.___", state 700, "((i<1))"
+       line 414, "pan.___", state 700, "((i>=1))"
+       line 421, "pan.___", state 707, "(1)"
+       line 421, "pan.___", state 708, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 708, "else"
+       line 421, "pan.___", state 711, "(1)"
+       line 421, "pan.___", state 712, "(1)"
+       line 421, "pan.___", state 712, "(1)"
+       line 425, "pan.___", state 720, "(1)"
+       line 425, "pan.___", state 721, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 721, "else"
+       line 425, "pan.___", state 724, "(1)"
+       line 425, "pan.___", state 725, "(1)"
+       line 425, "pan.___", state 725, "(1)"
+       line 423, "pan.___", state 730, "((i<2))"
+       line 423, "pan.___", state 730, "((i>=2))"
+       line 430, "pan.___", state 734, "(1)"
+       line 430, "pan.___", state 734, "(1)"
+       line 1085, "pan.___", state 738, "_proc_urcu_writer = (_proc_urcu_writer|(1<<10))"
+       line 395, "pan.___", state 743, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 745, "(1)"
+       line 395, "pan.___", state 746, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 746, "else"
+       line 395, "pan.___", state 749, "(1)"
+       line 399, "pan.___", state 757, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 759, "(1)"
+       line 399, "pan.___", state 760, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 760, "else"
+       line 399, "pan.___", state 763, "(1)"
+       line 399, "pan.___", state 764, "(1)"
+       line 399, "pan.___", state 764, "(1)"
+       line 397, "pan.___", state 769, "((i<1))"
+       line 397, "pan.___", state 769, "((i>=1))"
+       line 404, "pan.___", state 775, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 777, "(1)"
+       line 404, "pan.___", state 778, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 778, "else"
+       line 404, "pan.___", state 781, "(1)"
+       line 404, "pan.___", state 782, "(1)"
+       line 404, "pan.___", state 782, "(1)"
+       line 408, "pan.___", state 789, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 791, "(1)"
+       line 408, "pan.___", state 792, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 792, "else"
+       line 408, "pan.___", state 795, "(1)"
+       line 408, "pan.___", state 796, "(1)"
+       line 408, "pan.___", state 796, "(1)"
+       line 406, "pan.___", state 801, "((i<2))"
+       line 406, "pan.___", state 801, "((i>=2))"
+       line 412, "pan.___", state 808, "(1)"
+       line 412, "pan.___", state 809, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 809, "else"
+       line 412, "pan.___", state 812, "(1)"
+       line 412, "pan.___", state 813, "(1)"
+       line 412, "pan.___", state 813, "(1)"
+       line 416, "pan.___", state 821, "(1)"
+       line 416, "pan.___", state 822, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 822, "else"
+       line 416, "pan.___", state 825, "(1)"
+       line 416, "pan.___", state 826, "(1)"
+       line 416, "pan.___", state 826, "(1)"
+       line 414, "pan.___", state 831, "((i<1))"
+       line 414, "pan.___", state 831, "((i>=1))"
+       line 421, "pan.___", state 838, "(1)"
+       line 421, "pan.___", state 839, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 839, "else"
+       line 421, "pan.___", state 842, "(1)"
+       line 421, "pan.___", state 843, "(1)"
+       line 421, "pan.___", state 843, "(1)"
+       line 425, "pan.___", state 851, "(1)"
+       line 425, "pan.___", state 852, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 852, "else"
+       line 425, "pan.___", state 855, "(1)"
+       line 425, "pan.___", state 856, "(1)"
+       line 425, "pan.___", state 856, "(1)"
+       line 423, "pan.___", state 861, "((i<2))"
+       line 423, "pan.___", state 861, "((i>=2))"
+       line 430, "pan.___", state 865, "(1)"
+       line 430, "pan.___", state 865, "(1)"
+       line 1100, "pan.___", state 870, "_proc_urcu_writer = (_proc_urcu_writer|(1<<11))"
+       line 1095, "pan.___", state 871, "(((tmp2&((1<<7)-1))&&((tmp2^0)&(1<<7))))"
+       line 1095, "pan.___", state 871, "else"
+       line 1120, "pan.___", state 875, "_proc_urcu_writer = (_proc_urcu_writer&~(((1<<12)|(1<<11))))"
+       line 250, "pan.___", state 906, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 915, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 930, "(1)"
+       line 262, "pan.___", state 937, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 953, "(1)"
+       line 231, "pan.___", state 961, "(1)"
+       line 235, "pan.___", state 973, "(1)"
+       line 239, "pan.___", state 981, "(1)"
+       line 254, "pan.___", state 1006, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1019, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1028, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1044, "(1)"
+       line 231, "pan.___", state 1052, "(1)"
+       line 235, "pan.___", state 1064, "(1)"
+       line 239, "pan.___", state 1072, "(1)"
+       line 250, "pan.___", state 1088, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 250, "pan.___", state 1090, "(1)"
+       line 254, "pan.___", state 1097, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1099, "(1)"
+       line 254, "pan.___", state 1100, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 254, "pan.___", state 1100, "else"
+       line 252, "pan.___", state 1105, "((i<1))"
+       line 252, "pan.___", state 1105, "((i>=1))"
+       line 258, "pan.___", state 1110, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1112, "(1)"
+       line 258, "pan.___", state 1113, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 258, "pan.___", state 1113, "else"
+       line 262, "pan.___", state 1119, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1121, "(1)"
+       line 262, "pan.___", state 1122, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 262, "pan.___", state 1122, "else"
+       line 260, "pan.___", state 1127, "((i<2))"
+       line 260, "pan.___", state 1127, "((i>=2))"
+       line 227, "pan.___", state 1135, "(1)"
+       line 231, "pan.___", state 1143, "(1)"
+       line 231, "pan.___", state 1144, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 231, "pan.___", state 1144, "else"
+       line 229, "pan.___", state 1149, "((i<1))"
+       line 229, "pan.___", state 1149, "((i>=1))"
+       line 235, "pan.___", state 1155, "(1)"
+       line 235, "pan.___", state 1156, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 235, "pan.___", state 1156, "else"
+       line 239, "pan.___", state 1163, "(1)"
+       line 239, "pan.___", state 1164, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 239, "pan.___", state 1164, "else"
+       line 244, "pan.___", state 1173, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 244, "pan.___", state 1173, "else"
+       line 277, "pan.___", state 1175, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 277, "pan.___", state 1175, "else"
+       line 254, "pan.___", state 1188, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1201, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1210, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1226, "(1)"
+       line 231, "pan.___", state 1234, "(1)"
+       line 235, "pan.___", state 1246, "(1)"
+       line 239, "pan.___", state 1254, "(1)"
+       line 1204, "pan.___", state 1269, "-end-"
+       (192 of 1269 states)
+unreached in proctype :init:
+       line 1215, "pan.___", state 9, "((j<2))"
+       line 1215, "pan.___", state 9, "((j>=2))"
+       line 1216, "pan.___", state 20, "((j<2))"
+       line 1216, "pan.___", state 20, "((j>=2))"
+       line 1221, "pan.___", state 33, "((j<2))"
+       line 1221, "pan.___", state 33, "((j>=2))"
+       line 1219, "pan.___", state 43, "((i<1))"
+       line 1219, "pan.___", state 43, "((i>=1))"
+       line 1229, "pan.___", state 54, "((j<2))"
+       line 1229, "pan.___", state 54, "((j>=2))"
+       line 1233, "pan.___", state 67, "((j<2))"
+       line 1233, "pan.___", state 67, "((j>=2))"
+       (6 of 78 states)
+unreached in proctype :never:
+       line 1263, "pan.___", state 8, "-end-"
+       (1 of 8 states)
+
+pan: elapsed time 266 seconds
+pan: rate 2283.3239 states/second
+pan: avg transition delay 1.2613e-06 usec
+cp .input.spin urcu_free_single_flip.spin.input
+cp .input.spin.trail urcu_free_single_flip.spin.input.trail
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_single_flip.spin.input b/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_single_flip.spin.input
new file mode 100644 (file)
index 0000000..b2e670e
--- /dev/null
@@ -0,0 +1,1240 @@
+#define SINGLE_FLIP
+
+// Poison value for freed memory
+#define POISON 1
+// Memory with correct data
+#define WINE 0
+#define SLAB_SIZE 2
+
+#define read_poison    (data_read_first[0] == POISON || data_read_second[0] == POISON)
+
+#define RCU_GP_CTR_BIT (1 << 7)
+#define RCU_GP_CTR_NEST_MASK (RCU_GP_CTR_BIT - 1)
+
+//disabled
+//#define REMOTE_BARRIERS
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+typedef per_proc_bit {
+       bit val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bitfield {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bitfield cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               /*
+                * 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, j);
+               reader_barrier[get_readerid()] = 0;
+       :: 1 ->
+               /*
+                * 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)
+//#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);                                                           \
+       i = 0;                                                                  \
+       do                                                                      \
+       :: i < NR_READERS ->                                                    \
+               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.                                            \
+                */                                                             \
+               do                                                              \
+               :: (reader_barrier[i] == 1) ->                                  \
+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(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, smp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only one reader */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* RCU data */
+DECLARE_CACHED_VAR(bit, rcu_data[SLAB_SIZE]);
+
+/* RCU pointer */
+#if (SLAB_SIZE == 2)
+DECLARE_CACHED_VAR(bit, rcu_ptr);
+bit ptr_read_first[NR_READERS];
+bit ptr_read_second[NR_READERS];
+#else
+DECLARE_CACHED_VAR(byte, rcu_ptr);
+byte ptr_read_first[NR_READERS];
+byte ptr_read_second[NR_READERS];
+#endif
+
+bit data_read_first[NR_READERS];
+bit data_read_second[NR_READERS];
+
+bit init_done = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               ptr_read_first[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb1;
+rmb1_end:
+                               data_read_first[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_first[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               ptr_read_second[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb2;
+rmb2_end:
+                               data_read_second[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_second[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+rmb1:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb1_end;
+rmb2:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_DATA                     (1 << 1)
+#define WRITE_PROC_WMB                 (1 << 2)
+#define WRITE_XCHG_PTR                 (1 << 3)
+
+#define WRITE_PROC_FIRST_MB            (1 << 4)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 5)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 6)
+#define WRITE_PROC_FIRST_WAIT          (1 << 7)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 8)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 9)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 10)
+#define WRITE_PROC_SECOND_WAIT         (1 << 11)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 12)
+
+#define WRITE_PROC_SECOND_MB           (1 << 13)
+
+#define WRITE_FREE                     (1 << 14)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_DATA                    \
+                                       | WRITE_PROC_WMB                \
+                                       | WRITE_XCHG_PTR                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB          \
+                                       | WRITE_FREE)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 15) - 1)
+
+/*
+ * Mutexes are implied around writer execution. A single writer at a time.
+ */
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte cur_data = 0, old_data, loop_nr = 0;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (loop_nr < 3) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               loop_nr = loop_nr + 1;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_WMB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+#endif
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_DATA) ->
+                       ooo_mem(i);
+                       cur_data = (cur_data + 1) % SLAB_SIZE;
+                       WRITE_CACHED_VAR(rcu_data[cur_data], WINE);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_DATA);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA,
+                                 WRITE_PROC_WMB) ->
+                       smp_wmb(i, j);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_WMB,
+                                 WRITE_XCHG_PTR) ->
+                       /* rcu_xchg_pointer() */
+                       atomic {
+                               old_data = READ_CACHED_VAR(rcu_ptr);
+                               WRITE_CACHED_VAR(rcu_ptr, cur_data);
+                       }
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_XCHG_PTR);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_WMB      /* No dependency on
+                                                        * WRITE_DATA because we
+                                                        * write to a
+                                                        * different location. */
+                                 | WRITE_PROC_SECOND_MB
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_FREE) ->
+                       WRITE_CACHED_VAR(rcu_data[old_data], POISON);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_FREE);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+               /*
+                * Note : Promela model adds implicit serialization of the
+                * WRITE_FREE instruction. Normally, it would be permitted to
+                * spill on the next loop execution. Given the validation we do
+                * checks for the data entry read to be poisoned, it's ok if
+                * we do not check "late arriving" memory poisoning.
+                */
+       :: 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
+#ifdef READER_PROGRESS
+               /*
+                * Make sure we don't block the reader's progress.
+                */
+               smp_mb_send(i, j, 5);
+#endif
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(rcu_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       ptr_read_first[i] = 1;
+                       ptr_read_second[i] = 1;
+                       data_read_first[i] = WINE;
+                       data_read_second[i] = WINE;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               INIT_CACHED_VAR(rcu_data[0], WINE, j);
+               i = 1;
+               do
+               :: i < SLAB_SIZE ->
+                       INIT_CACHED_VAR(rcu_data[i], POISON, j);
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_single_flip.spin.input.trail b/formal-model/results/urcu-controldataflow-no-ipi/urcu_free_single_flip.spin.input.trail
new file mode 100644 (file)
index 0000000..d8a0531
--- /dev/null
@@ -0,0 +1,1039 @@
+-2:3:-2
+-4:-4:-4
+1:0:4464
+2:3:4384
+3:3:4387
+4:3:4387
+5:3:4390
+6:3:4398
+7:3:4398
+8:3:4401
+9:3:4407
+10:3:4411
+11:3:4411
+12:3:4414
+13:3:4424
+14:3:4432
+15:3:4432
+16:3:4435
+17:3:4441
+18:3:4445
+19:3:4445
+20:3:4448
+21:3:4454
+22:3:4458
+23:3:4459
+24:0:4464
+25:3:4461
+26:0:4464
+27:2:3117
+28:0:4464
+29:2:3123
+30:0:4464
+31:2:3124
+32:0:4464
+33:2:3126
+34:0:4464
+35:2:3127
+36:0:4464
+37:2:3128
+38:0:4464
+39:2:3129
+40:0:4464
+41:2:3130
+42:0:4464
+43:2:3131
+44:0:4464
+45:2:3132
+46:2:3133
+47:2:3137
+48:2:3138
+49:2:3146
+50:2:3147
+51:2:3151
+52:2:3152
+53:2:3160
+54:2:3165
+55:2:3169
+56:2:3170
+57:2:3178
+58:2:3179
+59:2:3183
+60:2:3184
+61:2:3178
+62:2:3179
+63:2:3183
+64:2:3184
+65:2:3192
+66:2:3197
+67:2:3198
+68:2:3209
+69:2:3210
+70:2:3211
+71:2:3222
+72:2:3227
+73:2:3228
+74:2:3239
+75:2:3240
+76:2:3241
+77:2:3239
+78:2:3240
+79:2:3241
+80:2:3252
+81:2:3260
+82:0:4464
+83:2:3131
+84:0:4464
+85:2:3264
+86:2:3268
+87:2:3269
+88:2:3273
+89:2:3277
+90:2:3278
+91:2:3282
+92:2:3290
+93:2:3291
+94:2:3295
+95:2:3299
+96:2:3300
+97:2:3295
+98:2:3296
+99:2:3304
+100:0:4464
+101:2:3131
+102:0:4464
+103:2:3312
+104:2:3313
+105:2:3314
+106:0:4464
+107:2:3131
+108:0:4464
+109:2:3319
+110:0:4464
+111:2:4021
+112:2:4022
+113:2:4026
+114:2:4030
+115:2:4031
+116:2:4035
+117:2:4040
+118:2:4048
+119:2:4052
+120:2:4053
+121:2:4048
+122:2:4052
+123:2:4053
+124:2:4057
+125:2:4064
+126:2:4071
+127:2:4072
+128:2:4079
+129:2:4084
+130:2:4091
+131:2:4092
+132:2:4091
+133:2:4092
+134:2:4099
+135:2:4103
+136:0:4464
+137:2:3321
+138:2:4002
+139:0:4464
+140:2:3131
+141:0:4464
+142:2:3322
+143:0:4464
+144:2:3131
+145:0:4464
+146:2:3325
+147:2:3326
+148:2:3330
+149:2:3331
+150:2:3339
+151:2:3340
+152:2:3344
+153:2:3345
+154:2:3353
+155:2:3358
+156:2:3362
+157:2:3363
+158:2:3371
+159:2:3372
+160:2:3376
+161:2:3377
+162:2:3371
+163:2:3372
+164:2:3376
+165:2:3377
+166:2:3385
+167:2:3390
+168:2:3391
+169:2:3402
+170:2:3403
+171:2:3404
+172:2:3415
+173:2:3420
+174:2:3421
+175:2:3432
+176:2:3433
+177:2:3434
+178:2:3432
+179:2:3433
+180:2:3434
+181:2:3445
+182:2:3452
+183:0:4464
+184:2:3131
+185:0:4464
+186:2:3456
+187:2:3457
+188:2:3458
+189:2:3470
+190:2:3471
+191:2:3475
+192:2:3476
+193:2:3484
+194:2:3489
+195:2:3493
+196:2:3494
+197:2:3502
+198:2:3503
+199:2:3507
+200:2:3508
+201:2:3502
+202:2:3503
+203:2:3507
+204:2:3508
+205:2:3516
+206:2:3521
+207:2:3522
+208:2:3533
+209:2:3534
+210:2:3535
+211:2:3546
+212:2:3551
+213:2:3552
+214:2:3563
+215:2:3564
+216:2:3565
+217:2:3563
+218:2:3564
+219:2:3565
+220:2:3576
+221:2:3586
+222:2:3587
+223:0:4464
+224:2:3131
+225:0:4464
+226:2:3990
+227:0:4464
+228:2:4294
+229:2:4295
+230:2:4299
+231:2:4303
+232:2:4304
+233:2:4308
+234:2:4316
+235:2:4317
+236:2:4321
+237:2:4325
+238:2:4326
+239:2:4321
+240:2:4325
+241:2:4326
+242:2:4330
+243:2:4337
+244:2:4344
+245:2:4345
+246:2:4352
+247:2:4357
+248:2:4364
+249:2:4365
+250:2:4364
+251:2:4365
+252:2:4372
+253:2:4376
+254:0:4464
+255:2:3992
+256:2:4002
+257:0:4464
+258:2:3131
+259:0:4464
+260:2:3993
+261:2:3994
+262:0:4464
+263:2:3131
+264:0:4464
+265:2:3998
+266:0:4464
+267:2:4006
+268:0:4464
+269:2:3124
+270:0:4464
+271:2:3126
+272:0:4464
+273:2:3127
+274:0:4464
+275:2:3128
+276:0:4464
+277:2:3129
+278:0:4464
+279:2:3130
+280:0:4464
+281:2:3131
+282:0:4464
+283:2:3132
+284:2:3133
+285:2:3137
+286:2:3138
+287:2:3146
+288:2:3147
+289:2:3151
+290:2:3152
+291:2:3160
+292:2:3165
+293:2:3169
+294:2:3170
+295:2:3178
+296:2:3179
+297:2:3180
+298:2:3178
+299:2:3179
+300:2:3183
+301:2:3184
+302:2:3192
+303:2:3197
+304:2:3198
+305:2:3209
+306:2:3210
+307:2:3211
+308:2:3222
+309:2:3227
+310:2:3228
+311:2:3239
+312:2:3240
+313:2:3241
+314:2:3239
+315:2:3240
+316:2:3241
+317:2:3252
+318:2:3260
+319:0:4464
+320:2:3131
+321:0:4464
+322:2:3264
+323:2:3268
+324:2:3269
+325:2:3273
+326:2:3277
+327:2:3278
+328:2:3282
+329:2:3290
+330:2:3291
+331:2:3295
+332:2:3296
+333:2:3295
+334:2:3299
+335:2:3300
+336:2:3304
+337:0:4464
+338:2:3131
+339:0:4464
+340:2:3312
+341:2:3313
+342:2:3314
+343:0:4464
+344:2:3131
+345:0:4464
+346:2:3319
+347:0:4464
+348:1:2
+349:0:4464
+350:1:8
+351:0:4464
+352:1:9
+353:0:4464
+354:1:10
+355:0:4464
+356:1:11
+357:0:4464
+358:1:12
+359:1:13
+360:1:17
+361:1:18
+362:1:26
+363:1:27
+364:1:31
+365:1:32
+366:1:40
+367:1:45
+368:1:49
+369:1:50
+370:1:58
+371:1:59
+372:1:63
+373:1:64
+374:1:58
+375:1:59
+376:1:63
+377:1:64
+378:1:72
+379:1:84
+380:1:85
+381:1:89
+382:1:90
+383:1:91
+384:1:102
+385:1:107
+386:1:108
+387:1:119
+388:1:120
+389:1:121
+390:1:119
+391:1:120
+392:1:121
+393:1:132
+394:0:4464
+395:1:11
+396:0:4464
+397:1:141
+398:1:142
+399:0:4464
+400:1:11
+401:0:4464
+402:1:148
+403:1:149
+404:1:153
+405:1:154
+406:1:162
+407:1:163
+408:1:167
+409:1:168
+410:1:176
+411:1:181
+412:1:185
+413:1:186
+414:1:194
+415:1:195
+416:1:199
+417:1:200
+418:1:194
+419:1:195
+420:1:199
+421:1:200
+422:1:208
+423:1:220
+424:1:221
+425:1:225
+426:1:226
+427:1:227
+428:1:238
+429:1:243
+430:1:244
+431:1:255
+432:1:256
+433:1:257
+434:1:255
+435:1:256
+436:1:257
+437:1:268
+438:0:4464
+439:1:11
+440:0:4464
+441:1:277
+442:1:278
+443:1:282
+444:1:283
+445:1:291
+446:1:292
+447:1:296
+448:1:297
+449:1:305
+450:1:310
+451:1:314
+452:1:315
+453:1:323
+454:1:324
+455:1:328
+456:1:329
+457:1:323
+458:1:324
+459:1:328
+460:1:329
+461:1:337
+462:1:342
+463:1:343
+464:1:354
+465:1:355
+466:1:356
+467:1:367
+468:1:372
+469:1:373
+470:1:384
+471:1:385
+472:1:386
+473:1:384
+474:1:385
+475:1:386
+476:1:397
+477:1:404
+478:0:4464
+479:1:11
+480:0:4464
+481:1:540
+482:1:544
+483:1:545
+484:1:549
+485:1:550
+486:1:558
+487:1:566
+488:1:567
+489:1:571
+490:1:575
+491:1:576
+492:1:571
+493:1:575
+494:1:576
+495:1:580
+496:1:587
+497:1:594
+498:1:595
+499:1:602
+500:1:607
+501:1:614
+502:1:615
+503:1:614
+504:1:615
+505:1:622
+506:0:4464
+507:1:11
+508:0:4464
+509:2:4021
+510:2:4022
+511:2:4026
+512:2:4030
+513:2:4031
+514:2:4035
+515:2:4040
+516:2:4048
+517:2:4052
+518:2:4053
+519:2:4048
+520:2:4052
+521:2:4053
+522:2:4057
+523:2:4064
+524:2:4071
+525:2:4072
+526:2:4079
+527:2:4084
+528:2:4091
+529:2:4092
+530:2:4091
+531:2:4092
+532:2:4099
+533:2:4103
+534:0:4464
+535:2:3321
+536:2:4002
+537:0:4464
+538:2:3131
+539:0:4464
+540:2:3322
+541:0:4464
+542:2:3131
+543:0:4464
+544:2:3325
+545:2:3326
+546:2:3330
+547:2:3331
+548:2:3339
+549:2:3340
+550:2:3344
+551:2:3345
+552:2:3353
+553:2:3358
+554:2:3362
+555:2:3363
+556:2:3371
+557:2:3372
+558:2:3376
+559:2:3377
+560:2:3371
+561:2:3372
+562:2:3376
+563:2:3377
+564:2:3385
+565:2:3390
+566:2:3391
+567:2:3402
+568:2:3403
+569:2:3404
+570:2:3415
+571:2:3420
+572:2:3421
+573:2:3432
+574:2:3433
+575:2:3434
+576:2:3432
+577:2:3433
+578:2:3434
+579:2:3445
+580:2:3452
+581:0:4464
+582:2:3131
+583:0:4464
+584:2:3456
+585:2:3457
+586:2:3458
+587:2:3470
+588:2:3471
+589:2:3475
+590:2:3476
+591:2:3484
+592:2:3489
+593:2:3493
+594:2:3494
+595:2:3502
+596:2:3503
+597:2:3507
+598:2:3508
+599:2:3502
+600:2:3503
+601:2:3507
+602:2:3508
+603:2:3516
+604:2:3521
+605:2:3522
+606:2:3533
+607:2:3534
+608:2:3535
+609:2:3546
+610:2:3551
+611:2:3552
+612:2:3563
+613:2:3564
+614:2:3565
+615:2:3563
+616:2:3564
+617:2:3565
+618:2:3576
+619:2:3586
+620:2:3587
+621:0:4464
+622:2:3131
+623:0:4464
+624:2:3990
+625:0:4464
+626:2:4294
+627:2:4295
+628:2:4299
+629:2:4303
+630:2:4304
+631:2:4308
+632:2:4316
+633:2:4317
+634:2:4321
+635:2:4325
+636:2:4326
+637:2:4321
+638:2:4325
+639:2:4326
+640:2:4330
+641:2:4337
+642:2:4344
+643:2:4345
+644:2:4352
+645:2:4357
+646:2:4364
+647:2:4365
+648:2:4364
+649:2:4365
+650:2:4372
+651:2:4376
+652:0:4464
+653:2:3992
+654:2:4002
+655:0:4464
+656:2:3131
+657:0:4464
+658:2:3993
+659:2:3994
+660:0:4464
+661:2:3131
+662:0:4464
+663:2:3998
+664:0:4464
+665:2:4006
+666:0:4464
+667:2:3124
+668:0:4464
+669:2:3126
+670:0:4464
+671:2:3127
+672:0:4464
+673:2:3128
+674:0:4464
+675:2:3129
+676:0:4464
+677:2:3130
+678:0:4464
+679:2:3131
+680:0:4464
+681:2:3132
+682:2:3133
+683:2:3137
+684:2:3138
+685:2:3146
+686:2:3147
+687:2:3151
+688:2:3152
+689:2:3160
+690:2:3165
+691:2:3169
+692:2:3170
+693:2:3178
+694:2:3179
+695:2:3183
+696:2:3184
+697:2:3178
+698:2:3179
+699:2:3180
+700:2:3192
+701:2:3197
+702:2:3198
+703:2:3209
+704:2:3210
+705:2:3211
+706:2:3222
+707:2:3227
+708:2:3228
+709:2:3239
+710:2:3240
+711:2:3241
+712:2:3239
+713:2:3240
+714:2:3241
+715:2:3252
+716:2:3260
+717:0:4464
+718:2:3131
+719:0:4464
+720:1:632
+721:1:633
+722:1:637
+723:1:638
+724:1:646
+725:1:647
+726:1:651
+727:1:652
+728:1:660
+729:1:665
+730:1:669
+731:1:670
+732:1:678
+733:1:679
+734:1:683
+735:1:684
+736:1:678
+737:1:679
+738:1:683
+739:1:684
+740:1:692
+741:1:697
+742:1:698
+743:1:709
+744:1:710
+745:1:711
+746:1:722
+747:1:734
+748:1:735
+749:1:739
+750:1:740
+751:1:741
+752:1:739
+753:1:740
+754:1:741
+755:1:752
+756:0:4464
+757:1:11
+758:0:4464
+759:1:761
+760:1:764
+761:1:765
+762:0:4464
+763:1:11
+764:0:4464
+765:1:1028
+766:1:1029
+767:1:1033
+768:1:1034
+769:1:1042
+770:1:1043
+771:1:1047
+772:1:1048
+773:1:1056
+774:1:1061
+775:1:1065
+776:1:1066
+777:1:1074
+778:1:1075
+779:1:1079
+780:1:1080
+781:1:1074
+782:1:1075
+783:1:1079
+784:1:1080
+785:1:1088
+786:1:1093
+787:1:1094
+788:1:1105
+789:1:1106
+790:1:1107
+791:1:1118
+792:1:1130
+793:1:1131
+794:1:1135
+795:1:1136
+796:1:1137
+797:1:1135
+798:1:1136
+799:1:1137
+800:1:1148
+801:1:1155
+802:1:1159
+803:0:4464
+804:1:11
+805:0:4464
+806:1:1160
+807:1:1161
+808:1:1165
+809:1:1166
+810:1:1174
+811:1:1175
+812:1:1176
+813:1:1188
+814:1:1193
+815:1:1197
+816:1:1198
+817:1:1206
+818:1:1207
+819:1:1211
+820:1:1212
+821:1:1206
+822:1:1207
+823:1:1211
+824:1:1212
+825:1:1220
+826:1:1225
+827:1:1226
+828:1:1237
+829:1:1238
+830:1:1239
+831:1:1250
+832:1:1262
+833:1:1263
+834:1:1267
+835:1:1268
+836:1:1269
+837:1:1267
+838:1:1268
+839:1:1269
+840:1:1280
+841:0:4464
+842:1:11
+843:0:4464
+844:1:1289
+845:0:4464
+846:1:3023
+847:1:3030
+848:1:3031
+849:1:3038
+850:1:3043
+851:1:3050
+852:1:3051
+853:1:3050
+854:1:3051
+855:1:3058
+856:1:3062
+857:0:4464
+858:2:3264
+859:2:3268
+860:2:3269
+861:2:3273
+862:2:3277
+863:2:3278
+864:2:3282
+865:2:3290
+866:2:3291
+867:2:3295
+868:2:3299
+869:2:3300
+870:2:3295
+871:2:3296
+872:2:3304
+873:0:4464
+874:2:3131
+875:0:4464
+876:2:3312
+877:2:3313
+878:2:3314
+879:0:4464
+880:2:3131
+881:0:4464
+882:2:3319
+883:0:4464
+884:2:4021
+885:2:4022
+886:2:4026
+887:2:4030
+888:2:4031
+889:2:4035
+890:2:4040
+891:2:4048
+892:2:4052
+893:2:4053
+894:2:4048
+895:2:4052
+896:2:4053
+897:2:4057
+898:2:4064
+899:2:4071
+900:2:4072
+901:2:4079
+902:2:4084
+903:2:4091
+904:2:4092
+905:2:4091
+906:2:4092
+907:2:4099
+908:2:4103
+909:0:4464
+910:2:3321
+911:2:4002
+912:0:4464
+913:2:3131
+914:0:4464
+915:2:3322
+916:0:4464
+917:2:3131
+918:0:4464
+919:2:3325
+920:2:3326
+921:2:3330
+922:2:3331
+923:2:3339
+924:2:3340
+925:2:3344
+926:2:3345
+927:2:3353
+928:2:3358
+929:2:3362
+930:2:3363
+931:2:3371
+932:2:3372
+933:2:3376
+934:2:3377
+935:2:3371
+936:2:3372
+937:2:3376
+938:2:3377
+939:2:3385
+940:2:3390
+941:2:3391
+942:2:3402
+943:2:3403
+944:2:3404
+945:2:3415
+946:2:3420
+947:2:3421
+948:2:3432
+949:2:3433
+950:2:3434
+951:2:3432
+952:2:3433
+953:2:3434
+954:2:3445
+955:2:3452
+956:0:4464
+957:2:3131
+958:0:4464
+959:2:3456
+960:2:3457
+961:2:3458
+962:2:3470
+963:2:3471
+964:2:3475
+965:2:3476
+966:2:3484
+967:2:3489
+968:2:3493
+969:2:3494
+970:2:3502
+971:2:3503
+972:2:3507
+973:2:3508
+974:2:3502
+975:2:3503
+976:2:3507
+977:2:3508
+978:2:3516
+979:2:3521
+980:2:3522
+981:2:3533
+982:2:3534
+983:2:3535
+984:2:3546
+985:2:3551
+986:2:3552
+987:2:3563
+988:2:3564
+989:2:3565
+990:2:3563
+991:2:3564
+992:2:3565
+993:2:3576
+994:2:3584
+995:0:4464
+996:2:3131
+997:0:4464
+998:2:3590
+999:0:4464
+1000:2:4112
+1001:2:4113
+1002:2:4117
+1003:2:4121
+1004:2:4122
+1005:2:4126
+1006:2:4134
+1007:2:4135
+1008:2:4139
+1009:2:4143
+1010:2:4144
+1011:2:4139
+1012:2:4143
+1013:2:4144
+1014:2:4148
+1015:2:4155
+1016:2:4162
+1017:2:4163
+1018:2:4170
+1019:2:4175
+1020:2:4182
+1021:2:4183
+1022:2:4182
+1023:2:4183
+1024:2:4190
+1025:2:4194
+1026:0:4464
+1027:2:3592
+1028:2:4002
+1029:0:4464
+1030:2:3131
+1031:0:4464
+1032:1:1291
+1033:1:1292
+1034:0:4462
+1035:1:11
+1036:0:4468
+1037:2:3480
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu_progress.ltl b/formal-model/results/urcu-controldataflow-no-ipi/urcu_progress.ltl
new file mode 100644 (file)
index 0000000..8718641
--- /dev/null
@@ -0,0 +1 @@
+([] <> !np_)
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu_progress_reader.define b/formal-model/results/urcu-controldataflow-no-ipi/urcu_progress_reader.define
new file mode 100644 (file)
index 0000000..ff3f783
--- /dev/null
@@ -0,0 +1 @@
+#define READER_PROGRESS
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu_progress_reader.log b/formal-model/results/urcu-controldataflow-no-ipi/urcu_progress_reader.log
new file mode 100644 (file)
index 0000000..b4f4e20
--- /dev/null
@@ -0,0 +1,543 @@
+rm -f pan* trail.out .input.spin* *.spin.trail .input.define
+touch .input.define
+cat .input.define > pan.ltl
+cat DEFINES >> pan.ltl
+spin -f "!(`cat urcu_progress.ltl | grep -v ^//`)" >> pan.ltl
+cp urcu_progress_reader.define .input.define
+cat .input.define > .input.spin
+cat DEFINES >> .input.spin
+cat urcu.spin >> .input.spin
+rm -f .input.spin.trail
+spin -a -X -N pan.ltl .input.spin
+Exit-Status 0
+gcc -O2 -w -DHASH64 -o pan pan.c
+./pan -a -f -v -c1 -X -m10000000 -w20
+warning: for p.o. reduction to be valid the never claim must be stutter-invariant
+(never claims generated from LTL formulae are stutter-invariant)
+depth 0: Claim reached state 5 (line 1258)
+depth 23: Claim reached state 9 (line 1263)
+depth 1143: Claim reached state 9 (line 1262)
+Depth=    5344 States=    1e+06 Transitions= 4.94e+08 Memory=   506.389        t=    677 R=   1e+03
+Depth=    5344 States=    2e+06 Transitions= 1.22e+09 Memory=   545.647        t= 1.68e+03 R=   1e+03
+Depth=    5344 States=    3e+06 Transitions= 1.85e+09 Memory=   585.490        t= 2.58e+03 R=   1e+03
+pan: resizing hashtable to -w22..  done
+Depth=    5344 States=    4e+06 Transitions= 2.51e+09 Memory=   656.358        t= 3.5e+03 R=   1e+03
+Depth=    5344 States=    5e+06 Transitions= 3.19e+09 Memory=   693.662        t= 4.45e+03 R=   1e+03
+Depth=    5344 States=    6e+06 Transitions= 3.87e+09 Memory=   736.240        t= 5.41e+03 R=   1e+03
+Depth=    5344 States=    7e+06 Transitions= 4.51e+09 Memory=   776.084        t= 6.3e+03 R=   1e+03
+Depth=    5344 States=    8e+06 Transitions= 5.21e+09 Memory=   816.416        t= 7.28e+03 R=   1e+03
+
+(Spin Version 5.1.7 -- 23 December 2008)
+       + Partial Order Reduction
+
+Full statespace search for:
+       never claim             +
+       assertion violations    + (if within scope of claim)
+       acceptance   cycles     + (fairness enabled)
+       invalid end states      - (disabled by never claim)
+
+State-vector 88 byte, depth reached 5344, errors: 0
+  3811179 states, stored (8.02512e+06 visited)
+5.2123433e+09 states, matched
+5.2203684e+09 transitions (= visited+matched)
+3.1088208e+10 atomic steps
+hash conflicts: 1.9918982e+09 (resolved)
+
+Stats on memory usage (in Megabytes):
+  421.616      equivalent memory usage for states (stored*(State-vector + overhead))
+  328.016      actual memory usage for states (compression: 77.80%)
+               state-vector as stored = 62 byte + 28 byte overhead
+   32.000      memory used for hash table (-w22)
+  457.764      memory used for DFS stack (-m10000000)
+  817.490      total actual memory usage
+
+unreached in proctype urcu_reader
+       line 395, "pan.___", state 17, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 49, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 63, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 82, "(1)"
+       line 421, "pan.___", state 112, "(1)"
+       line 425, "pan.___", state 125, "(1)"
+       line 576, "pan.___", state 146, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<1))"
+       line 395, "pan.___", state 153, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 185, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 199, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 218, "(1)"
+       line 421, "pan.___", state 248, "(1)"
+       line 425, "pan.___", state 261, "(1)"
+       line 395, "pan.___", state 282, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 314, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 328, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 347, "(1)"
+       line 421, "pan.___", state 377, "(1)"
+       line 425, "pan.___", state 390, "(1)"
+       line 395, "pan.___", state 413, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 415, "(1)"
+       line 395, "pan.___", state 416, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 416, "else"
+       line 395, "pan.___", state 419, "(1)"
+       line 399, "pan.___", state 427, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 429, "(1)"
+       line 399, "pan.___", state 430, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 430, "else"
+       line 399, "pan.___", state 433, "(1)"
+       line 399, "pan.___", state 434, "(1)"
+       line 399, "pan.___", state 434, "(1)"
+       line 397, "pan.___", state 439, "((i<1))"
+       line 397, "pan.___", state 439, "((i>=1))"
+       line 404, "pan.___", state 445, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 447, "(1)"
+       line 404, "pan.___", state 448, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 448, "else"
+       line 404, "pan.___", state 451, "(1)"
+       line 404, "pan.___", state 452, "(1)"
+       line 404, "pan.___", state 452, "(1)"
+       line 408, "pan.___", state 459, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 461, "(1)"
+       line 408, "pan.___", state 462, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 462, "else"
+       line 408, "pan.___", state 465, "(1)"
+       line 408, "pan.___", state 466, "(1)"
+       line 408, "pan.___", state 466, "(1)"
+       line 406, "pan.___", state 471, "((i<2))"
+       line 406, "pan.___", state 471, "((i>=2))"
+       line 412, "pan.___", state 478, "(1)"
+       line 412, "pan.___", state 479, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 479, "else"
+       line 412, "pan.___", state 482, "(1)"
+       line 412, "pan.___", state 483, "(1)"
+       line 412, "pan.___", state 483, "(1)"
+       line 416, "pan.___", state 491, "(1)"
+       line 416, "pan.___", state 492, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 492, "else"
+       line 416, "pan.___", state 495, "(1)"
+       line 416, "pan.___", state 496, "(1)"
+       line 416, "pan.___", state 496, "(1)"
+       line 414, "pan.___", state 501, "((i<1))"
+       line 414, "pan.___", state 501, "((i>=1))"
+       line 421, "pan.___", state 508, "(1)"
+       line 421, "pan.___", state 509, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 509, "else"
+       line 421, "pan.___", state 512, "(1)"
+       line 421, "pan.___", state 513, "(1)"
+       line 421, "pan.___", state 513, "(1)"
+       line 425, "pan.___", state 521, "(1)"
+       line 425, "pan.___", state 522, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 522, "else"
+       line 425, "pan.___", state 525, "(1)"
+       line 425, "pan.___", state 526, "(1)"
+       line 425, "pan.___", state 526, "(1)"
+       line 423, "pan.___", state 531, "((i<2))"
+       line 423, "pan.___", state 531, "((i>=2))"
+       line 430, "pan.___", state 535, "(1)"
+       line 430, "pan.___", state 535, "(1)"
+       line 576, "pan.___", state 538, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 576, "pan.___", state 539, "_proc_urcu_reader = (_proc_urcu_reader|(1<<5))"
+       line 576, "pan.___", state 540, "(1)"
+       line 250, "pan.___", state 544, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 555, "(1)"
+       line 258, "pan.___", state 566, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 575, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 591, "(1)"
+       line 231, "pan.___", state 599, "(1)"
+       line 235, "pan.___", state 611, "(1)"
+       line 239, "pan.___", state 619, "(1)"
+       line 395, "pan.___", state 637, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 651, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 669, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 683, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 702, "(1)"
+       line 416, "pan.___", state 715, "(1)"
+       line 421, "pan.___", state 732, "(1)"
+       line 425, "pan.___", state 745, "(1)"
+       line 395, "pan.___", state 773, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 775, "(1)"
+       line 395, "pan.___", state 776, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 776, "else"
+       line 395, "pan.___", state 779, "(1)"
+       line 399, "pan.___", state 787, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 789, "(1)"
+       line 399, "pan.___", state 790, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 790, "else"
+       line 399, "pan.___", state 793, "(1)"
+       line 399, "pan.___", state 794, "(1)"
+       line 399, "pan.___", state 794, "(1)"
+       line 397, "pan.___", state 799, "((i<1))"
+       line 397, "pan.___", state 799, "((i>=1))"
+       line 404, "pan.___", state 805, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 807, "(1)"
+       line 404, "pan.___", state 808, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 808, "else"
+       line 404, "pan.___", state 811, "(1)"
+       line 404, "pan.___", state 812, "(1)"
+       line 404, "pan.___", state 812, "(1)"
+       line 408, "pan.___", state 819, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 821, "(1)"
+       line 408, "pan.___", state 822, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 822, "else"
+       line 408, "pan.___", state 825, "(1)"
+       line 408, "pan.___", state 826, "(1)"
+       line 408, "pan.___", state 826, "(1)"
+       line 406, "pan.___", state 831, "((i<2))"
+       line 406, "pan.___", state 831, "((i>=2))"
+       line 412, "pan.___", state 838, "(1)"
+       line 412, "pan.___", state 839, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 839, "else"
+       line 412, "pan.___", state 842, "(1)"
+       line 412, "pan.___", state 843, "(1)"
+       line 412, "pan.___", state 843, "(1)"
+       line 416, "pan.___", state 851, "(1)"
+       line 416, "pan.___", state 852, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 852, "else"
+       line 416, "pan.___", state 855, "(1)"
+       line 416, "pan.___", state 856, "(1)"
+       line 416, "pan.___", state 856, "(1)"
+       line 414, "pan.___", state 861, "((i<1))"
+       line 414, "pan.___", state 861, "((i>=1))"
+       line 421, "pan.___", state 868, "(1)"
+       line 421, "pan.___", state 869, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 869, "else"
+       line 421, "pan.___", state 872, "(1)"
+       line 421, "pan.___", state 873, "(1)"
+       line 421, "pan.___", state 873, "(1)"
+       line 425, "pan.___", state 881, "(1)"
+       line 425, "pan.___", state 882, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 882, "else"
+       line 425, "pan.___", state 885, "(1)"
+       line 425, "pan.___", state 886, "(1)"
+       line 425, "pan.___", state 886, "(1)"
+       line 430, "pan.___", state 895, "(1)"
+       line 430, "pan.___", state 895, "(1)"
+       line 395, "pan.___", state 902, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 904, "(1)"
+       line 395, "pan.___", state 905, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 905, "else"
+       line 395, "pan.___", state 908, "(1)"
+       line 399, "pan.___", state 916, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 918, "(1)"
+       line 399, "pan.___", state 919, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 919, "else"
+       line 399, "pan.___", state 922, "(1)"
+       line 399, "pan.___", state 923, "(1)"
+       line 399, "pan.___", state 923, "(1)"
+       line 397, "pan.___", state 928, "((i<1))"
+       line 397, "pan.___", state 928, "((i>=1))"
+       line 404, "pan.___", state 934, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 936, "(1)"
+       line 404, "pan.___", state 937, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 937, "else"
+       line 404, "pan.___", state 940, "(1)"
+       line 404, "pan.___", state 941, "(1)"
+       line 404, "pan.___", state 941, "(1)"
+       line 408, "pan.___", state 948, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 950, "(1)"
+       line 408, "pan.___", state 951, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 951, "else"
+       line 408, "pan.___", state 954, "(1)"
+       line 408, "pan.___", state 955, "(1)"
+       line 408, "pan.___", state 955, "(1)"
+       line 406, "pan.___", state 960, "((i<2))"
+       line 406, "pan.___", state 960, "((i>=2))"
+       line 412, "pan.___", state 967, "(1)"
+       line 412, "pan.___", state 968, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 968, "else"
+       line 412, "pan.___", state 971, "(1)"
+       line 412, "pan.___", state 972, "(1)"
+       line 412, "pan.___", state 972, "(1)"
+       line 416, "pan.___", state 980, "(1)"
+       line 416, "pan.___", state 981, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 981, "else"
+       line 416, "pan.___", state 984, "(1)"
+       line 416, "pan.___", state 985, "(1)"
+       line 416, "pan.___", state 985, "(1)"
+       line 414, "pan.___", state 990, "((i<1))"
+       line 414, "pan.___", state 990, "((i>=1))"
+       line 421, "pan.___", state 997, "(1)"
+       line 421, "pan.___", state 998, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 998, "else"
+       line 421, "pan.___", state 1001, "(1)"
+       line 421, "pan.___", state 1002, "(1)"
+       line 421, "pan.___", state 1002, "(1)"
+       line 425, "pan.___", state 1010, "(1)"
+       line 425, "pan.___", state 1011, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 1011, "else"
+       line 425, "pan.___", state 1014, "(1)"
+       line 425, "pan.___", state 1015, "(1)"
+       line 425, "pan.___", state 1015, "(1)"
+       line 423, "pan.___", state 1020, "((i<2))"
+       line 423, "pan.___", state 1020, "((i>=2))"
+       line 430, "pan.___", state 1024, "(1)"
+       line 430, "pan.___", state 1024, "(1)"
+       line 584, "pan.___", state 1028, "_proc_urcu_reader = (_proc_urcu_reader|(1<<11))"
+       line 395, "pan.___", state 1033, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 1047, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1065, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1079, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1098, "(1)"
+       line 416, "pan.___", state 1111, "(1)"
+       line 421, "pan.___", state 1128, "(1)"
+       line 425, "pan.___", state 1141, "(1)"
+       line 395, "pan.___", state 1165, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1197, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1211, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1230, "(1)"
+       line 421, "pan.___", state 1260, "(1)"
+       line 425, "pan.___", state 1273, "(1)"
+       line 395, "pan.___", state 1298, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1330, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1344, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1363, "(1)"
+       line 421, "pan.___", state 1393, "(1)"
+       line 425, "pan.___", state 1406, "(1)"
+       line 395, "pan.___", state 1427, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1459, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1473, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1492, "(1)"
+       line 421, "pan.___", state 1522, "(1)"
+       line 425, "pan.___", state 1535, "(1)"
+       line 250, "pan.___", state 1558, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1580, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1589, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1605, "(1)"
+       line 231, "pan.___", state 1613, "(1)"
+       line 235, "pan.___", state 1625, "(1)"
+       line 239, "pan.___", state 1633, "(1)"
+       line 395, "pan.___", state 1651, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 1665, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1683, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1697, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1716, "(1)"
+       line 416, "pan.___", state 1729, "(1)"
+       line 421, "pan.___", state 1746, "(1)"
+       line 425, "pan.___", state 1759, "(1)"
+       line 395, "pan.___", state 1780, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 1794, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1812, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1826, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1845, "(1)"
+       line 416, "pan.___", state 1858, "(1)"
+       line 421, "pan.___", state 1875, "(1)"
+       line 425, "pan.___", state 1888, "(1)"
+       line 395, "pan.___", state 1912, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 1928, "(1)"
+       line 404, "pan.___", state 1944, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1958, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1977, "(1)"
+       line 421, "pan.___", state 2007, "(1)"
+       line 425, "pan.___", state 2020, "(1)"
+       line 623, "pan.___", state 2041, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<19))"
+       line 395, "pan.___", state 2048, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2080, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2094, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2113, "(1)"
+       line 421, "pan.___", state 2143, "(1)"
+       line 425, "pan.___", state 2156, "(1)"
+       line 395, "pan.___", state 2177, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2209, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2223, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2242, "(1)"
+       line 421, "pan.___", state 2272, "(1)"
+       line 425, "pan.___", state 2285, "(1)"
+       line 395, "pan.___", state 2308, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 2310, "(1)"
+       line 395, "pan.___", state 2311, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 2311, "else"
+       line 395, "pan.___", state 2314, "(1)"
+       line 399, "pan.___", state 2322, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 2324, "(1)"
+       line 399, "pan.___", state 2325, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 2325, "else"
+       line 399, "pan.___", state 2328, "(1)"
+       line 399, "pan.___", state 2329, "(1)"
+       line 399, "pan.___", state 2329, "(1)"
+       line 397, "pan.___", state 2334, "((i<1))"
+       line 397, "pan.___", state 2334, "((i>=1))"
+       line 404, "pan.___", state 2340, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2342, "(1)"
+       line 404, "pan.___", state 2343, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 2343, "else"
+       line 404, "pan.___", state 2346, "(1)"
+       line 404, "pan.___", state 2347, "(1)"
+       line 404, "pan.___", state 2347, "(1)"
+       line 408, "pan.___", state 2354, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2356, "(1)"
+       line 408, "pan.___", state 2357, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 2357, "else"
+       line 408, "pan.___", state 2360, "(1)"
+       line 408, "pan.___", state 2361, "(1)"
+       line 408, "pan.___", state 2361, "(1)"
+       line 406, "pan.___", state 2366, "((i<2))"
+       line 406, "pan.___", state 2366, "((i>=2))"
+       line 412, "pan.___", state 2373, "(1)"
+       line 412, "pan.___", state 2374, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 2374, "else"
+       line 412, "pan.___", state 2377, "(1)"
+       line 412, "pan.___", state 2378, "(1)"
+       line 412, "pan.___", state 2378, "(1)"
+       line 416, "pan.___", state 2386, "(1)"
+       line 416, "pan.___", state 2387, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 2387, "else"
+       line 416, "pan.___", state 2390, "(1)"
+       line 416, "pan.___", state 2391, "(1)"
+       line 416, "pan.___", state 2391, "(1)"
+       line 414, "pan.___", state 2396, "((i<1))"
+       line 414, "pan.___", state 2396, "((i>=1))"
+       line 421, "pan.___", state 2403, "(1)"
+       line 421, "pan.___", state 2404, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 2404, "else"
+       line 421, "pan.___", state 2407, "(1)"
+       line 421, "pan.___", state 2408, "(1)"
+       line 421, "pan.___", state 2408, "(1)"
+       line 425, "pan.___", state 2416, "(1)"
+       line 425, "pan.___", state 2417, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 2417, "else"
+       line 425, "pan.___", state 2420, "(1)"
+       line 425, "pan.___", state 2421, "(1)"
+       line 425, "pan.___", state 2421, "(1)"
+       line 423, "pan.___", state 2426, "((i<2))"
+       line 423, "pan.___", state 2426, "((i>=2))"
+       line 430, "pan.___", state 2430, "(1)"
+       line 430, "pan.___", state 2430, "(1)"
+       line 623, "pan.___", state 2433, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 623, "pan.___", state 2434, "_proc_urcu_reader = (_proc_urcu_reader|(1<<23))"
+       line 623, "pan.___", state 2435, "(1)"
+       line 250, "pan.___", state 2439, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 2450, "(1)"
+       line 258, "pan.___", state 2461, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 2470, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 2486, "(1)"
+       line 231, "pan.___", state 2494, "(1)"
+       line 235, "pan.___", state 2506, "(1)"
+       line 239, "pan.___", state 2514, "(1)"
+       line 395, "pan.___", state 2532, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 2546, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2564, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2578, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2597, "(1)"
+       line 416, "pan.___", state 2610, "(1)"
+       line 421, "pan.___", state 2627, "(1)"
+       line 425, "pan.___", state 2640, "(1)"
+       line 250, "pan.___", state 2664, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 2673, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 2686, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 2695, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 2711, "(1)"
+       line 231, "pan.___", state 2719, "(1)"
+       line 235, "pan.___", state 2731, "(1)"
+       line 239, "pan.___", state 2739, "(1)"
+       line 395, "pan.___", state 2757, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 2771, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2789, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2803, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2822, "(1)"
+       line 416, "pan.___", state 2835, "(1)"
+       line 421, "pan.___", state 2852, "(1)"
+       line 425, "pan.___", state 2865, "(1)"
+       line 395, "pan.___", state 2886, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 2900, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2918, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2932, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2951, "(1)"
+       line 416, "pan.___", state 2964, "(1)"
+       line 421, "pan.___", state 2981, "(1)"
+       line 425, "pan.___", state 2994, "(1)"
+       line 227, "pan.___", state 3027, "(1)"
+       line 235, "pan.___", state 3047, "(1)"
+       line 239, "pan.___", state 3055, "(1)"
+       line 227, "pan.___", state 3070, "(1)"
+       line 231, "pan.___", state 3078, "(1)"
+       line 235, "pan.___", state 3090, "(1)"
+       line 239, "pan.___", state 3098, "(1)"
+       line 877, "pan.___", state 3115, "-end-"
+       (318 of 3115 states)
+unreached in proctype urcu_writer
+       line 395, "pan.___", state 18, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 32, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 50, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 83, "(1)"
+       line 416, "pan.___", state 96, "(1)"
+       line 421, "pan.___", state 113, "(1)"
+       line 250, "pan.___", state 149, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 158, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 171, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 211, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 225, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 243, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 257, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 276, "(1)"
+       line 416, "pan.___", state 289, "(1)"
+       line 421, "pan.___", state 306, "(1)"
+       line 425, "pan.___", state 319, "(1)"
+       line 399, "pan.___", state 356, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 374, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 388, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 420, "(1)"
+       line 421, "pan.___", state 437, "(1)"
+       line 425, "pan.___", state 450, "(1)"
+       line 399, "pan.___", state 494, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 512, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 526, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 558, "(1)"
+       line 421, "pan.___", state 575, "(1)"
+       line 425, "pan.___", state 588, "(1)"
+       line 399, "pan.___", state 623, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 641, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 655, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 687, "(1)"
+       line 421, "pan.___", state 704, "(1)"
+       line 425, "pan.___", state 717, "(1)"
+       line 399, "pan.___", state 754, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 772, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 786, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 818, "(1)"
+       line 421, "pan.___", state 835, "(1)"
+       line 425, "pan.___", state 848, "(1)"
+       line 250, "pan.___", state 898, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 907, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 920, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 945, "(1)"
+       line 231, "pan.___", state 953, "(1)"
+       line 235, "pan.___", state 965, "(1)"
+       line 239, "pan.___", state 973, "(1)"
+       line 250, "pan.___", state 993, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 1002, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1017, "(1)"
+       line 262, "pan.___", state 1024, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1040, "(1)"
+       line 231, "pan.___", state 1048, "(1)"
+       line 235, "pan.___", state 1060, "(1)"
+       line 239, "pan.___", state 1068, "(1)"
+       line 254, "pan.___", state 1093, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1106, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1115, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1131, "(1)"
+       line 231, "pan.___", state 1139, "(1)"
+       line 235, "pan.___", state 1151, "(1)"
+       line 239, "pan.___", state 1159, "(1)"
+       line 254, "pan.___", state 1184, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1197, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1206, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1222, "(1)"
+       line 231, "pan.___", state 1230, "(1)"
+       line 235, "pan.___", state 1242, "(1)"
+       line 239, "pan.___", state 1250, "(1)"
+       line 254, "pan.___", state 1275, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1288, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1297, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1313, "(1)"
+       line 231, "pan.___", state 1321, "(1)"
+       line 235, "pan.___", state 1333, "(1)"
+       line 239, "pan.___", state 1341, "(1)"
+       line 1204, "pan.___", state 1356, "-end-"
+       (78 of 1356 states)
+unreached in proctype :init:
+       (0 of 78 states)
+unreached in proctype :never:
+       line 1265, "pan.___", state 11, "-end-"
+       (1 of 11 states)
+
+pan: elapsed time 7.29e+03 seconds
+pan: rate 1100.4528 states/second
+pan: avg transition delay 1.3969e-06 usec
+cp .input.spin urcu_progress_reader.spin.input
+cp .input.spin.trail urcu_progress_reader.spin.input.trail
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu_progress_reader.spin.input b/formal-model/results/urcu-controldataflow-no-ipi/urcu_progress_reader.spin.input
new file mode 100644 (file)
index 0000000..a9b6907
--- /dev/null
@@ -0,0 +1,1240 @@
+#define READER_PROGRESS
+
+// Poison value for freed memory
+#define POISON 1
+// Memory with correct data
+#define WINE 0
+#define SLAB_SIZE 2
+
+#define read_poison    (data_read_first[0] == POISON || data_read_second[0] == POISON)
+
+#define RCU_GP_CTR_BIT (1 << 7)
+#define RCU_GP_CTR_NEST_MASK (RCU_GP_CTR_BIT - 1)
+
+//disabled
+//#define REMOTE_BARRIERS
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+typedef per_proc_bit {
+       bit val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bitfield {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bitfield cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               /*
+                * 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, j);
+               reader_barrier[get_readerid()] = 0;
+       :: 1 ->
+               /*
+                * 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)
+//#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);                                                           \
+       i = 0;                                                                  \
+       do                                                                      \
+       :: i < NR_READERS ->                                                    \
+               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.                                            \
+                */                                                             \
+               do                                                              \
+               :: (reader_barrier[i] == 1) ->                                  \
+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(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, smp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only one reader */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* RCU data */
+DECLARE_CACHED_VAR(bit, rcu_data[SLAB_SIZE]);
+
+/* RCU pointer */
+#if (SLAB_SIZE == 2)
+DECLARE_CACHED_VAR(bit, rcu_ptr);
+bit ptr_read_first[NR_READERS];
+bit ptr_read_second[NR_READERS];
+#else
+DECLARE_CACHED_VAR(byte, rcu_ptr);
+byte ptr_read_first[NR_READERS];
+byte ptr_read_second[NR_READERS];
+#endif
+
+bit data_read_first[NR_READERS];
+bit data_read_second[NR_READERS];
+
+bit init_done = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               ptr_read_first[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb1;
+rmb1_end:
+                               data_read_first[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_first[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               ptr_read_second[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb2;
+rmb2_end:
+                               data_read_second[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_second[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+rmb1:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb1_end;
+rmb2:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_DATA                     (1 << 1)
+#define WRITE_PROC_WMB                 (1 << 2)
+#define WRITE_XCHG_PTR                 (1 << 3)
+
+#define WRITE_PROC_FIRST_MB            (1 << 4)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 5)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 6)
+#define WRITE_PROC_FIRST_WAIT          (1 << 7)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 8)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 9)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 10)
+#define WRITE_PROC_SECOND_WAIT         (1 << 11)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 12)
+
+#define WRITE_PROC_SECOND_MB           (1 << 13)
+
+#define WRITE_FREE                     (1 << 14)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_DATA                    \
+                                       | WRITE_PROC_WMB                \
+                                       | WRITE_XCHG_PTR                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB          \
+                                       | WRITE_FREE)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 15) - 1)
+
+/*
+ * Mutexes are implied around writer execution. A single writer at a time.
+ */
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte cur_data = 0, old_data, loop_nr = 0;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (loop_nr < 3) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               loop_nr = loop_nr + 1;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_WMB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+#endif
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_DATA) ->
+                       ooo_mem(i);
+                       cur_data = (cur_data + 1) % SLAB_SIZE;
+                       WRITE_CACHED_VAR(rcu_data[cur_data], WINE);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_DATA);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA,
+                                 WRITE_PROC_WMB) ->
+                       smp_wmb(i, j);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_WMB,
+                                 WRITE_XCHG_PTR) ->
+                       /* rcu_xchg_pointer() */
+                       atomic {
+                               old_data = READ_CACHED_VAR(rcu_ptr);
+                               WRITE_CACHED_VAR(rcu_ptr, cur_data);
+                       }
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_XCHG_PTR);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_WMB      /* No dependency on
+                                                        * WRITE_DATA because we
+                                                        * write to a
+                                                        * different location. */
+                                 | WRITE_PROC_SECOND_MB
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_FREE) ->
+                       WRITE_CACHED_VAR(rcu_data[old_data], POISON);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_FREE);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+               /*
+                * Note : Promela model adds implicit serialization of the
+                * WRITE_FREE instruction. Normally, it would be permitted to
+                * spill on the next loop execution. Given the validation we do
+                * checks for the data entry read to be poisoned, it's ok if
+                * we do not check "late arriving" memory poisoning.
+                */
+       :: 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
+#ifdef READER_PROGRESS
+               /*
+                * Make sure we don't block the reader's progress.
+                */
+               smp_mb_send(i, j, 5);
+#endif
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(rcu_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       ptr_read_first[i] = 1;
+                       ptr_read_second[i] = 1;
+                       data_read_first[i] = WINE;
+                       data_read_second[i] = WINE;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               INIT_CACHED_VAR(rcu_data[0], WINE, j);
+               i = 1;
+               do
+               :: i < SLAB_SIZE ->
+                       INIT_CACHED_VAR(rcu_data[i], POISON, j);
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu_progress_writer.define b/formal-model/results/urcu-controldataflow-no-ipi/urcu_progress_writer.define
new file mode 100644 (file)
index 0000000..1e4417f
--- /dev/null
@@ -0,0 +1 @@
+#define WRITER_PROGRESS
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu_progress_writer.log b/formal-model/results/urcu-controldataflow-no-ipi/urcu_progress_writer.log
new file mode 100644 (file)
index 0000000..240c728
--- /dev/null
@@ -0,0 +1,536 @@
+rm -f pan* trail.out .input.spin* *.spin.trail .input.define
+touch .input.define
+cat .input.define > pan.ltl
+cat DEFINES >> pan.ltl
+spin -f "!(`cat urcu_progress.ltl | grep -v ^//`)" >> pan.ltl
+cp urcu_progress_writer.define .input.define
+cat .input.define > .input.spin
+cat DEFINES >> .input.spin
+cat urcu.spin >> .input.spin
+rm -f .input.spin.trail
+spin -a -X -N pan.ltl .input.spin
+Exit-Status 0
+gcc -O2 -w -DHASH64 -o pan pan.c
+./pan -a -f -v -c1 -X -m10000000 -w20
+warning: for p.o. reduction to be valid the never claim must be stutter-invariant
+(never claims generated from LTL formulae are stutter-invariant)
+depth 0: Claim reached state 5 (line 1258)
+depth 23: Claim reached state 9 (line 1263)
+depth 1481: Claim reached state 9 (line 1262)
+Depth=    4026 States=    1e+06 Transitions=  4.1e+08 Memory=   492.131        t=    536 R=   2e+03
+Depth=    4485 States=    2e+06 Transitions= 8.98e+08 Memory=   518.401        t= 1.18e+03 R=   2e+03
+Depth=    4485 States=    3e+06 Transitions= 1.65e+09 Memory=   565.666        t= 2.18e+03 R=   1e+03
+pan: resizing hashtable to -w22..  done
+Depth=    4694 States=    4e+06 Transitions= 2.35e+09 Memory=   638.975        t= 3.12e+03 R=   1e+03
+Depth=    4694 States=    5e+06 Transitions= 3.04e+09 Memory=   684.190        t= 4.03e+03 R=   1e+03
+Depth=    4694 States=    6e+06 Transitions=  3.8e+09 Memory=   723.936        t= 5.04e+03 R=   1e+03
+Depth=    4694 States=    7e+06 Transitions= 4.45e+09 Memory=   769.248        t= 5.92e+03 R=   1e+03
+Depth=    4694 States=    8e+06 Transitions= 5.23e+09 Memory=   814.561        t= 6.96e+03 R=   1e+03
+
+(Spin Version 5.1.7 -- 23 December 2008)
+       + Partial Order Reduction
+
+Full statespace search for:
+       never claim             +
+       assertion violations    + (if within scope of claim)
+       acceptance   cycles     + (fairness enabled)
+       invalid end states      - (disabled by never claim)
+
+State-vector 88 byte, depth reached 4694, errors: 0
+  3819484 states, stored (8.06154e+06 visited)
+5.2640635e+09 states, matched
+5.272125e+09 transitions (= visited+matched)
+3.1366722e+10 atomic steps
+hash conflicts: 1.5911163e+09 (resolved)
+
+Stats on memory usage (in Megabytes):
+  422.535      equivalent memory usage for states (stored*(State-vector + overhead))
+  328.667      actual memory usage for states (compression: 77.78%)
+               state-vector as stored = 62 byte + 28 byte overhead
+   32.000      memory used for hash table (-w22)
+  457.764      memory used for DFS stack (-m10000000)
+  818.174      total actual memory usage
+
+unreached in proctype urcu_reader
+       line 395, "pan.___", state 17, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 49, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 63, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 82, "(1)"
+       line 421, "pan.___", state 112, "(1)"
+       line 425, "pan.___", state 125, "(1)"
+       line 576, "pan.___", state 146, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<1))"
+       line 395, "pan.___", state 153, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 185, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 199, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 218, "(1)"
+       line 421, "pan.___", state 248, "(1)"
+       line 425, "pan.___", state 261, "(1)"
+       line 395, "pan.___", state 282, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 314, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 328, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 347, "(1)"
+       line 421, "pan.___", state 377, "(1)"
+       line 425, "pan.___", state 390, "(1)"
+       line 395, "pan.___", state 413, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 415, "(1)"
+       line 395, "pan.___", state 416, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 416, "else"
+       line 395, "pan.___", state 419, "(1)"
+       line 399, "pan.___", state 427, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 429, "(1)"
+       line 399, "pan.___", state 430, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 430, "else"
+       line 399, "pan.___", state 433, "(1)"
+       line 399, "pan.___", state 434, "(1)"
+       line 399, "pan.___", state 434, "(1)"
+       line 397, "pan.___", state 439, "((i<1))"
+       line 397, "pan.___", state 439, "((i>=1))"
+       line 404, "pan.___", state 445, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 447, "(1)"
+       line 404, "pan.___", state 448, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 448, "else"
+       line 404, "pan.___", state 451, "(1)"
+       line 404, "pan.___", state 452, "(1)"
+       line 404, "pan.___", state 452, "(1)"
+       line 408, "pan.___", state 459, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 461, "(1)"
+       line 408, "pan.___", state 462, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 462, "else"
+       line 408, "pan.___", state 465, "(1)"
+       line 408, "pan.___", state 466, "(1)"
+       line 408, "pan.___", state 466, "(1)"
+       line 406, "pan.___", state 471, "((i<2))"
+       line 406, "pan.___", state 471, "((i>=2))"
+       line 412, "pan.___", state 478, "(1)"
+       line 412, "pan.___", state 479, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 479, "else"
+       line 412, "pan.___", state 482, "(1)"
+       line 412, "pan.___", state 483, "(1)"
+       line 412, "pan.___", state 483, "(1)"
+       line 416, "pan.___", state 491, "(1)"
+       line 416, "pan.___", state 492, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 492, "else"
+       line 416, "pan.___", state 495, "(1)"
+       line 416, "pan.___", state 496, "(1)"
+       line 416, "pan.___", state 496, "(1)"
+       line 414, "pan.___", state 501, "((i<1))"
+       line 414, "pan.___", state 501, "((i>=1))"
+       line 421, "pan.___", state 508, "(1)"
+       line 421, "pan.___", state 509, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 509, "else"
+       line 421, "pan.___", state 512, "(1)"
+       line 421, "pan.___", state 513, "(1)"
+       line 421, "pan.___", state 513, "(1)"
+       line 425, "pan.___", state 521, "(1)"
+       line 425, "pan.___", state 522, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 522, "else"
+       line 425, "pan.___", state 525, "(1)"
+       line 425, "pan.___", state 526, "(1)"
+       line 425, "pan.___", state 526, "(1)"
+       line 423, "pan.___", state 531, "((i<2))"
+       line 423, "pan.___", state 531, "((i>=2))"
+       line 430, "pan.___", state 535, "(1)"
+       line 430, "pan.___", state 535, "(1)"
+       line 576, "pan.___", state 538, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 576, "pan.___", state 539, "_proc_urcu_reader = (_proc_urcu_reader|(1<<5))"
+       line 576, "pan.___", state 540, "(1)"
+       line 250, "pan.___", state 544, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 555, "(1)"
+       line 258, "pan.___", state 566, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 575, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 591, "(1)"
+       line 231, "pan.___", state 599, "(1)"
+       line 235, "pan.___", state 611, "(1)"
+       line 239, "pan.___", state 619, "(1)"
+       line 395, "pan.___", state 637, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 651, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 669, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 683, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 702, "(1)"
+       line 416, "pan.___", state 715, "(1)"
+       line 421, "pan.___", state 732, "(1)"
+       line 425, "pan.___", state 745, "(1)"
+       line 395, "pan.___", state 773, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 775, "(1)"
+       line 395, "pan.___", state 776, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 776, "else"
+       line 395, "pan.___", state 779, "(1)"
+       line 399, "pan.___", state 787, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 789, "(1)"
+       line 399, "pan.___", state 790, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 790, "else"
+       line 399, "pan.___", state 793, "(1)"
+       line 399, "pan.___", state 794, "(1)"
+       line 399, "pan.___", state 794, "(1)"
+       line 397, "pan.___", state 799, "((i<1))"
+       line 397, "pan.___", state 799, "((i>=1))"
+       line 404, "pan.___", state 805, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 807, "(1)"
+       line 404, "pan.___", state 808, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 808, "else"
+       line 404, "pan.___", state 811, "(1)"
+       line 404, "pan.___", state 812, "(1)"
+       line 404, "pan.___", state 812, "(1)"
+       line 408, "pan.___", state 819, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 821, "(1)"
+       line 408, "pan.___", state 822, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 822, "else"
+       line 408, "pan.___", state 825, "(1)"
+       line 408, "pan.___", state 826, "(1)"
+       line 408, "pan.___", state 826, "(1)"
+       line 406, "pan.___", state 831, "((i<2))"
+       line 406, "pan.___", state 831, "((i>=2))"
+       line 412, "pan.___", state 838, "(1)"
+       line 412, "pan.___", state 839, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 839, "else"
+       line 412, "pan.___", state 842, "(1)"
+       line 412, "pan.___", state 843, "(1)"
+       line 412, "pan.___", state 843, "(1)"
+       line 416, "pan.___", state 851, "(1)"
+       line 416, "pan.___", state 852, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 852, "else"
+       line 416, "pan.___", state 855, "(1)"
+       line 416, "pan.___", state 856, "(1)"
+       line 416, "pan.___", state 856, "(1)"
+       line 414, "pan.___", state 861, "((i<1))"
+       line 414, "pan.___", state 861, "((i>=1))"
+       line 421, "pan.___", state 868, "(1)"
+       line 421, "pan.___", state 869, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 869, "else"
+       line 421, "pan.___", state 872, "(1)"
+       line 421, "pan.___", state 873, "(1)"
+       line 421, "pan.___", state 873, "(1)"
+       line 425, "pan.___", state 881, "(1)"
+       line 425, "pan.___", state 882, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 882, "else"
+       line 425, "pan.___", state 885, "(1)"
+       line 425, "pan.___", state 886, "(1)"
+       line 425, "pan.___", state 886, "(1)"
+       line 430, "pan.___", state 895, "(1)"
+       line 430, "pan.___", state 895, "(1)"
+       line 395, "pan.___", state 902, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 904, "(1)"
+       line 395, "pan.___", state 905, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 905, "else"
+       line 395, "pan.___", state 908, "(1)"
+       line 399, "pan.___", state 916, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 918, "(1)"
+       line 399, "pan.___", state 919, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 919, "else"
+       line 399, "pan.___", state 922, "(1)"
+       line 399, "pan.___", state 923, "(1)"
+       line 399, "pan.___", state 923, "(1)"
+       line 397, "pan.___", state 928, "((i<1))"
+       line 397, "pan.___", state 928, "((i>=1))"
+       line 404, "pan.___", state 934, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 936, "(1)"
+       line 404, "pan.___", state 937, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 937, "else"
+       line 404, "pan.___", state 940, "(1)"
+       line 404, "pan.___", state 941, "(1)"
+       line 404, "pan.___", state 941, "(1)"
+       line 408, "pan.___", state 948, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 950, "(1)"
+       line 408, "pan.___", state 951, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 951, "else"
+       line 408, "pan.___", state 954, "(1)"
+       line 408, "pan.___", state 955, "(1)"
+       line 408, "pan.___", state 955, "(1)"
+       line 406, "pan.___", state 960, "((i<2))"
+       line 406, "pan.___", state 960, "((i>=2))"
+       line 412, "pan.___", state 967, "(1)"
+       line 412, "pan.___", state 968, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 968, "else"
+       line 412, "pan.___", state 971, "(1)"
+       line 412, "pan.___", state 972, "(1)"
+       line 412, "pan.___", state 972, "(1)"
+       line 416, "pan.___", state 980, "(1)"
+       line 416, "pan.___", state 981, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 981, "else"
+       line 416, "pan.___", state 984, "(1)"
+       line 416, "pan.___", state 985, "(1)"
+       line 416, "pan.___", state 985, "(1)"
+       line 414, "pan.___", state 990, "((i<1))"
+       line 414, "pan.___", state 990, "((i>=1))"
+       line 421, "pan.___", state 997, "(1)"
+       line 421, "pan.___", state 998, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 998, "else"
+       line 421, "pan.___", state 1001, "(1)"
+       line 421, "pan.___", state 1002, "(1)"
+       line 421, "pan.___", state 1002, "(1)"
+       line 425, "pan.___", state 1010, "(1)"
+       line 425, "pan.___", state 1011, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 1011, "else"
+       line 425, "pan.___", state 1014, "(1)"
+       line 425, "pan.___", state 1015, "(1)"
+       line 425, "pan.___", state 1015, "(1)"
+       line 423, "pan.___", state 1020, "((i<2))"
+       line 423, "pan.___", state 1020, "((i>=2))"
+       line 430, "pan.___", state 1024, "(1)"
+       line 430, "pan.___", state 1024, "(1)"
+       line 584, "pan.___", state 1028, "_proc_urcu_reader = (_proc_urcu_reader|(1<<11))"
+       line 395, "pan.___", state 1033, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 1047, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1065, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1079, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1098, "(1)"
+       line 416, "pan.___", state 1111, "(1)"
+       line 421, "pan.___", state 1128, "(1)"
+       line 425, "pan.___", state 1141, "(1)"
+       line 395, "pan.___", state 1165, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1197, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1211, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1230, "(1)"
+       line 421, "pan.___", state 1260, "(1)"
+       line 425, "pan.___", state 1273, "(1)"
+       line 395, "pan.___", state 1298, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1330, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1344, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1363, "(1)"
+       line 421, "pan.___", state 1393, "(1)"
+       line 425, "pan.___", state 1406, "(1)"
+       line 395, "pan.___", state 1427, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1459, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1473, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1492, "(1)"
+       line 421, "pan.___", state 1522, "(1)"
+       line 425, "pan.___", state 1535, "(1)"
+       line 250, "pan.___", state 1558, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1580, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1589, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1605, "(1)"
+       line 231, "pan.___", state 1613, "(1)"
+       line 235, "pan.___", state 1625, "(1)"
+       line 239, "pan.___", state 1633, "(1)"
+       line 395, "pan.___", state 1651, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 1665, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1683, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1697, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1716, "(1)"
+       line 416, "pan.___", state 1729, "(1)"
+       line 421, "pan.___", state 1746, "(1)"
+       line 425, "pan.___", state 1759, "(1)"
+       line 395, "pan.___", state 1780, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 1794, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 1812, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1826, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1845, "(1)"
+       line 416, "pan.___", state 1858, "(1)"
+       line 421, "pan.___", state 1875, "(1)"
+       line 425, "pan.___", state 1888, "(1)"
+       line 395, "pan.___", state 1912, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 1928, "(1)"
+       line 404, "pan.___", state 1944, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 1958, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 1977, "(1)"
+       line 421, "pan.___", state 2007, "(1)"
+       line 425, "pan.___", state 2020, "(1)"
+       line 623, "pan.___", state 2041, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<19))"
+       line 395, "pan.___", state 2048, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2080, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2094, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2113, "(1)"
+       line 421, "pan.___", state 2143, "(1)"
+       line 425, "pan.___", state 2156, "(1)"
+       line 395, "pan.___", state 2177, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2209, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2223, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2242, "(1)"
+       line 421, "pan.___", state 2272, "(1)"
+       line 425, "pan.___", state 2285, "(1)"
+       line 395, "pan.___", state 2308, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 2310, "(1)"
+       line 395, "pan.___", state 2311, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 395, "pan.___", state 2311, "else"
+       line 395, "pan.___", state 2314, "(1)"
+       line 399, "pan.___", state 2322, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 2324, "(1)"
+       line 399, "pan.___", state 2325, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 399, "pan.___", state 2325, "else"
+       line 399, "pan.___", state 2328, "(1)"
+       line 399, "pan.___", state 2329, "(1)"
+       line 399, "pan.___", state 2329, "(1)"
+       line 397, "pan.___", state 2334, "((i<1))"
+       line 397, "pan.___", state 2334, "((i>=1))"
+       line 404, "pan.___", state 2340, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2342, "(1)"
+       line 404, "pan.___", state 2343, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 404, "pan.___", state 2343, "else"
+       line 404, "pan.___", state 2346, "(1)"
+       line 404, "pan.___", state 2347, "(1)"
+       line 404, "pan.___", state 2347, "(1)"
+       line 408, "pan.___", state 2354, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2356, "(1)"
+       line 408, "pan.___", state 2357, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 408, "pan.___", state 2357, "else"
+       line 408, "pan.___", state 2360, "(1)"
+       line 408, "pan.___", state 2361, "(1)"
+       line 408, "pan.___", state 2361, "(1)"
+       line 406, "pan.___", state 2366, "((i<2))"
+       line 406, "pan.___", state 2366, "((i>=2))"
+       line 412, "pan.___", state 2373, "(1)"
+       line 412, "pan.___", state 2374, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 412, "pan.___", state 2374, "else"
+       line 412, "pan.___", state 2377, "(1)"
+       line 412, "pan.___", state 2378, "(1)"
+       line 412, "pan.___", state 2378, "(1)"
+       line 416, "pan.___", state 2386, "(1)"
+       line 416, "pan.___", state 2387, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 416, "pan.___", state 2387, "else"
+       line 416, "pan.___", state 2390, "(1)"
+       line 416, "pan.___", state 2391, "(1)"
+       line 416, "pan.___", state 2391, "(1)"
+       line 414, "pan.___", state 2396, "((i<1))"
+       line 414, "pan.___", state 2396, "((i>=1))"
+       line 421, "pan.___", state 2403, "(1)"
+       line 421, "pan.___", state 2404, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 421, "pan.___", state 2404, "else"
+       line 421, "pan.___", state 2407, "(1)"
+       line 421, "pan.___", state 2408, "(1)"
+       line 421, "pan.___", state 2408, "(1)"
+       line 425, "pan.___", state 2416, "(1)"
+       line 425, "pan.___", state 2417, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 425, "pan.___", state 2417, "else"
+       line 425, "pan.___", state 2420, "(1)"
+       line 425, "pan.___", state 2421, "(1)"
+       line 425, "pan.___", state 2421, "(1)"
+       line 423, "pan.___", state 2426, "((i<2))"
+       line 423, "pan.___", state 2426, "((i>=2))"
+       line 430, "pan.___", state 2430, "(1)"
+       line 430, "pan.___", state 2430, "(1)"
+       line 623, "pan.___", state 2433, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 623, "pan.___", state 2434, "_proc_urcu_reader = (_proc_urcu_reader|(1<<23))"
+       line 623, "pan.___", state 2435, "(1)"
+       line 250, "pan.___", state 2439, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 2450, "(1)"
+       line 258, "pan.___", state 2461, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 2470, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 2486, "(1)"
+       line 231, "pan.___", state 2494, "(1)"
+       line 235, "pan.___", state 2506, "(1)"
+       line 239, "pan.___", state 2514, "(1)"
+       line 395, "pan.___", state 2532, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 2546, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2564, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2578, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2597, "(1)"
+       line 416, "pan.___", state 2610, "(1)"
+       line 421, "pan.___", state 2627, "(1)"
+       line 425, "pan.___", state 2640, "(1)"
+       line 250, "pan.___", state 2664, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 2673, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 2686, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 2695, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 2711, "(1)"
+       line 231, "pan.___", state 2719, "(1)"
+       line 235, "pan.___", state 2731, "(1)"
+       line 239, "pan.___", state 2739, "(1)"
+       line 395, "pan.___", state 2757, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 2771, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2789, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2803, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2822, "(1)"
+       line 416, "pan.___", state 2835, "(1)"
+       line 421, "pan.___", state 2852, "(1)"
+       line 425, "pan.___", state 2865, "(1)"
+       line 395, "pan.___", state 2886, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 2900, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 2918, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 2932, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 2951, "(1)"
+       line 416, "pan.___", state 2964, "(1)"
+       line 421, "pan.___", state 2981, "(1)"
+       line 425, "pan.___", state 2994, "(1)"
+       line 227, "pan.___", state 3027, "(1)"
+       line 235, "pan.___", state 3047, "(1)"
+       line 239, "pan.___", state 3055, "(1)"
+       line 227, "pan.___", state 3070, "(1)"
+       line 231, "pan.___", state 3078, "(1)"
+       line 235, "pan.___", state 3090, "(1)"
+       line 239, "pan.___", state 3098, "(1)"
+       line 877, "pan.___", state 3115, "-end-"
+       (318 of 3115 states)
+unreached in proctype urcu_writer
+       line 395, "pan.___", state 18, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 32, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 50, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 83, "(1)"
+       line 416, "pan.___", state 96, "(1)"
+       line 421, "pan.___", state 113, "(1)"
+       line 250, "pan.___", state 149, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 158, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 171, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 395, "pan.___", state 211, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 399, "pan.___", state 225, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 243, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 257, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 412, "pan.___", state 276, "(1)"
+       line 416, "pan.___", state 289, "(1)"
+       line 421, "pan.___", state 306, "(1)"
+       line 425, "pan.___", state 319, "(1)"
+       line 399, "pan.___", state 356, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 374, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 388, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 420, "(1)"
+       line 421, "pan.___", state 437, "(1)"
+       line 425, "pan.___", state 450, "(1)"
+       line 399, "pan.___", state 494, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 512, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 526, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 558, "(1)"
+       line 421, "pan.___", state 575, "(1)"
+       line 425, "pan.___", state 588, "(1)"
+       line 399, "pan.___", state 623, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 641, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 655, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 687, "(1)"
+       line 421, "pan.___", state 704, "(1)"
+       line 425, "pan.___", state 717, "(1)"
+       line 399, "pan.___", state 754, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 404, "pan.___", state 772, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 408, "pan.___", state 786, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 416, "pan.___", state 818, "(1)"
+       line 421, "pan.___", state 835, "(1)"
+       line 425, "pan.___", state 848, "(1)"
+       line 250, "pan.___", state 903, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 254, "pan.___", state 912, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 927, "(1)"
+       line 262, "pan.___", state 934, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 950, "(1)"
+       line 231, "pan.___", state 958, "(1)"
+       line 235, "pan.___", state 970, "(1)"
+       line 239, "pan.___", state 978, "(1)"
+       line 254, "pan.___", state 1003, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1016, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1025, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1041, "(1)"
+       line 231, "pan.___", state 1049, "(1)"
+       line 235, "pan.___", state 1061, "(1)"
+       line 239, "pan.___", state 1069, "(1)"
+       line 254, "pan.___", state 1094, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1107, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1116, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1132, "(1)"
+       line 231, "pan.___", state 1140, "(1)"
+       line 235, "pan.___", state 1152, "(1)"
+       line 239, "pan.___", state 1160, "(1)"
+       line 254, "pan.___", state 1185, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 258, "pan.___", state 1198, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 262, "pan.___", state 1207, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 227, "pan.___", state 1223, "(1)"
+       line 231, "pan.___", state 1231, "(1)"
+       line 235, "pan.___", state 1243, "(1)"
+       line 239, "pan.___", state 1251, "(1)"
+       line 1204, "pan.___", state 1266, "-end-"
+       (71 of 1266 states)
+unreached in proctype :init:
+       (0 of 78 states)
+unreached in proctype :never:
+       line 1265, "pan.___", state 11, "-end-"
+       (1 of 11 states)
+
+pan: elapsed time 7.01e+03 seconds
+pan: rate 1149.3413 states/second
+pan: avg transition delay 1.3304e-06 usec
+cp .input.spin urcu_progress_writer.spin.input
+cp .input.spin.trail urcu_progress_writer.spin.input.trail
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu_progress_writer.spin.input b/formal-model/results/urcu-controldataflow-no-ipi/urcu_progress_writer.spin.input
new file mode 100644 (file)
index 0000000..d9d698f
--- /dev/null
@@ -0,0 +1,1240 @@
+#define WRITER_PROGRESS
+
+// Poison value for freed memory
+#define POISON 1
+// Memory with correct data
+#define WINE 0
+#define SLAB_SIZE 2
+
+#define read_poison    (data_read_first[0] == POISON || data_read_second[0] == POISON)
+
+#define RCU_GP_CTR_BIT (1 << 7)
+#define RCU_GP_CTR_NEST_MASK (RCU_GP_CTR_BIT - 1)
+
+//disabled
+//#define REMOTE_BARRIERS
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+typedef per_proc_bit {
+       bit val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bitfield {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bitfield cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               /*
+                * 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, j);
+               reader_barrier[get_readerid()] = 0;
+       :: 1 ->
+               /*
+                * 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)
+//#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);                                                           \
+       i = 0;                                                                  \
+       do                                                                      \
+       :: i < NR_READERS ->                                                    \
+               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.                                            \
+                */                                                             \
+               do                                                              \
+               :: (reader_barrier[i] == 1) ->                                  \
+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(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, smp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only one reader */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* RCU data */
+DECLARE_CACHED_VAR(bit, rcu_data[SLAB_SIZE]);
+
+/* RCU pointer */
+#if (SLAB_SIZE == 2)
+DECLARE_CACHED_VAR(bit, rcu_ptr);
+bit ptr_read_first[NR_READERS];
+bit ptr_read_second[NR_READERS];
+#else
+DECLARE_CACHED_VAR(byte, rcu_ptr);
+byte ptr_read_first[NR_READERS];
+byte ptr_read_second[NR_READERS];
+#endif
+
+bit data_read_first[NR_READERS];
+bit data_read_second[NR_READERS];
+
+bit init_done = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               ptr_read_first[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb1;
+rmb1_end:
+                               data_read_first[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_first[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               ptr_read_second[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb2;
+rmb2_end:
+                               data_read_second[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_second[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+rmb1:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb1_end;
+rmb2:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_DATA                     (1 << 1)
+#define WRITE_PROC_WMB                 (1 << 2)
+#define WRITE_XCHG_PTR                 (1 << 3)
+
+#define WRITE_PROC_FIRST_MB            (1 << 4)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 5)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 6)
+#define WRITE_PROC_FIRST_WAIT          (1 << 7)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 8)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 9)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 10)
+#define WRITE_PROC_SECOND_WAIT         (1 << 11)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 12)
+
+#define WRITE_PROC_SECOND_MB           (1 << 13)
+
+#define WRITE_FREE                     (1 << 14)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_DATA                    \
+                                       | WRITE_PROC_WMB                \
+                                       | WRITE_XCHG_PTR                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB          \
+                                       | WRITE_FREE)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 15) - 1)
+
+/*
+ * Mutexes are implied around writer execution. A single writer at a time.
+ */
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte cur_data = 0, old_data, loop_nr = 0;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (loop_nr < 3) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               loop_nr = loop_nr + 1;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_WMB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+#endif
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_DATA) ->
+                       ooo_mem(i);
+                       cur_data = (cur_data + 1) % SLAB_SIZE;
+                       WRITE_CACHED_VAR(rcu_data[cur_data], WINE);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_DATA);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA,
+                                 WRITE_PROC_WMB) ->
+                       smp_wmb(i, j);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_WMB,
+                                 WRITE_XCHG_PTR) ->
+                       /* rcu_xchg_pointer() */
+                       atomic {
+                               old_data = READ_CACHED_VAR(rcu_ptr);
+                               WRITE_CACHED_VAR(rcu_ptr, cur_data);
+                       }
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_XCHG_PTR);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_WMB      /* No dependency on
+                                                        * WRITE_DATA because we
+                                                        * write to a
+                                                        * different location. */
+                                 | WRITE_PROC_SECOND_MB
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_FREE) ->
+                       WRITE_CACHED_VAR(rcu_data[old_data], POISON);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_FREE);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+               /*
+                * Note : Promela model adds implicit serialization of the
+                * WRITE_FREE instruction. Normally, it would be permitted to
+                * spill on the next loop execution. Given the validation we do
+                * checks for the data entry read to be poisoned, it's ok if
+                * we do not check "late arriving" memory poisoning.
+                */
+       :: 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
+#ifdef READER_PROGRESS
+               /*
+                * Make sure we don't block the reader's progress.
+                */
+               smp_mb_send(i, j, 5);
+#endif
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(rcu_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       ptr_read_first[i] = 1;
+                       ptr_read_second[i] = 1;
+                       data_read_first[i] = WINE;
+                       data_read_second[i] = WINE;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               INIT_CACHED_VAR(rcu_data[0], WINE, j);
+               i = 1;
+               do
+               :: i < SLAB_SIZE ->
+                       INIT_CACHED_VAR(rcu_data[i], POISON, j);
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu_progress_writer_error.define b/formal-model/results/urcu-controldataflow-no-ipi/urcu_progress_writer_error.define
new file mode 100644 (file)
index 0000000..8d304f5
--- /dev/null
@@ -0,0 +1,2 @@
+#define WRITER_PROGRESS
+#define GEN_ERROR_WRITER_PROGRESS
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu_progress_writer_error.log b/formal-model/results/urcu-controldataflow-no-ipi/urcu_progress_writer_error.log
new file mode 100644 (file)
index 0000000..99db2db
--- /dev/null
@@ -0,0 +1,809 @@
+rm -f pan* trail.out .input.spin* *.spin.trail .input.define
+touch .input.define
+cat .input.define > pan.ltl
+cat DEFINES >> pan.ltl
+spin -f "!(`cat urcu_progress.ltl | grep -v ^//`)" >> pan.ltl
+cp urcu_progress_writer_error.define .input.define
+cat .input.define > .input.spin
+cat DEFINES >> .input.spin
+cat urcu.spin >> .input.spin
+rm -f .input.spin.trail
+spin -a -X -N pan.ltl .input.spin
+Exit-Status 0
+gcc -O2 -w -DHASH64 -o pan pan.c
+./pan -a -f -v -c1 -X -m10000000 -w20
+warning: for p.o. reduction to be valid the never claim must be stutter-invariant
+(never claims generated from LTL formulae are stutter-invariant)
+depth 0: Claim reached state 5 (line 1259)
+depth 23: Claim reached state 9 (line 1264)
+depth 1481: Claim reached state 9 (line 1263)
+pan: acceptance cycle (at depth 7186)
+pan: wrote .input.spin.trail
+
+(Spin Version 5.1.7 -- 23 December 2008)
+Warning: Search not completed
+       + Partial Order Reduction
+
+Full statespace search for:
+       never claim             +
+       assertion violations    + (if within scope of claim)
+       acceptance   cycles     + (fairness enabled)
+       invalid end states      - (disabled by never claim)
+
+State-vector 88 byte, depth reached 8718, errors: 1
+    25100 states, stored (77932 visited)
+ 18210466 states, matched
+ 18288398 transitions (= visited+matched)
+1.0440929e+08 atomic steps
+hash conflicts:    119465 (resolved)
+
+Stats on memory usage (in Megabytes):
+    2.777      equivalent memory usage for states (stored*(State-vector + overhead))
+    2.791      actual memory usage for states (unsuccessful compression: 100.52%)
+               state-vector as stored = 89 byte + 28 byte overhead
+    8.000      memory used for hash table (-w20)
+  457.764      memory used for DFS stack (-m10000000)
+  468.498      total actual memory usage
+
+unreached in proctype urcu_reader
+       line 396, "pan.___", state 17, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 49, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 63, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 82, "(1)"
+       line 422, "pan.___", state 112, "(1)"
+       line 426, "pan.___", state 125, "(1)"
+       line 577, "pan.___", state 146, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<1))"
+       line 396, "pan.___", state 153, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 185, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 199, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 218, "(1)"
+       line 422, "pan.___", state 248, "(1)"
+       line 426, "pan.___", state 261, "(1)"
+       line 396, "pan.___", state 282, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 314, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 328, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 347, "(1)"
+       line 422, "pan.___", state 377, "(1)"
+       line 426, "pan.___", state 390, "(1)"
+       line 396, "pan.___", state 413, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 415, "(1)"
+       line 396, "pan.___", state 416, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 416, "else"
+       line 396, "pan.___", state 419, "(1)"
+       line 400, "pan.___", state 427, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 429, "(1)"
+       line 400, "pan.___", state 430, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 430, "else"
+       line 400, "pan.___", state 433, "(1)"
+       line 400, "pan.___", state 434, "(1)"
+       line 400, "pan.___", state 434, "(1)"
+       line 398, "pan.___", state 439, "((i<1))"
+       line 398, "pan.___", state 439, "((i>=1))"
+       line 405, "pan.___", state 445, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 447, "(1)"
+       line 405, "pan.___", state 448, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 405, "pan.___", state 448, "else"
+       line 405, "pan.___", state 451, "(1)"
+       line 405, "pan.___", state 452, "(1)"
+       line 405, "pan.___", state 452, "(1)"
+       line 409, "pan.___", state 459, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 461, "(1)"
+       line 409, "pan.___", state 462, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 409, "pan.___", state 462, "else"
+       line 409, "pan.___", state 465, "(1)"
+       line 409, "pan.___", state 466, "(1)"
+       line 409, "pan.___", state 466, "(1)"
+       line 407, "pan.___", state 471, "((i<2))"
+       line 407, "pan.___", state 471, "((i>=2))"
+       line 413, "pan.___", state 478, "(1)"
+       line 413, "pan.___", state 479, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 479, "else"
+       line 413, "pan.___", state 482, "(1)"
+       line 413, "pan.___", state 483, "(1)"
+       line 413, "pan.___", state 483, "(1)"
+       line 417, "pan.___", state 491, "(1)"
+       line 417, "pan.___", state 492, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 492, "else"
+       line 417, "pan.___", state 495, "(1)"
+       line 417, "pan.___", state 496, "(1)"
+       line 417, "pan.___", state 496, "(1)"
+       line 415, "pan.___", state 501, "((i<1))"
+       line 415, "pan.___", state 501, "((i>=1))"
+       line 422, "pan.___", state 508, "(1)"
+       line 422, "pan.___", state 509, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 422, "pan.___", state 509, "else"
+       line 422, "pan.___", state 512, "(1)"
+       line 422, "pan.___", state 513, "(1)"
+       line 422, "pan.___", state 513, "(1)"
+       line 426, "pan.___", state 521, "(1)"
+       line 426, "pan.___", state 522, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 426, "pan.___", state 522, "else"
+       line 426, "pan.___", state 525, "(1)"
+       line 426, "pan.___", state 526, "(1)"
+       line 426, "pan.___", state 526, "(1)"
+       line 424, "pan.___", state 531, "((i<2))"
+       line 424, "pan.___", state 531, "((i>=2))"
+       line 431, "pan.___", state 535, "(1)"
+       line 431, "pan.___", state 535, "(1)"
+       line 577, "pan.___", state 538, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 577, "pan.___", state 539, "_proc_urcu_reader = (_proc_urcu_reader|(1<<5))"
+       line 577, "pan.___", state 540, "(1)"
+       line 251, "pan.___", state 544, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 255, "pan.___", state 555, "(1)"
+       line 259, "pan.___", state 566, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 263, "pan.___", state 575, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 228, "pan.___", state 591, "(1)"
+       line 232, "pan.___", state 599, "(1)"
+       line 236, "pan.___", state 611, "(1)"
+       line 240, "pan.___", state 619, "(1)"
+       line 396, "pan.___", state 637, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 651, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 669, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 683, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 702, "(1)"
+       line 417, "pan.___", state 715, "(1)"
+       line 422, "pan.___", state 732, "(1)"
+       line 426, "pan.___", state 745, "(1)"
+       line 396, "pan.___", state 773, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 775, "(1)"
+       line 396, "pan.___", state 776, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 776, "else"
+       line 396, "pan.___", state 779, "(1)"
+       line 400, "pan.___", state 787, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 789, "(1)"
+       line 400, "pan.___", state 790, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 790, "else"
+       line 400, "pan.___", state 793, "(1)"
+       line 400, "pan.___", state 794, "(1)"
+       line 400, "pan.___", state 794, "(1)"
+       line 398, "pan.___", state 799, "((i<1))"
+       line 398, "pan.___", state 799, "((i>=1))"
+       line 405, "pan.___", state 805, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 807, "(1)"
+       line 405, "pan.___", state 808, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 405, "pan.___", state 808, "else"
+       line 405, "pan.___", state 811, "(1)"
+       line 405, "pan.___", state 812, "(1)"
+       line 405, "pan.___", state 812, "(1)"
+       line 409, "pan.___", state 819, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 821, "(1)"
+       line 409, "pan.___", state 822, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 409, "pan.___", state 822, "else"
+       line 409, "pan.___", state 825, "(1)"
+       line 409, "pan.___", state 826, "(1)"
+       line 409, "pan.___", state 826, "(1)"
+       line 407, "pan.___", state 831, "((i<2))"
+       line 407, "pan.___", state 831, "((i>=2))"
+       line 413, "pan.___", state 838, "(1)"
+       line 413, "pan.___", state 839, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 839, "else"
+       line 413, "pan.___", state 842, "(1)"
+       line 413, "pan.___", state 843, "(1)"
+       line 413, "pan.___", state 843, "(1)"
+       line 417, "pan.___", state 851, "(1)"
+       line 417, "pan.___", state 852, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 852, "else"
+       line 417, "pan.___", state 855, "(1)"
+       line 417, "pan.___", state 856, "(1)"
+       line 417, "pan.___", state 856, "(1)"
+       line 415, "pan.___", state 861, "((i<1))"
+       line 415, "pan.___", state 861, "((i>=1))"
+       line 422, "pan.___", state 868, "(1)"
+       line 422, "pan.___", state 869, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 422, "pan.___", state 869, "else"
+       line 422, "pan.___", state 872, "(1)"
+       line 422, "pan.___", state 873, "(1)"
+       line 422, "pan.___", state 873, "(1)"
+       line 426, "pan.___", state 881, "(1)"
+       line 426, "pan.___", state 882, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 426, "pan.___", state 882, "else"
+       line 426, "pan.___", state 885, "(1)"
+       line 426, "pan.___", state 886, "(1)"
+       line 426, "pan.___", state 886, "(1)"
+       line 431, "pan.___", state 895, "(1)"
+       line 431, "pan.___", state 895, "(1)"
+       line 396, "pan.___", state 902, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 904, "(1)"
+       line 396, "pan.___", state 905, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 905, "else"
+       line 396, "pan.___", state 908, "(1)"
+       line 400, "pan.___", state 916, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 918, "(1)"
+       line 400, "pan.___", state 919, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 919, "else"
+       line 400, "pan.___", state 922, "(1)"
+       line 400, "pan.___", state 923, "(1)"
+       line 400, "pan.___", state 923, "(1)"
+       line 398, "pan.___", state 928, "((i<1))"
+       line 398, "pan.___", state 928, "((i>=1))"
+       line 405, "pan.___", state 934, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 936, "(1)"
+       line 405, "pan.___", state 937, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 405, "pan.___", state 937, "else"
+       line 405, "pan.___", state 940, "(1)"
+       line 405, "pan.___", state 941, "(1)"
+       line 405, "pan.___", state 941, "(1)"
+       line 409, "pan.___", state 948, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 950, "(1)"
+       line 409, "pan.___", state 951, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 409, "pan.___", state 951, "else"
+       line 409, "pan.___", state 954, "(1)"
+       line 409, "pan.___", state 955, "(1)"
+       line 409, "pan.___", state 955, "(1)"
+       line 407, "pan.___", state 960, "((i<2))"
+       line 407, "pan.___", state 960, "((i>=2))"
+       line 413, "pan.___", state 967, "(1)"
+       line 413, "pan.___", state 968, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 968, "else"
+       line 413, "pan.___", state 971, "(1)"
+       line 413, "pan.___", state 972, "(1)"
+       line 413, "pan.___", state 972, "(1)"
+       line 417, "pan.___", state 980, "(1)"
+       line 417, "pan.___", state 981, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 981, "else"
+       line 417, "pan.___", state 984, "(1)"
+       line 417, "pan.___", state 985, "(1)"
+       line 417, "pan.___", state 985, "(1)"
+       line 415, "pan.___", state 990, "((i<1))"
+       line 415, "pan.___", state 990, "((i>=1))"
+       line 422, "pan.___", state 997, "(1)"
+       line 422, "pan.___", state 998, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 422, "pan.___", state 998, "else"
+       line 422, "pan.___", state 1001, "(1)"
+       line 422, "pan.___", state 1002, "(1)"
+       line 422, "pan.___", state 1002, "(1)"
+       line 426, "pan.___", state 1010, "(1)"
+       line 426, "pan.___", state 1011, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 426, "pan.___", state 1011, "else"
+       line 426, "pan.___", state 1014, "(1)"
+       line 426, "pan.___", state 1015, "(1)"
+       line 426, "pan.___", state 1015, "(1)"
+       line 424, "pan.___", state 1020, "((i<2))"
+       line 424, "pan.___", state 1020, "((i>=2))"
+       line 431, "pan.___", state 1024, "(1)"
+       line 431, "pan.___", state 1024, "(1)"
+       line 585, "pan.___", state 1028, "_proc_urcu_reader = (_proc_urcu_reader|(1<<11))"
+       line 396, "pan.___", state 1033, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1047, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 1065, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 1079, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 1098, "(1)"
+       line 417, "pan.___", state 1111, "(1)"
+       line 422, "pan.___", state 1128, "(1)"
+       line 426, "pan.___", state 1141, "(1)"
+       line 396, "pan.___", state 1165, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 1197, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 1211, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 1230, "(1)"
+       line 422, "pan.___", state 1260, "(1)"
+       line 426, "pan.___", state 1273, "(1)"
+       line 396, "pan.___", state 1298, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 1330, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 1344, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 1363, "(1)"
+       line 422, "pan.___", state 1393, "(1)"
+       line 426, "pan.___", state 1406, "(1)"
+       line 396, "pan.___", state 1427, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 1459, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 1473, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 1492, "(1)"
+       line 422, "pan.___", state 1522, "(1)"
+       line 426, "pan.___", state 1535, "(1)"
+       line 251, "pan.___", state 1558, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 259, "pan.___", state 1580, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 263, "pan.___", state 1589, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 228, "pan.___", state 1605, "(1)"
+       line 232, "pan.___", state 1613, "(1)"
+       line 236, "pan.___", state 1625, "(1)"
+       line 240, "pan.___", state 1633, "(1)"
+       line 396, "pan.___", state 1651, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1665, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 1683, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 1697, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 1716, "(1)"
+       line 417, "pan.___", state 1729, "(1)"
+       line 422, "pan.___", state 1746, "(1)"
+       line 426, "pan.___", state 1759, "(1)"
+       line 396, "pan.___", state 1780, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1794, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 1812, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 1826, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 1845, "(1)"
+       line 417, "pan.___", state 1858, "(1)"
+       line 422, "pan.___", state 1875, "(1)"
+       line 426, "pan.___", state 1888, "(1)"
+       line 396, "pan.___", state 1912, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1928, "(1)"
+       line 405, "pan.___", state 1944, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 1958, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 1977, "(1)"
+       line 422, "pan.___", state 2007, "(1)"
+       line 426, "pan.___", state 2020, "(1)"
+       line 624, "pan.___", state 2041, "_proc_urcu_reader = (_proc_urcu_reader|((1<<2)<<19))"
+       line 396, "pan.___", state 2048, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 2080, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 2094, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 2113, "(1)"
+       line 422, "pan.___", state 2143, "(1)"
+       line 426, "pan.___", state 2156, "(1)"
+       line 396, "pan.___", state 2177, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 2209, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 2223, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 2242, "(1)"
+       line 422, "pan.___", state 2272, "(1)"
+       line 426, "pan.___", state 2285, "(1)"
+       line 396, "pan.___", state 2308, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 2310, "(1)"
+       line 396, "pan.___", state 2311, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 2311, "else"
+       line 396, "pan.___", state 2314, "(1)"
+       line 400, "pan.___", state 2322, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2324, "(1)"
+       line 400, "pan.___", state 2325, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 2325, "else"
+       line 400, "pan.___", state 2328, "(1)"
+       line 400, "pan.___", state 2329, "(1)"
+       line 400, "pan.___", state 2329, "(1)"
+       line 398, "pan.___", state 2334, "((i<1))"
+       line 398, "pan.___", state 2334, "((i>=1))"
+       line 405, "pan.___", state 2340, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 2342, "(1)"
+       line 405, "pan.___", state 2343, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 405, "pan.___", state 2343, "else"
+       line 405, "pan.___", state 2346, "(1)"
+       line 405, "pan.___", state 2347, "(1)"
+       line 405, "pan.___", state 2347, "(1)"
+       line 409, "pan.___", state 2354, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 2356, "(1)"
+       line 409, "pan.___", state 2357, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 409, "pan.___", state 2357, "else"
+       line 409, "pan.___", state 2360, "(1)"
+       line 409, "pan.___", state 2361, "(1)"
+       line 409, "pan.___", state 2361, "(1)"
+       line 407, "pan.___", state 2366, "((i<2))"
+       line 407, "pan.___", state 2366, "((i>=2))"
+       line 413, "pan.___", state 2373, "(1)"
+       line 413, "pan.___", state 2374, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 2374, "else"
+       line 413, "pan.___", state 2377, "(1)"
+       line 413, "pan.___", state 2378, "(1)"
+       line 413, "pan.___", state 2378, "(1)"
+       line 417, "pan.___", state 2386, "(1)"
+       line 417, "pan.___", state 2387, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 2387, "else"
+       line 417, "pan.___", state 2390, "(1)"
+       line 417, "pan.___", state 2391, "(1)"
+       line 417, "pan.___", state 2391, "(1)"
+       line 415, "pan.___", state 2396, "((i<1))"
+       line 415, "pan.___", state 2396, "((i>=1))"
+       line 422, "pan.___", state 2403, "(1)"
+       line 422, "pan.___", state 2404, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 422, "pan.___", state 2404, "else"
+       line 422, "pan.___", state 2407, "(1)"
+       line 422, "pan.___", state 2408, "(1)"
+       line 422, "pan.___", state 2408, "(1)"
+       line 426, "pan.___", state 2416, "(1)"
+       line 426, "pan.___", state 2417, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 426, "pan.___", state 2417, "else"
+       line 426, "pan.___", state 2420, "(1)"
+       line 426, "pan.___", state 2421, "(1)"
+       line 426, "pan.___", state 2421, "(1)"
+       line 424, "pan.___", state 2426, "((i<2))"
+       line 424, "pan.___", state 2426, "((i>=2))"
+       line 431, "pan.___", state 2430, "(1)"
+       line 431, "pan.___", state 2430, "(1)"
+       line 624, "pan.___", state 2433, "cached_urcu_active_readers.val[_pid] = (tmp+1)"
+       line 624, "pan.___", state 2434, "_proc_urcu_reader = (_proc_urcu_reader|(1<<23))"
+       line 624, "pan.___", state 2435, "(1)"
+       line 251, "pan.___", state 2439, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 255, "pan.___", state 2450, "(1)"
+       line 259, "pan.___", state 2461, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 263, "pan.___", state 2470, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 228, "pan.___", state 2486, "(1)"
+       line 232, "pan.___", state 2494, "(1)"
+       line 236, "pan.___", state 2506, "(1)"
+       line 240, "pan.___", state 2514, "(1)"
+       line 396, "pan.___", state 2532, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2546, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 2564, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 2578, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 2597, "(1)"
+       line 417, "pan.___", state 2610, "(1)"
+       line 422, "pan.___", state 2627, "(1)"
+       line 426, "pan.___", state 2640, "(1)"
+       line 251, "pan.___", state 2664, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 255, "pan.___", state 2673, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 259, "pan.___", state 2686, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 263, "pan.___", state 2695, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 228, "pan.___", state 2711, "(1)"
+       line 232, "pan.___", state 2719, "(1)"
+       line 236, "pan.___", state 2731, "(1)"
+       line 240, "pan.___", state 2739, "(1)"
+       line 396, "pan.___", state 2757, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2771, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 2789, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 2803, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 2822, "(1)"
+       line 417, "pan.___", state 2835, "(1)"
+       line 422, "pan.___", state 2852, "(1)"
+       line 426, "pan.___", state 2865, "(1)"
+       line 396, "pan.___", state 2886, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 2900, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 2918, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 2932, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 2951, "(1)"
+       line 417, "pan.___", state 2964, "(1)"
+       line 422, "pan.___", state 2981, "(1)"
+       line 426, "pan.___", state 2994, "(1)"
+       line 228, "pan.___", state 3027, "(1)"
+       line 236, "pan.___", state 3047, "(1)"
+       line 240, "pan.___", state 3055, "(1)"
+       line 228, "pan.___", state 3070, "(1)"
+       line 232, "pan.___", state 3078, "(1)"
+       line 236, "pan.___", state 3090, "(1)"
+       line 240, "pan.___", state 3098, "(1)"
+       line 878, "pan.___", state 3115, "-end-"
+       (318 of 3115 states)
+unreached in proctype urcu_writer
+       line 396, "pan.___", state 18, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 24, "(1)"
+       line 400, "pan.___", state 32, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 38, "(1)"
+       line 400, "pan.___", state 39, "(1)"
+       line 400, "pan.___", state 39, "(1)"
+       line 398, "pan.___", state 44, "((i<1))"
+       line 398, "pan.___", state 44, "((i>=1))"
+       line 405, "pan.___", state 50, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 56, "(1)"
+       line 405, "pan.___", state 57, "(1)"
+       line 405, "pan.___", state 57, "(1)"
+       line 409, "pan.___", state 64, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 70, "(1)"
+       line 409, "pan.___", state 71, "(1)"
+       line 409, "pan.___", state 71, "(1)"
+       line 407, "pan.___", state 76, "((i<2))"
+       line 407, "pan.___", state 76, "((i>=2))"
+       line 413, "pan.___", state 83, "(1)"
+       line 413, "pan.___", state 84, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 84, "else"
+       line 413, "pan.___", state 87, "(1)"
+       line 413, "pan.___", state 88, "(1)"
+       line 413, "pan.___", state 88, "(1)"
+       line 417, "pan.___", state 96, "(1)"
+       line 417, "pan.___", state 97, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 97, "else"
+       line 417, "pan.___", state 100, "(1)"
+       line 417, "pan.___", state 101, "(1)"
+       line 417, "pan.___", state 101, "(1)"
+       line 415, "pan.___", state 106, "((i<1))"
+       line 415, "pan.___", state 106, "((i>=1))"
+       line 422, "pan.___", state 113, "(1)"
+       line 422, "pan.___", state 114, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 422, "pan.___", state 114, "else"
+       line 422, "pan.___", state 117, "(1)"
+       line 422, "pan.___", state 118, "(1)"
+       line 422, "pan.___", state 118, "(1)"
+       line 426, "pan.___", state 126, "(1)"
+       line 426, "pan.___", state 127, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 426, "pan.___", state 127, "else"
+       line 426, "pan.___", state 130, "(1)"
+       line 426, "pan.___", state 131, "(1)"
+       line 426, "pan.___", state 131, "(1)"
+       line 424, "pan.___", state 136, "((i<2))"
+       line 424, "pan.___", state 136, "((i>=2))"
+       line 431, "pan.___", state 140, "(1)"
+       line 431, "pan.___", state 140, "(1)"
+       line 251, "pan.___", state 149, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 255, "pan.___", state 158, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 253, "pan.___", state 166, "((i<1))"
+       line 253, "pan.___", state 166, "((i>=1))"
+       line 259, "pan.___", state 171, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 1001, "pan.___", state 199, "old_data = cached_rcu_ptr.val[_pid]"
+       line 396, "pan.___", state 211, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 217, "(1)"
+       line 400, "pan.___", state 225, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 231, "(1)"
+       line 400, "pan.___", state 232, "(1)"
+       line 400, "pan.___", state 232, "(1)"
+       line 398, "pan.___", state 237, "((i<1))"
+       line 398, "pan.___", state 237, "((i>=1))"
+       line 405, "pan.___", state 243, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 249, "(1)"
+       line 405, "pan.___", state 250, "(1)"
+       line 405, "pan.___", state 250, "(1)"
+       line 409, "pan.___", state 257, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 263, "(1)"
+       line 409, "pan.___", state 264, "(1)"
+       line 409, "pan.___", state 264, "(1)"
+       line 407, "pan.___", state 269, "((i<2))"
+       line 407, "pan.___", state 269, "((i>=2))"
+       line 413, "pan.___", state 276, "(1)"
+       line 413, "pan.___", state 277, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 277, "else"
+       line 413, "pan.___", state 280, "(1)"
+       line 413, "pan.___", state 281, "(1)"
+       line 413, "pan.___", state 281, "(1)"
+       line 417, "pan.___", state 289, "(1)"
+       line 417, "pan.___", state 290, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 290, "else"
+       line 417, "pan.___", state 293, "(1)"
+       line 417, "pan.___", state 294, "(1)"
+       line 417, "pan.___", state 294, "(1)"
+       line 415, "pan.___", state 299, "((i<1))"
+       line 415, "pan.___", state 299, "((i>=1))"
+       line 422, "pan.___", state 306, "(1)"
+       line 422, "pan.___", state 307, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 422, "pan.___", state 307, "else"
+       line 422, "pan.___", state 310, "(1)"
+       line 422, "pan.___", state 311, "(1)"
+       line 422, "pan.___", state 311, "(1)"
+       line 426, "pan.___", state 319, "(1)"
+       line 426, "pan.___", state 320, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 426, "pan.___", state 320, "else"
+       line 426, "pan.___", state 323, "(1)"
+       line 426, "pan.___", state 324, "(1)"
+       line 426, "pan.___", state 324, "(1)"
+       line 424, "pan.___", state 329, "((i<2))"
+       line 424, "pan.___", state 329, "((i>=2))"
+       line 431, "pan.___", state 333, "(1)"
+       line 431, "pan.___", state 333, "(1)"
+       line 396, "pan.___", state 344, "(1)"
+       line 396, "pan.___", state 345, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 345, "else"
+       line 396, "pan.___", state 348, "(1)"
+       line 400, "pan.___", state 356, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 362, "(1)"
+       line 400, "pan.___", state 363, "(1)"
+       line 400, "pan.___", state 363, "(1)"
+       line 398, "pan.___", state 368, "((i<1))"
+       line 398, "pan.___", state 368, "((i>=1))"
+       line 405, "pan.___", state 374, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 380, "(1)"
+       line 405, "pan.___", state 381, "(1)"
+       line 405, "pan.___", state 381, "(1)"
+       line 409, "pan.___", state 388, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 394, "(1)"
+       line 409, "pan.___", state 395, "(1)"
+       line 409, "pan.___", state 395, "(1)"
+       line 407, "pan.___", state 400, "((i<2))"
+       line 407, "pan.___", state 400, "((i>=2))"
+       line 413, "pan.___", state 407, "(1)"
+       line 413, "pan.___", state 408, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 408, "else"
+       line 413, "pan.___", state 411, "(1)"
+       line 413, "pan.___", state 412, "(1)"
+       line 413, "pan.___", state 412, "(1)"
+       line 417, "pan.___", state 420, "(1)"
+       line 417, "pan.___", state 421, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 421, "else"
+       line 417, "pan.___", state 424, "(1)"
+       line 417, "pan.___", state 425, "(1)"
+       line 417, "pan.___", state 425, "(1)"
+       line 415, "pan.___", state 430, "((i<1))"
+       line 415, "pan.___", state 430, "((i>=1))"
+       line 422, "pan.___", state 437, "(1)"
+       line 422, "pan.___", state 438, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 422, "pan.___", state 438, "else"
+       line 422, "pan.___", state 441, "(1)"
+       line 422, "pan.___", state 442, "(1)"
+       line 422, "pan.___", state 442, "(1)"
+       line 426, "pan.___", state 450, "(1)"
+       line 426, "pan.___", state 451, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 426, "pan.___", state 451, "else"
+       line 426, "pan.___", state 454, "(1)"
+       line 426, "pan.___", state 455, "(1)"
+       line 426, "pan.___", state 455, "(1)"
+       line 424, "pan.___", state 460, "((i<2))"
+       line 424, "pan.___", state 460, "((i>=2))"
+       line 431, "pan.___", state 464, "(1)"
+       line 431, "pan.___", state 464, "(1)"
+       line 396, "pan.___", state 477, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 479, "(1)"
+       line 396, "pan.___", state 480, "((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid)))"
+       line 396, "pan.___", state 480, "else"
+       line 396, "pan.___", state 483, "(1)"
+       line 400, "pan.___", state 491, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 493, "(1)"
+       line 400, "pan.___", state 494, "((cache_dirty_urcu_active_readers.bitfield&(1<<_pid)))"
+       line 400, "pan.___", state 494, "else"
+       line 400, "pan.___", state 497, "(1)"
+       line 400, "pan.___", state 498, "(1)"
+       line 400, "pan.___", state 498, "(1)"
+       line 398, "pan.___", state 503, "((i<1))"
+       line 398, "pan.___", state 503, "((i>=1))"
+       line 405, "pan.___", state 509, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 511, "(1)"
+       line 405, "pan.___", state 512, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 405, "pan.___", state 512, "else"
+       line 405, "pan.___", state 515, "(1)"
+       line 405, "pan.___", state 516, "(1)"
+       line 405, "pan.___", state 516, "(1)"
+       line 409, "pan.___", state 523, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 525, "(1)"
+       line 409, "pan.___", state 526, "((cache_dirty_rcu_data[i].bitfield&(1<<_pid)))"
+       line 409, "pan.___", state 526, "else"
+       line 409, "pan.___", state 529, "(1)"
+       line 409, "pan.___", state 530, "(1)"
+       line 409, "pan.___", state 530, "(1)"
+       line 407, "pan.___", state 535, "((i<2))"
+       line 407, "pan.___", state 535, "((i>=2))"
+       line 413, "pan.___", state 542, "(1)"
+       line 413, "pan.___", state 543, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 543, "else"
+       line 413, "pan.___", state 546, "(1)"
+       line 413, "pan.___", state 547, "(1)"
+       line 413, "pan.___", state 547, "(1)"
+       line 417, "pan.___", state 555, "(1)"
+       line 417, "pan.___", state 556, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 556, "else"
+       line 417, "pan.___", state 559, "(1)"
+       line 417, "pan.___", state 560, "(1)"
+       line 417, "pan.___", state 560, "(1)"
+       line 415, "pan.___", state 565, "((i<1))"
+       line 415, "pan.___", state 565, "((i>=1))"
+       line 422, "pan.___", state 572, "(1)"
+       line 422, "pan.___", state 573, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 422, "pan.___", state 573, "else"
+       line 422, "pan.___", state 576, "(1)"
+       line 422, "pan.___", state 577, "(1)"
+       line 422, "pan.___", state 577, "(1)"
+       line 426, "pan.___", state 585, "(1)"
+       line 426, "pan.___", state 586, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 426, "pan.___", state 586, "else"
+       line 426, "pan.___", state 589, "(1)"
+       line 426, "pan.___", state 590, "(1)"
+       line 426, "pan.___", state 590, "(1)"
+       line 431, "pan.___", state 599, "(1)"
+       line 431, "pan.___", state 599, "(1)"
+       line 396, "pan.___", state 605, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 611, "(1)"
+       line 400, "pan.___", state 619, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 625, "(1)"
+       line 400, "pan.___", state 626, "(1)"
+       line 400, "pan.___", state 626, "(1)"
+       line 398, "pan.___", state 631, "((i<1))"
+       line 398, "pan.___", state 631, "((i>=1))"
+       line 405, "pan.___", state 637, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 643, "(1)"
+       line 405, "pan.___", state 644, "(1)"
+       line 405, "pan.___", state 644, "(1)"
+       line 409, "pan.___", state 651, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 657, "(1)"
+       line 409, "pan.___", state 658, "(1)"
+       line 409, "pan.___", state 658, "(1)"
+       line 407, "pan.___", state 663, "((i<2))"
+       line 407, "pan.___", state 663, "((i>=2))"
+       line 413, "pan.___", state 670, "(1)"
+       line 413, "pan.___", state 671, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 671, "else"
+       line 413, "pan.___", state 674, "(1)"
+       line 413, "pan.___", state 675, "(1)"
+       line 413, "pan.___", state 675, "(1)"
+       line 417, "pan.___", state 683, "(1)"
+       line 417, "pan.___", state 684, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 684, "else"
+       line 417, "pan.___", state 687, "(1)"
+       line 417, "pan.___", state 688, "(1)"
+       line 417, "pan.___", state 688, "(1)"
+       line 415, "pan.___", state 693, "((i<1))"
+       line 415, "pan.___", state 693, "((i>=1))"
+       line 422, "pan.___", state 700, "(1)"
+       line 422, "pan.___", state 701, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 422, "pan.___", state 701, "else"
+       line 422, "pan.___", state 704, "(1)"
+       line 422, "pan.___", state 705, "(1)"
+       line 422, "pan.___", state 705, "(1)"
+       line 426, "pan.___", state 713, "(1)"
+       line 426, "pan.___", state 714, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 426, "pan.___", state 714, "else"
+       line 426, "pan.___", state 717, "(1)"
+       line 426, "pan.___", state 718, "(1)"
+       line 426, "pan.___", state 718, "(1)"
+       line 431, "pan.___", state 727, "(1)"
+       line 431, "pan.___", state 727, "(1)"
+       line 396, "pan.___", state 734, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 396, "pan.___", state 740, "(1)"
+       line 400, "pan.___", state 748, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 754, "(1)"
+       line 400, "pan.___", state 755, "(1)"
+       line 400, "pan.___", state 755, "(1)"
+       line 398, "pan.___", state 760, "((i<1))"
+       line 398, "pan.___", state 760, "((i>=1))"
+       line 405, "pan.___", state 766, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 772, "(1)"
+       line 405, "pan.___", state 773, "(1)"
+       line 405, "pan.___", state 773, "(1)"
+       line 409, "pan.___", state 780, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 786, "(1)"
+       line 409, "pan.___", state 787, "(1)"
+       line 409, "pan.___", state 787, "(1)"
+       line 407, "pan.___", state 792, "((i<2))"
+       line 407, "pan.___", state 792, "((i>=2))"
+       line 413, "pan.___", state 799, "(1)"
+       line 413, "pan.___", state 800, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 413, "pan.___", state 800, "else"
+       line 413, "pan.___", state 803, "(1)"
+       line 413, "pan.___", state 804, "(1)"
+       line 413, "pan.___", state 804, "(1)"
+       line 417, "pan.___", state 812, "(1)"
+       line 417, "pan.___", state 813, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 417, "pan.___", state 813, "else"
+       line 417, "pan.___", state 816, "(1)"
+       line 417, "pan.___", state 817, "(1)"
+       line 417, "pan.___", state 817, "(1)"
+       line 415, "pan.___", state 822, "((i<1))"
+       line 415, "pan.___", state 822, "((i>=1))"
+       line 422, "pan.___", state 829, "(1)"
+       line 422, "pan.___", state 830, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 422, "pan.___", state 830, "else"
+       line 422, "pan.___", state 833, "(1)"
+       line 422, "pan.___", state 834, "(1)"
+       line 422, "pan.___", state 834, "(1)"
+       line 426, "pan.___", state 842, "(1)"
+       line 426, "pan.___", state 843, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 426, "pan.___", state 843, "else"
+       line 426, "pan.___", state 846, "(1)"
+       line 426, "pan.___", state 847, "(1)"
+       line 426, "pan.___", state 847, "(1)"
+       line 424, "pan.___", state 852, "((i<2))"
+       line 424, "pan.___", state 852, "((i>=2))"
+       line 431, "pan.___", state 856, "(1)"
+       line 431, "pan.___", state 856, "(1)"
+       line 400, "pan.___", state 879, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 897, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 911, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 417, "pan.___", state 943, "(1)"
+       line 422, "pan.___", state 960, "(1)"
+       line 426, "pan.___", state 973, "(1)"
+       line 396, "pan.___", state 999, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 400, "pan.___", state 1013, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 405, "pan.___", state 1031, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 409, "pan.___", state 1045, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 413, "pan.___", state 1064, "(1)"
+       line 417, "pan.___", state 1077, "(1)"
+       line 422, "pan.___", state 1094, "(1)"
+       line 426, "pan.___", state 1107, "(1)"
+       line 251, "pan.___", state 1153, "cache_dirty_urcu_gp_ctr.bitfield = (cache_dirty_urcu_gp_ctr.bitfield&~((1<<_pid)))"
+       line 255, "pan.___", state 1162, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 253, "pan.___", state 1170, "((i<1))"
+       line 253, "pan.___", state 1170, "((i>=1))"
+       line 259, "pan.___", state 1177, "(1)"
+       line 259, "pan.___", state 1178, "((cache_dirty_rcu_ptr.bitfield&(1<<_pid)))"
+       line 259, "pan.___", state 1178, "else"
+       line 263, "pan.___", state 1184, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 261, "pan.___", state 1192, "((i<2))"
+       line 261, "pan.___", state 1192, "((i>=2))"
+       line 228, "pan.___", state 1200, "(1)"
+       line 232, "pan.___", state 1208, "(1)"
+       line 232, "pan.___", state 1209, "(!((cache_dirty_urcu_active_readers.bitfield&(1<<_pid))))"
+       line 232, "pan.___", state 1209, "else"
+       line 230, "pan.___", state 1214, "((i<1))"
+       line 230, "pan.___", state 1214, "((i>=1))"
+       line 236, "pan.___", state 1220, "(1)"
+       line 236, "pan.___", state 1221, "(!((cache_dirty_rcu_ptr.bitfield&(1<<_pid))))"
+       line 236, "pan.___", state 1221, "else"
+       line 240, "pan.___", state 1228, "(1)"
+       line 240, "pan.___", state 1229, "(!((cache_dirty_rcu_data[i].bitfield&(1<<_pid))))"
+       line 240, "pan.___", state 1229, "else"
+       line 245, "pan.___", state 1238, "(!((cache_dirty_urcu_gp_ctr.bitfield&(1<<_pid))))"
+       line 245, "pan.___", state 1238, "else"
+       line 255, "pan.___", state 1253, "cache_dirty_urcu_active_readers.bitfield = (cache_dirty_urcu_active_readers.bitfield&~((1<<_pid)))"
+       line 259, "pan.___", state 1266, "cache_dirty_rcu_ptr.bitfield = (cache_dirty_rcu_ptr.bitfield&~((1<<_pid)))"
+       line 263, "pan.___", state 1275, "cache_dirty_rcu_data[i].bitfield = (cache_dirty_rcu_data[i].bitfield&~((1<<_pid)))"
+       line 228, "pan.___", state 1291, "(1)"
+       line 232, "pan.___", state 1299, "(1)"
+       line 236, "pan.___", state 1311, "(1)"
+       line 240, "pan.___", state 1319, "(1)"
+       line 1205, "pan.___", state 1334, "-end-"
+       (242 of 1334 states)
+unreached in proctype :init:
+       (0 of 78 states)
+unreached in proctype :never:
+       line 1266, "pan.___", state 11, "-end-"
+       (1 of 11 states)
+
+pan: elapsed time 24.3 seconds
+pan: rate 3201.8077 states/second
+pan: avg transition delay 1.3309e-06 usec
+cp .input.spin urcu_progress_writer_error.spin.input
+cp .input.spin.trail urcu_progress_writer_error.spin.input.trail
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu_progress_writer_error.spin.input b/formal-model/results/urcu-controldataflow-no-ipi/urcu_progress_writer_error.spin.input
new file mode 100644 (file)
index 0000000..ea022e9
--- /dev/null
@@ -0,0 +1,1241 @@
+#define WRITER_PROGRESS
+#define GEN_ERROR_WRITER_PROGRESS
+
+// Poison value for freed memory
+#define POISON 1
+// Memory with correct data
+#define WINE 0
+#define SLAB_SIZE 2
+
+#define read_poison    (data_read_first[0] == POISON || data_read_second[0] == POISON)
+
+#define RCU_GP_CTR_BIT (1 << 7)
+#define RCU_GP_CTR_NEST_MASK (RCU_GP_CTR_BIT - 1)
+
+//disabled
+//#define REMOTE_BARRIERS
+/*
+ * mem.spin: Promela code to validate memory barriers with OOO memory
+ * and out-of-order instruction scheduling.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (c) 2009 Mathieu Desnoyers
+ */
+
+/* Promela validation variables. */
+
+/* specific defines "included" here */
+/* DEFINES file "included" here */
+
+#define NR_READERS 1
+#define NR_WRITERS 1
+
+#define NR_PROCS 2
+
+#define get_pid()      (_pid)
+
+#define get_readerid() (get_pid())
+
+/*
+ * Produced process control and data flow. Updated after each instruction to
+ * show which variables are ready. Using one-hot bit encoding per variable to
+ * save state space. Used as triggers to execute the instructions having those
+ * variables as input. Leaving bits active to inhibit instruction execution.
+ * Scheme used to make instruction disabling and automatic dependency fall-back
+ * automatic.
+ */
+
+#define CONSUME_TOKENS(state, bits, notbits)                   \
+       ((!(state & (notbits))) && (state & (bits)) == (bits))
+
+#define PRODUCE_TOKENS(state, bits)                            \
+       state = state | (bits);
+
+#define CLEAR_TOKENS(state, bits)                              \
+       state = state & ~(bits)
+
+/*
+ * Types of dependency :
+ *
+ * Data dependency
+ *
+ * - True dependency, Read-after-Write (RAW)
+ *
+ * This type of dependency happens when a statement depends on the result of a
+ * previous statement. This applies to any statement which needs to read a
+ * variable written by a preceding statement.
+ *
+ * - False dependency, Write-after-Read (WAR)
+ *
+ * Typically, variable renaming can ensure that this dependency goes away.
+ * However, if the statements must read and then write from/to the same variable
+ * in the OOO memory model, renaming may be impossible, and therefore this
+ * causes a WAR dependency.
+ *
+ * - Output dependency, Write-after-Write (WAW)
+ *
+ * Two writes to the same variable in subsequent statements. Variable renaming
+ * can ensure this is not needed, but can be required when writing multiple
+ * times to the same OOO mem model variable.
+ *
+ * Control dependency
+ *
+ * Execution of a given instruction depends on a previous instruction evaluating
+ * in a way that allows its execution. E.g. : branches.
+ *
+ * Useful considerations for joining dependencies after branch
+ *
+ * - Pre-dominance
+ *
+ * "We say box i dominates box j if every path (leading from input to output
+ * through the diagram) which passes through box j must also pass through box
+ * i. Thus box i dominates box j if box j is subordinate to box i in the
+ * program."
+ *
+ * http://www.hipersoft.rice.edu/grads/publications/dom14.pdf
+ * Other classic algorithm to calculate dominance : Lengauer-Tarjan (in gcc)
+ *
+ * - Post-dominance
+ *
+ * Just as pre-dominance, but with arcs of the data flow inverted, and input vs
+ * output exchanged. Therefore, i post-dominating j ensures that every path
+ * passing by j will pass by i before reaching the output.
+ *
+ * Other considerations
+ *
+ * Note about "volatile" keyword dependency : The compiler will order volatile
+ * accesses so they appear in the right order on a given CPU. They can be
+ * reordered by the CPU instruction scheduling. This therefore cannot be
+ * considered as a depencency.
+ *
+ * References :
+ *
+ * Cooper, Keith D.; & Torczon, Linda. (2005). Engineering a Compiler. Morgan
+ * Kaufmann. ISBN 1-55860-698-X. 
+ * Kennedy, Ken; & Allen, Randy. (2001). Optimizing Compilers for Modern
+ * Architectures: A Dependence-based Approach. Morgan Kaufmann. ISBN
+ * 1-55860-286-0. 
+ * Muchnick, Steven S. (1997). Advanced Compiler Design and Implementation.
+ * Morgan Kaufmann. ISBN 1-55860-320-4.
+ */
+
+/*
+ * Note about loops and nested calls
+ *
+ * To keep this model simple, loops expressed in the framework will behave as if
+ * there was a core synchronizing instruction between loops. To see the effect
+ * of loop unrolling, manually unrolling loops is required. Note that if loops
+ * end or start with a core synchronizing instruction, the model is appropriate.
+ * Nested calls are not supported.
+ */
+
+/*
+ * 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
+ * both.
+ */
+
+typedef per_proc_byte {
+       byte val[NR_PROCS];
+};
+
+typedef per_proc_bit {
+       bit val[NR_PROCS];
+};
+
+/* Bitfield has a maximum of 8 procs */
+typedef per_proc_bitfield {
+       byte bitfield;
+};
+
+#define DECLARE_CACHED_VAR(type, x)    \
+       type mem_##x;                   \
+       per_proc_##type cached_##x;     \
+       per_proc_bitfield cache_dirty_##x;
+
+#define INIT_CACHED_VAR(x, v, j)       \
+       mem_##x = v;                    \
+       cache_dirty_##x.bitfield = 0;   \
+       j = 0;                          \
+       do                              \
+       :: j < NR_PROCS ->              \
+               cached_##x.val[j] = v;  \
+               j++                     \
+       :: j >= NR_PROCS -> break       \
+       od;
+
+#define IS_CACHE_DIRTY(x, id)  (cache_dirty_##x.bitfield & (1 << id))
+
+#define READ_CACHED_VAR(x)     (cached_##x.val[get_pid()])
+
+#define WRITE_CACHED_VAR(x, v)                         \
+       atomic {                                        \
+               cached_##x.val[get_pid()] = v;          \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield | (1 << get_pid());    \
+       }
+
+#define CACHE_WRITE_TO_MEM(x, id)                      \
+       if                                              \
+       :: IS_CACHE_DIRTY(x, id) ->                     \
+               mem_##x = cached_##x.val[id];           \
+               cache_dirty_##x.bitfield =              \
+                       cache_dirty_##x.bitfield & (~(1 << id));        \
+       :: else ->                                      \
+               skip                                    \
+       fi;
+
+#define CACHE_READ_FROM_MEM(x, id)     \
+       if                              \
+       :: !IS_CACHE_DIRTY(x, id) ->    \
+               cached_##x.val[id] = mem_##x;\
+       :: else ->                      \
+               skip                    \
+       fi;
+
+/*
+ * May update other caches if cache is dirty, or not.
+ */
+#define RANDOM_CACHE_WRITE_TO_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_WRITE_TO_MEM(x, id);      \
+       :: 1 -> skip                    \
+       fi;
+
+#define RANDOM_CACHE_READ_FROM_MEM(x, id)\
+       if                              \
+       :: 1 -> CACHE_READ_FROM_MEM(x, id);     \
+       :: 1 -> skip                    \
+       fi;
+
+/* Must consume all prior read tokens. All subsequent reads depend on it. */
+inline smp_rmb(i, j)
+{
+       atomic {
+               CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_READ_FROM_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Must consume all prior write tokens. All subsequent writes depend on it. */
+inline smp_wmb(i, j)
+{
+       atomic {
+               CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       CACHE_WRITE_TO_MEM(urcu_active_readers[i], get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/* Synchronization point. Must consume all prior read and write tokens. All
+ * subsequent reads and writes depend on it. */
+inline smp_mb(i, j)
+{
+       atomic {
+               smp_wmb(i, j);
+               smp_rmb(i, j);
+       }
+}
+
+#ifdef REMOTE_BARRIERS
+
+bit reader_barrier[NR_READERS];
+
+/*
+ * We cannot leave the barriers dependencies in place in REMOTE_BARRIERS mode
+ * because they would add unexisting core synchronization and would therefore
+ * create an incomplete model.
+ * Therefore, we model the read-side memory barriers by completely disabling the
+ * memory barriers and their dependencies from the read-side. One at a time
+ * (different verification runs), we make a different instruction listen for
+ * signals.
+ */
+
+#define smp_mb_reader(i, j)
+
+/*
+ * Service 0, 1 or many barrier requests.
+ */
+inline smp_mb_recv(i, j)
+{
+       do
+       :: (reader_barrier[get_readerid()] == 1) ->
+               /*
+                * 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, j);
+               reader_barrier[get_readerid()] = 0;
+       :: 1 ->
+               /*
+                * 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)
+//#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);                                                           \
+       i = 0;                                                                  \
+       do                                                                      \
+       :: i < NR_READERS ->                                                    \
+               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.                                            \
+                */                                                             \
+               do                                                              \
+               :: (reader_barrier[i] == 1) ->                                  \
+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(i, j, progressid)  smp_mb(i, j)
+#define smp_mb_reader  smp_mb
+#define smp_mb_recv(i, j)
+
+#endif
+
+/* Keep in sync manually with smp_rmb, smp_wmb, ooo_mem and init() */
+DECLARE_CACHED_VAR(byte, urcu_gp_ctr);
+/* Note ! currently only one reader */
+DECLARE_CACHED_VAR(byte, urcu_active_readers[NR_READERS]);
+/* RCU data */
+DECLARE_CACHED_VAR(bit, rcu_data[SLAB_SIZE]);
+
+/* RCU pointer */
+#if (SLAB_SIZE == 2)
+DECLARE_CACHED_VAR(bit, rcu_ptr);
+bit ptr_read_first[NR_READERS];
+bit ptr_read_second[NR_READERS];
+#else
+DECLARE_CACHED_VAR(byte, rcu_ptr);
+byte ptr_read_first[NR_READERS];
+byte ptr_read_second[NR_READERS];
+#endif
+
+bit data_read_first[NR_READERS];
+bit data_read_second[NR_READERS];
+
+bit init_done = 0;
+
+inline wait_init_done()
+{
+       do
+       :: init_done == 0 -> skip;
+       :: else -> break;
+       od;
+}
+
+inline ooo_mem(i)
+{
+       atomic {
+               RANDOM_CACHE_WRITE_TO_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_WRITE_TO_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_WRITE_TO_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_WRITE_TO_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(urcu_gp_ctr, get_pid());
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       RANDOM_CACHE_READ_FROM_MEM(urcu_active_readers[i],
+                               get_pid());
+                       i++
+               :: i >= NR_READERS -> break
+               od;
+               RANDOM_CACHE_READ_FROM_MEM(rcu_ptr, get_pid());
+               i = 0;
+               do
+               :: i < SLAB_SIZE ->
+                       RANDOM_CACHE_READ_FROM_MEM(rcu_data[i], get_pid());
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+       }
+}
+
+/*
+ * Bit encoding, urcu_reader :
+ */
+
+int _proc_urcu_reader;
+#define proc_urcu_reader       _proc_urcu_reader
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROD_A_READ               (1 << 0)
+#define READ_PROD_B_IF_TRUE            (1 << 1)
+#define READ_PROD_B_IF_FALSE           (1 << 2)
+#define READ_PROD_C_IF_TRUE_READ       (1 << 3)
+
+#define PROCEDURE_READ_LOCK(base, consumetoken, producetoken)                          \
+       :: CONSUME_TOKENS(proc_urcu_reader, consumetoken, READ_PROD_A_READ << base) ->  \
+               ooo_mem(i);                                                             \
+               tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);             \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_A_READ << base);             \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         READ_PROD_A_READ << base,             /* RAW, pre-dominant */ \
+                         (READ_PROD_B_IF_TRUE | READ_PROD_B_IF_FALSE) << base) ->      \
+               if                                                                      \
+               :: (!(tmp & RCU_GP_CTR_NEST_MASK)) ->                                   \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base);  \
+               :: else ->                                                              \
+                       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_B_IF_FALSE << base); \
+               fi;                                                                     \
+       /* IF TRUE */                                                                   \
+       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_B_IF_TRUE << base,                \
+                         READ_PROD_C_IF_TRUE_READ << base) ->                          \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_gp_ctr);                                    \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_C_IF_TRUE_READ << base);     \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_C_IF_TRUE_READ     /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2);            \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ELSE */                                                                      \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         (READ_PROD_B_IF_FALSE         /* pre-dominant */              \
+                         | READ_PROD_A_READ) << base,          /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()],                   \
+                                tmp + 1);                                              \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+                                                       /* IF_MERGE implies             \
+                                                        * post-dominance */            \
+       /* ENDIF */                                                                     \
+       skip
+
+/* Body of PROCEDURE_READ_LOCK */
+#define READ_PROC_READ_UNLOCK          (1 << 0)
+
+#define PROCEDURE_READ_UNLOCK(base, consumetoken, producetoken)                                \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken,                                                 \
+                         READ_PROC_READ_UNLOCK << base) ->                             \
+               ooo_mem(i);                                                             \
+               tmp2 = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);            \
+               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_UNLOCK << base);        \
+       :: CONSUME_TOKENS(proc_urcu_reader,                                             \
+                         consumetoken                                                  \
+                         | (READ_PROC_READ_UNLOCK << base),    /* WAR */               \
+                         producetoken) ->                                              \
+               ooo_mem(i);                                                             \
+               WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1);        \
+               PRODUCE_TOKENS(proc_urcu_reader, producetoken);                         \
+       skip
+
+
+#define READ_PROD_NONE                 (1 << 0)
+
+/* PROCEDURE_READ_LOCK base = << 1 : 1 to 5 */
+#define READ_LOCK_BASE                 1
+#define READ_LOCK_OUT                  (1 << 5)
+
+#define READ_PROC_FIRST_MB             (1 << 6)
+
+/* PROCEDURE_READ_LOCK (NESTED) base : << 7 : 7 to 11 */
+#define READ_LOCK_NESTED_BASE          7
+#define READ_LOCK_NESTED_OUT           (1 << 11)
+
+#define READ_PROC_READ_GEN             (1 << 12)
+#define READ_PROC_ACCESS_GEN           (1 << 13)
+
+/* PROCEDURE_READ_UNLOCK (NESTED) base = << 14 : 14 to 15 */
+#define READ_UNLOCK_NESTED_BASE                14
+#define READ_UNLOCK_NESTED_OUT         (1 << 15)
+
+#define READ_PROC_SECOND_MB            (1 << 16)
+
+/* PROCEDURE_READ_UNLOCK base = << 17 : 17 to 18 */
+#define READ_UNLOCK_BASE               17
+#define READ_UNLOCK_OUT                        (1 << 18)
+
+/* PROCEDURE_READ_LOCK_UNROLL base = << 19 : 19 to 23 */
+#define READ_LOCK_UNROLL_BASE          19
+#define READ_LOCK_OUT_UNROLL           (1 << 23)
+
+#define READ_PROC_THIRD_MB             (1 << 24)
+
+#define READ_PROC_READ_GEN_UNROLL      (1 << 25)
+#define READ_PROC_ACCESS_GEN_UNROLL    (1 << 26)
+
+#define READ_PROC_FOURTH_MB            (1 << 27)
+
+/* PROCEDURE_READ_UNLOCK_UNROLL base = << 28 : 28 to 29 */
+#define READ_UNLOCK_UNROLL_BASE                28
+#define READ_UNLOCK_OUT_UNROLL         (1 << 29)
+
+
+/* Should not include branches */
+#define READ_PROC_ALL_TOKENS           (READ_PROD_NONE                 \
+                                       | READ_LOCK_OUT                 \
+                                       | READ_PROC_FIRST_MB            \
+                                       | READ_LOCK_NESTED_OUT          \
+                                       | READ_PROC_READ_GEN            \
+                                       | READ_PROC_ACCESS_GEN          \
+                                       | READ_UNLOCK_NESTED_OUT        \
+                                       | READ_PROC_SECOND_MB           \
+                                       | READ_UNLOCK_OUT               \
+                                       | READ_LOCK_OUT_UNROLL          \
+                                       | READ_PROC_THIRD_MB            \
+                                       | READ_PROC_READ_GEN_UNROLL     \
+                                       | READ_PROC_ACCESS_GEN_UNROLL   \
+                                       | READ_PROC_FOURTH_MB           \
+                                       | READ_UNLOCK_OUT_UNROLL)
+
+/* Must clear all tokens, including branches */
+#define READ_PROC_ALL_TOKENS_CLEAR     ((1 << 30) - 1)
+
+inline urcu_one_read(i, j, nest_i, tmp, tmp2)
+{
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROD_NONE);
+
+#ifdef NO_MB
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+#ifdef REMOTE_BARRIERS
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+       PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+#endif
+
+       do
+       :: 1 ->
+
+#ifdef REMOTE_BARRIERS
+               /*
+                * Signal-based memory barrier will only execute when the
+                * execution order appears in program order.
+                */
+               if
+               :: 1 ->
+                       atomic {
+                               if
+                               :: CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE,
+                                               READ_LOCK_OUT | READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT,
+                                               READ_LOCK_NESTED_OUT
+                                               | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT | READ_LOCK_NESTED_OUT,
+                                               READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN,
+                                               READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN,
+                                               READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT,
+                                               READ_UNLOCK_OUT
+                                               | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT,
+                                               READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL,
+                                               READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL,
+                                               READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN
+                                               | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL,
+                                               READ_UNLOCK_OUT_UNROLL)
+                                       || CONSUME_TOKENS(proc_urcu_reader, READ_PROD_NONE | READ_LOCK_OUT
+                                               | READ_LOCK_NESTED_OUT | READ_PROC_READ_GEN | READ_PROC_ACCESS_GEN | READ_UNLOCK_NESTED_OUT
+                                               | READ_UNLOCK_OUT | READ_LOCK_OUT_UNROLL
+                                               | READ_PROC_READ_GEN_UNROLL | READ_PROC_ACCESS_GEN_UNROLL | READ_UNLOCK_OUT_UNROLL,
+                                               0) ->
+                                       goto non_atomic3;
+non_atomic3_end:
+                                       skip;
+                               fi;
+                       }
+               fi;
+
+               goto non_atomic3_skip;
+non_atomic3:
+               smp_mb_recv(i, j);
+               goto non_atomic3_end;
+non_atomic3_skip:
+
+#endif /* REMOTE_BARRIERS */
+
+               atomic {
+                       if
+                       PROCEDURE_READ_LOCK(READ_LOCK_BASE, READ_PROD_NONE, READ_LOCK_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_LOCK_OUT,                /* post-dominant */
+                                         READ_PROC_FIRST_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FIRST_MB);
+
+                       PROCEDURE_READ_LOCK(READ_LOCK_NESTED_BASE, READ_PROC_FIRST_MB | READ_LOCK_OUT,
+                                           READ_LOCK_NESTED_OUT);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB,           /* mb() orders reads */
+                                         READ_PROC_READ_GEN) ->
+                               ooo_mem(i);
+                               ptr_read_first[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_READ_GEN,
+                                         READ_PROC_ACCESS_GEN) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb1;
+rmb1_end:
+                               data_read_first[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_first[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN);
+
+
+                       /* Note : we remove the nested memory barrier from the read unlock
+                        * model, given it is not usually needed. The implementation has the barrier
+                        * because the performance impact added by a branch in the common case does not
+                        * justify it.
+                        */
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_NESTED_BASE,
+                                             READ_PROC_FIRST_MB
+                                             | READ_LOCK_OUT
+                                             | READ_LOCK_NESTED_OUT,
+                                             READ_UNLOCK_NESTED_OUT);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_ACCESS_GEN          /* mb() orders reads */
+                                         | READ_PROC_READ_GEN          /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT               /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT        /* post-dominant */
+                                         | READ_UNLOCK_NESTED_OUT,
+                                         READ_PROC_SECOND_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_SECOND_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_BASE,
+                                             READ_PROC_SECOND_MB       /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT);
+
+                       /* Unrolling loop : second consecutive lock */
+                       /* reading urcu_active_readers, which have been written by
+                        * READ_UNLOCK_OUT : RAW */
+                       PROCEDURE_READ_LOCK(READ_LOCK_UNROLL_BASE,
+                                           READ_UNLOCK_OUT             /* RAW */
+                                           | READ_PROC_SECOND_MB       /* mb() orders reads */
+                                           | READ_PROC_FIRST_MB        /* mb() orders reads */
+                                           | READ_LOCK_NESTED_OUT      /* RAW */
+                                           | READ_LOCK_OUT             /* RAW */
+                                           | READ_UNLOCK_NESTED_OUT,   /* RAW */
+                                           READ_LOCK_OUT_UNROLL);
+
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_THIRD_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_THIRD_MB);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_FIRST_MB            /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_READ_GEN_UNROLL) ->
+                               ooo_mem(i);
+                               ptr_read_second[get_readerid()] = READ_CACHED_VAR(rcu_ptr);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_READ_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL
+                                         | READ_PROC_FIRST_MB          /* mb() orders reads */
+                                         | READ_PROC_SECOND_MB         /* mb() orders reads */
+                                         | READ_PROC_THIRD_MB,         /* mb() orders reads */
+                                         READ_PROC_ACCESS_GEN_UNROLL) ->
+                               /* smp_read_barrier_depends */
+                               goto rmb2;
+rmb2_end:
+                               data_read_second[get_readerid()] =
+                                       READ_CACHED_VAR(rcu_data[ptr_read_second[get_readerid()]]);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_ACCESS_GEN_UNROLL);
+
+                       :: CONSUME_TOKENS(proc_urcu_reader,
+                                         READ_PROC_READ_GEN_UNROLL     /* mb() orders reads */
+                                         | READ_PROC_ACCESS_GEN_UNROLL /* mb() orders reads */
+                                         | READ_PROC_FIRST_MB          /* mb() ordered */
+                                         | READ_PROC_SECOND_MB         /* mb() ordered */
+                                         | READ_PROC_THIRD_MB          /* mb() ordered */
+                                         | READ_LOCK_OUT_UNROLL        /* post-dominant */
+                                         | READ_LOCK_NESTED_OUT
+                                         | READ_LOCK_OUT
+                                         | READ_UNLOCK_NESTED_OUT
+                                         | READ_UNLOCK_OUT,
+                                         READ_PROC_FOURTH_MB) ->
+                               smp_mb_reader(i, j);
+                               PRODUCE_TOKENS(proc_urcu_reader, READ_PROC_FOURTH_MB);
+
+                       PROCEDURE_READ_UNLOCK(READ_UNLOCK_UNROLL_BASE,
+                                             READ_PROC_FOURTH_MB       /* mb() orders reads */
+                                             | READ_PROC_THIRD_MB      /* mb() orders reads */
+                                             | READ_LOCK_OUT_UNROLL    /* RAW */
+                                             | READ_PROC_SECOND_MB     /* mb() orders reads */
+                                             | READ_PROC_FIRST_MB      /* mb() orders reads */
+                                             | READ_LOCK_NESTED_OUT    /* RAW */
+                                             | READ_LOCK_OUT           /* RAW */
+                                             | READ_UNLOCK_NESTED_OUT, /* RAW */
+                                             READ_UNLOCK_OUT_UNROLL);
+                       :: CONSUME_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS, 0) ->
+                               CLEAR_TOKENS(proc_urcu_reader, READ_PROC_ALL_TOKENS_CLEAR);
+                               break;
+                       fi;
+               }
+       od;
+       /*
+        * Dependency between consecutive loops :
+        * RAW dependency on 
+        * WRITE_CACHED_VAR(urcu_active_readers[get_readerid()], tmp2 - 1)
+        * tmp = READ_CACHED_VAR(urcu_active_readers[get_readerid()]);
+        * between loops.
+        * _WHEN THE MB()s are in place_, they add full ordering of the
+        * generation pointer read wrt active reader count read, which ensures
+        * execution will not spill across loop execution.
+        * However, in the event mb()s are removed (execution using signal
+        * handler to promote barrier()() -> smp_mb()), nothing prevents one loop
+        * to spill its execution on other loop's execution.
+        */
+       goto end;
+rmb1:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb1_end;
+rmb2:
+#ifndef NO_RMB
+       smp_rmb(i, j);
+#else
+       ooo_mem(i);
+#endif
+       goto rmb2_end;
+end:
+       skip;
+}
+
+
+
+active proctype urcu_reader()
+{
+       byte i, j, nest_i;
+       byte tmp, tmp2;
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+end_reader:
+       do
+       :: 1 ->
+               /*
+                * We do not test reader's progress here, because we are mainly
+                * interested in writer's progress. The reader never blocks
+                * anyway. We have to test for reader/writer's progress
+                * separately, otherwise we could think the writer is doing
+                * progress when it's blocked by an always progressing reader.
+                */
+#ifdef READER_PROGRESS
+progress_reader:
+#endif
+               urcu_one_read(i, j, nest_i, tmp, tmp2);
+       od;
+}
+
+/* no name clash please */
+#undef proc_urcu_reader
+
+
+/* Model the RCU update process. */
+
+/*
+ * Bit encoding, urcu_writer :
+ * Currently only supports one reader.
+ */
+
+int _proc_urcu_writer;
+#define proc_urcu_writer       _proc_urcu_writer
+
+#define WRITE_PROD_NONE                        (1 << 0)
+
+#define WRITE_DATA                     (1 << 1)
+#define WRITE_PROC_WMB                 (1 << 2)
+#define WRITE_XCHG_PTR                 (1 << 3)
+
+#define WRITE_PROC_FIRST_MB            (1 << 4)
+
+/* first flip */
+#define WRITE_PROC_FIRST_READ_GP       (1 << 5)
+#define WRITE_PROC_FIRST_WRITE_GP      (1 << 6)
+#define WRITE_PROC_FIRST_WAIT          (1 << 7)
+#define WRITE_PROC_FIRST_WAIT_LOOP     (1 << 8)
+
+/* second flip */
+#define WRITE_PROC_SECOND_READ_GP      (1 << 9)
+#define WRITE_PROC_SECOND_WRITE_GP     (1 << 10)
+#define WRITE_PROC_SECOND_WAIT         (1 << 11)
+#define WRITE_PROC_SECOND_WAIT_LOOP    (1 << 12)
+
+#define WRITE_PROC_SECOND_MB           (1 << 13)
+
+#define WRITE_FREE                     (1 << 14)
+
+#define WRITE_PROC_ALL_TOKENS          (WRITE_PROD_NONE                \
+                                       | WRITE_DATA                    \
+                                       | WRITE_PROC_WMB                \
+                                       | WRITE_XCHG_PTR                \
+                                       | WRITE_PROC_FIRST_MB           \
+                                       | WRITE_PROC_FIRST_READ_GP      \
+                                       | WRITE_PROC_FIRST_WRITE_GP     \
+                                       | WRITE_PROC_FIRST_WAIT         \
+                                       | WRITE_PROC_SECOND_READ_GP     \
+                                       | WRITE_PROC_SECOND_WRITE_GP    \
+                                       | WRITE_PROC_SECOND_WAIT        \
+                                       | WRITE_PROC_SECOND_MB          \
+                                       | WRITE_FREE)
+
+#define WRITE_PROC_ALL_TOKENS_CLEAR    ((1 << 15) - 1)
+
+/*
+ * Mutexes are implied around writer execution. A single writer at a time.
+ */
+active proctype urcu_writer()
+{
+       byte i, j;
+       byte tmp, tmp2, tmpa;
+       byte cur_data = 0, old_data, loop_nr = 0;
+       byte cur_gp_val = 0;    /*
+                                * Keep a local trace of the current parity so
+                                * we don't add non-existing dependencies on the global
+                                * GP update. Needed to test single flip case.
+                                */
+
+       wait_init_done();
+
+       assert(get_pid() < NR_PROCS);
+
+       do
+       :: (loop_nr < 3) ->
+#ifdef WRITER_PROGRESS
+progress_writer1:
+#endif
+               loop_nr = loop_nr + 1;
+
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROD_NONE);
+
+#ifdef NO_WMB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+#endif
+
+#ifdef NO_MB
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+#endif
+
+#ifdef SINGLE_FLIP
+               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 ->
+               atomic {
+               if
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROD_NONE,
+                                 WRITE_DATA) ->
+                       ooo_mem(i);
+                       cur_data = (cur_data + 1) % SLAB_SIZE;
+                       WRITE_CACHED_VAR(rcu_data[cur_data], WINE);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_DATA);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA,
+                                 WRITE_PROC_WMB) ->
+                       smp_wmb(i, j);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_WMB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_WMB,
+                                 WRITE_XCHG_PTR) ->
+                       /* rcu_xchg_pointer() */
+                       atomic {
+                               old_data = READ_CACHED_VAR(rcu_ptr);
+                               WRITE_CACHED_VAR(rcu_ptr, cur_data);
+                       }
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_XCHG_PTR);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR,
+                                 WRITE_PROC_FIRST_MB) ->
+                       goto smp_mb_send1;
+smp_mb_send1_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_MB);
+
+               /* first flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_FIRST_READ_GP) ->
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP,
+                                 WRITE_PROC_FIRST_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_MB,  /* can be reordered before/after flips */
+                                 WRITE_PROC_FIRST_WAIT | WRITE_PROC_FIRST_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+#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) ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP);
+                       :: else ->
+                               PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send2;
+smp_mb_send2_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_FIRST_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_FIRST_WAIT_LOOP | WRITE_PROC_FIRST_WAIT);
+
+               /* second flip */
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT         /* Control dependency : need to branch out of
+                                                                * the loop to execute the next flip (CHECK) */
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_READ_GP) ->
+                       ooo_mem(i);
+                       tmpa = READ_CACHED_VAR(urcu_gp_ctr);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_READ_GP);
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_MB
+                                 | WRITE_PROC_WMB
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP,
+                                 WRITE_PROC_SECOND_WRITE_GP) ->
+                       ooo_mem(i);
+                       WRITE_CACHED_VAR(urcu_gp_ctr, tmpa ^ RCU_GP_CTR_BIT);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WRITE_GP);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 WRITE_PROC_SECOND_WAIT | WRITE_PROC_SECOND_WAIT_LOOP) ->
+                       ooo_mem(i);
+                       /* ONLY WAITING FOR READER 0 */
+                       tmp2 = READ_CACHED_VAR(urcu_active_readers[0]);
+                       if
+                       :: (tmp2 & RCU_GP_CTR_NEST_MASK)
+                                       && ((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);
+                       fi;
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 //WRITE_PROC_FIRST_WRITE_GP   /* TEST ADDING SYNC CORE */
+                                 WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_WAIT_LOOP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,        /* can be reordered before/after flips */
+                                 0) ->
+#ifndef GEN_ERROR_WRITER_PROGRESS
+                       goto smp_mb_send3;
+smp_mb_send3_end:
+#else
+                       ooo_mem(i);
+#endif
+                       /* This instruction loops to WRITE_PROC_SECOND_WAIT */
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_WAIT_LOOP | WRITE_PROC_SECOND_WAIT);
+
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_FIRST_READ_GP
+                                 | WRITE_PROC_SECOND_READ_GP
+                                 | WRITE_PROC_FIRST_WRITE_GP
+                                 | WRITE_PROC_SECOND_WRITE_GP
+                                 | WRITE_DATA | WRITE_PROC_WMB | WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_PROC_SECOND_MB) ->
+                       goto smp_mb_send4;
+smp_mb_send4_end:
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_PROC_SECOND_MB);
+
+               :: CONSUME_TOKENS(proc_urcu_writer,
+                                 WRITE_XCHG_PTR
+                                 | WRITE_PROC_FIRST_WAIT
+                                 | WRITE_PROC_SECOND_WAIT
+                                 | WRITE_PROC_WMB      /* No dependency on
+                                                        * WRITE_DATA because we
+                                                        * write to a
+                                                        * different location. */
+                                 | WRITE_PROC_SECOND_MB
+                                 | WRITE_PROC_FIRST_MB,
+                                 WRITE_FREE) ->
+                       WRITE_CACHED_VAR(rcu_data[old_data], POISON);
+                       PRODUCE_TOKENS(proc_urcu_writer, WRITE_FREE);
+
+               :: CONSUME_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS, 0) ->
+                       CLEAR_TOKENS(proc_urcu_writer, WRITE_PROC_ALL_TOKENS_CLEAR);
+                       break;
+               fi;
+               }
+               od;
+               /*
+                * Note : Promela model adds implicit serialization of the
+                * WRITE_FREE instruction. Normally, it would be permitted to
+                * spill on the next loop execution. Given the validation we do
+                * checks for the data entry read to be poisoned, it's ok if
+                * we do not check "late arriving" memory poisoning.
+                */
+       :: 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
+#ifdef READER_PROGRESS
+               /*
+                * Make sure we don't block the reader's progress.
+                */
+               smp_mb_send(i, j, 5);
+#endif
+               skip;
+       od;
+
+       /* Non-atomic parts of the loop */
+       goto end;
+smp_mb_send1:
+       smp_mb_send(i, j, 1);
+       goto smp_mb_send1_end;
+#ifndef GEN_ERROR_WRITER_PROGRESS
+smp_mb_send2:
+       smp_mb_send(i, j, 2);
+       goto smp_mb_send2_end;
+smp_mb_send3:
+       smp_mb_send(i, j, 3);
+       goto smp_mb_send3_end;
+#endif
+smp_mb_send4:
+       smp_mb_send(i, j, 4);
+       goto smp_mb_send4_end;
+end:
+       skip;
+}
+
+/* no name clash please */
+#undef proc_urcu_writer
+
+
+/* Leave after the readers and writers so the pid count is ok. */
+init {
+       byte i, j;
+
+       atomic {
+               INIT_CACHED_VAR(urcu_gp_ctr, 1, j);
+               INIT_CACHED_VAR(rcu_ptr, 0, j);
+
+               i = 0;
+               do
+               :: i < NR_READERS ->
+                       INIT_CACHED_VAR(urcu_active_readers[i], 0, j);
+                       ptr_read_first[i] = 1;
+                       ptr_read_second[i] = 1;
+                       data_read_first[i] = WINE;
+                       data_read_second[i] = WINE;
+                       i++;
+               :: i >= NR_READERS -> break
+               od;
+               INIT_CACHED_VAR(rcu_data[0], WINE, j);
+               i = 1;
+               do
+               :: i < SLAB_SIZE ->
+                       INIT_CACHED_VAR(rcu_data[i], POISON, j);
+                       i++
+               :: i >= SLAB_SIZE -> break
+               od;
+
+               init_done = 1;
+       }
+}
diff --git a/formal-model/results/urcu-controldataflow-no-ipi/urcu_progress_writer_error.spin.input.trail b/formal-model/results/urcu-controldataflow-no-ipi/urcu_progress_writer_error.spin.input.trail
new file mode 100644 (file)
index 0000000..29e0696
--- /dev/null
@@ -0,0 +1,8711 @@
+-2:3:-2
+-4:-4:-4
+1:0:4529
+2:3:4449
+3:3:4452
+4:3:4452
+5:3:4455
+6:3:4463
+7:3:4463
+8:3:4466
+9:3:4472
+10:3:4476
+11:3:4476
+12:3:4479
+13:3:4489
+14:3:4497
+15:3:4497
+16:3:4500
+17:3:4506
+18:3:4510
+19:3:4510
+20:3:4513
+21:3:4519
+22:3:4523
+23:3:4524
+24:0:4529
+25:3:4526
+26:0:4529
+27:2:3117
+28:0:4529
+29:2:3123
+30:0:4529
+31:2:3124
+32:0:4529
+33:2:3125
+34:0:4527
+35:2:3126
+36:0:4533
+37:2:3127
+38:0:4533
+39:2:3128
+40:2:3129
+41:2:3133
+42:2:3134
+43:2:3142
+44:2:3143
+45:2:3147
+46:2:3148
+47:2:3156
+48:2:3161
+49:2:3165
+50:2:3166
+51:2:3174
+52:2:3175
+53:2:3179
+54:2:3180
+55:2:3174
+56:2:3175
+57:2:3179
+58:2:3180
+59:2:3188
+60:2:3193
+61:2:3194
+62:2:3205
+63:2:3206
+64:2:3207
+65:2:3218
+66:2:3223
+67:2:3224
+68:2:3235
+69:2:3236
+70:2:3237
+71:2:3235
+72:2:3236
+73:2:3237
+74:2:3248
+75:2:3256
+76:0:4533
+77:2:3127
+78:0:4533
+79:2:3260
+80:2:3264
+81:2:3265
+82:2:3269
+83:2:3273
+84:2:3274
+85:2:3278
+86:2:3286
+87:2:3287
+88:2:3291
+89:2:3295
+90:2:3296
+91:2:3291
+92:2:3292
+93:2:3300
+94:0:4533
+95:2:3127
+96:0:4533
+97:2:3308
+98:2:3309
+99:2:3310
+100:0:4533
+101:2:3127
+102:0:4533
+103:2:3315
+104:0:4533
+105:2:4268
+106:2:4269
+107:2:4273
+108:2:4277
+109:2:4278
+110:2:4282
+111:2:4287
+112:2:4295
+113:2:4299
+114:2:4300
+115:2:4295
+116:2:4299
+117:2:4300
+118:2:4304
+119:2:4311
+120:2:4318
+121:2:4319
+122:2:4326
+123:2:4331
+124:2:4338
+125:2:4339
+126:2:4338
+127:2:4339
+128:2:4346
+129:2:4350
+130:0:4533
+131:2:3317
+132:2:4249
+133:0:4533
+134:2:3127
+135:0:4533
+136:2:3318
+137:0:4533
+138:2:3127
+139:0:4533
+140:2:3321
+141:2:3322
+142:2:3326
+143:2:3327
+144:2:3335
+145:2:3336
+146:2:3340
+147:2:3341
+148:2:3349
+149:2:3354
+150:2:3358
+151:2:3359
+152:2:3367
+153:2:3368
+154:2:3372
+155:2:3373
+156:2:3367
+157:2:3368
+158:2:3372
+159:2:3373
+160:2:3381
+161:2:3386
+162:2:3387
+163:2:3398
+164:2:3399
+165:2:3400
+166:2:3411
+167:2:3416
+168:2:3417
+169:2:3428
+170:2:3429
+171:2:3430
+172:2:3428
+173:2:3429
+174:2:3430
+175:2:3441
+176:2:3448
+177:0:4533
+178:2:3127
+179:0:4533
+180:2:3452
+181:2:3453
+182:2:3454
+183:2:3466
+184:2:3467
+185:2:3471
+186:2:3472
+187:2:3480
+188:2:3485
+189:2:3489
+190:2:3490
+191:2:3498
+192:2:3499
+193:2:3503
+194:2:3504
+195:2:3498
+196:2:3499
+197:2:3503
+198:2:3504
+199:2:3512
+200:2:3517
+201:2:3518
+202:2:3529
+203:2:3530
+204:2:3531
+205:2:3542
+206:2:3547
+207:2:3548
+208:2:3559
+209:2:3560
+210:2:3561
+211:2:3559
+212:2:3560
+213:2:3561
+214:2:3572
+215:2:3583
+216:2:3584
+217:0:4533
+218:2:3127
+219:0:4533
+220:2:3715
+221:2:3716
+222:2:3720
+223:2:3721
+224:2:3729
+225:2:3730
+226:2:3734
+227:2:3735
+228:2:3743
+229:2:3748
+230:2:3752
+231:2:3753
+232:2:3761
+233:2:3762
+234:2:3766
+235:2:3767
+236:2:3761
+237:2:3762
+238:2:3766
+239:2:3767
+240:2:3775
+241:2:3780
+242:2:3781
+243:2:3792
+244:2:3793
+245:2:3794
+246:2:3805
+247:2:3810
+248:2:3811
+249:2:3822
+250:2:3823
+251:2:3824
+252:2:3822
+253:2:3823
+254:2:3824
+255:2:3835
+256:0:4533
+257:2:3127
+258:0:4533
+259:2:3844
+260:2:3845
+261:2:3849
+262:2:3850
+263:2:3858
+264:2:3859
+265:2:3863
+266:2:3864
+267:2:3872
+268:2:3877
+269:2:3881
+270:2:3882
+271:2:3890
+272:2:3891
+273:2:3895
+274:2:3896
+275:2:3890
+276:2:3891
+277:2:3895
+278:2:3896
+279:2:3904
+280:2:3909
+281:2:3910
+282:2:3921
+283:2:3922
+284:2:3923
+285:2:3934
+286:2:3939
+287:2:3940
+288:2:3951
+289:2:3952
+290:2:3953
+291:2:3951
+292:2:3952
+293:2:3953
+294:2:3964
+295:2:3971
+296:0:4533
+297:2:3127
+298:0:4533
+299:1:2
+300:0:4533
+301:1:8
+302:0:4533
+303:1:9
+304:0:4533
+305:1:10
+306:0:4533
+307:1:11
+308:0:4533
+309:1:12
+310:1:13
+311:1:17
+312:1:18
+313:1:26
+314:1:27
+315:1:31
+316:1:32
+317:1:40
+318:1:45
+319:1:49
+320:1:50
+321:1:58
+322:1:59
+323:1:63
+324:1:64
+325:1:58
+326:1:59
+327:1:63
+328:1:64
+329:1:72
+330:1:77
+331:1:78
+332:1:89
+333:1:90
+334:1:91
+335:1:102
+336:1:107
+337:1:108
+338:1:119
+339:1:120
+340:1:121
+341:1:119
+342:1:120
+343:1:121
+344:1:132
+345:0:4533
+346:1:11
+347:0:4533
+348:1:141
+349:1:142
+350:0:4533
+351:1:11
+352:0:4533
+353:1:148
+354:1:149
+355:1:153
+356:1:154
+357:1:162
+358:1:163
+359:1:167
+360:1:168
+361:1:176
+362:1:181
+363:1:185
+364:1:186
+365:1:194
+366:1:195
+367:1:199
+368:1:200
+369:1:194
+370:1:195
+371:1:199
+372:1:200
+373:1:208
+374:1:213
+375:1:214
+376:1:225
+377:1:226
+378:1:227
+379:1:238
+380:1:243
+381:1:244
+382:1:255
+383:1:256
+384:1:257
+385:1:255
+386:1:256
+387:1:257
+388:1:268
+389:0:4533
+390:1:11
+391:0:4533
+392:1:277
+393:1:278
+394:1:282
+395:1:283
+396:1:291
+397:1:292
+398:1:296
+399:1:297
+400:1:305
+401:1:310
+402:1:314
+403:1:315
+404:1:323
+405:1:324
+406:1:328
+407:1:329
+408:1:323
+409:1:324
+410:1:328
+411:1:329
+412:1:337
+413:1:342
+414:1:343
+415:1:354
+416:1:355
+417:1:356
+418:1:367
+419:1:372
+420:1:373
+421:1:384
+422:1:385
+423:1:386
+424:1:384
+425:1:385
+426:1:386
+427:1:397
+428:1:404
+429:0:4533
+430:1:11
+431:0:4533
+432:1:540
+433:1:544
+434:1:545
+435:1:549
+436:1:550
+437:1:558
+438:1:566
+439:1:567
+440:1:571
+441:1:575
+442:1:576
+443:1:571
+444:1:575
+445:1:576
+446:1:580
+447:1:587
+448:1:594
+449:1:595
+450:1:602
+451:1:607
+452:1:614
+453:1:615
+454:1:614
+455:1:615
+456:1:622
+457:0:4533
+458:1:11
+459:0:4533
+460:2:3975
+461:2:3976
+462:2:3977
+463:2:3989
+464:2:3990
+465:2:3994
+466:2:3995
+467:2:4003
+468:2:4008
+469:2:4012
+470:2:4013
+471:2:4021
+472:2:4022
+473:2:4026
+474:2:4027
+475:2:4021
+476:2:4022
+477:2:4026
+478:2:4027
+479:2:4035
+480:2:4040
+481:2:4041
+482:2:4052
+483:2:4053
+484:2:4054
+485:2:4065
+486:2:4070
+487:2:4071
+488:2:4082
+489:2:4083
+490:2:4084
+491:2:4082
+492:2:4083
+493:2:4084
+494:2:4095
+495:2:4103
+496:0:4533
+497:2:3127
+498:0:4533
+499:2:4109
+500:2:4110
+501:2:4114
+502:2:4115
+503:2:4123
+504:2:4124
+505:2:4128
+506:2:4129
+507:2:4137
+508:2:4142
+509:2:4146
+510:2:4147
+511:2:4155
+512:2:4156
+513:2:4160
+514:2:4161
+515:2:4155
+516:2:4156
+517:2:4160
+518:2:4161
+519:2:4169
+520:2:4174
+521:2:4175
+522:2:4186
+523:2:4187
+524:2:4188
+525:2:4199
+526:2:4204
+527:2:4205
+528:2:4216
+529:2:4217
+530:2:4218
+531:2:4216
+532:2:4217
+533:2:4218
+534:2:4229
+535:0:4533
+536:2:3127
+537:0:4533
+538:1:632
+539:1:633
+540:1:637
+541:1:638
+542:1:646
+543:1:647
+544:1:651
+545:1:652
+546:1:660
+547:1:665
+548:1:669
+549:1:670
+550:1:678
+551:1:679
+552:1:683
+553:1:684
+554:1:678
+555:1:679
+556:1:683
+557:1:684
+558:1:692
+559:1:697
+560:1:698
+561:1:709
+562:1:710
+563:1:711
+564:1:722
+565:1:727
+566:1:728
+567:1:739
+568:1:740
+569:1:741
+570:1:739
+571:1:740
+572:1:741
+573:1:752
+574:0:4533
+575:1:11
+576:0:4533
+577:2:3975
+578:2:3976
+579:2:3980
+580:2:3981
+581:2:3989
+582:2:3990
+583:2:3994
+584:2:3995
+585:2:4003
+586:2:4008
+587:2:4012
+588:2:4013
+589:2:4021
+590:2:4022
+591:2:4026
+592:2:4027
+593:2:4021
+594:2:4022
+595:2:4026
+596:2:4027
+597:2:4035
+598:2:4040
+599:2:4041
+600:2:4052
+601:2:4053
+602:2:4054
+603:2:4065
+604:2:4070
+605:2:4071
+606:2:4082
+607:2:4083
+608:2:4084
+609:2:4082
+610:2:4083
+611:2:4084
+612:2:4095
+613:2:4103
+614:0:4533
+615:2:3127
+616:0:4533
+617:2:4109
+618:2:4110
+619:2:4114
+620:2:4115
+621:2:4123
+622:2:4124
+623:2:4128
+624:2:4129
+625:2:4137
+626:2:4142
+627:2:4146
+628:2:4147
+629:2:4155
+630:2:4156
+631:2:4160
+632:2:4161
+633:2:4155
+634:2:4156
+635:2:4160
+636:2:4161
+637:2:4169
+638:2:4174
+639:2:4175
+640:2:4186
+641:2:4187
+642:2:4188
+643:2:4199
+644:2:4204
+645:2:4205
+646:2:4216
+647:2:4217
+648:2:4218
+649:2:4216
+650:2:4217
+651:2:4218
+652:2:4229
+653:0:4533
+654:2:3127
+655:0:4533
+656:1:761
+657:1:764
+658:1:765
+659:0:4533
+660:1:11
+661:0:4533
+662:2:3975
+663:2:3976
+664:2:3980
+665:2:3981
+666:2:3989
+667:2:3990
+668:2:3994
+669:2:3995
+670:2:4003
+671:2:4008
+672:2:4012
+673:2:4013
+674:2:4021
+675:2:4022
+676:2:4026
+677:2:4027
+678:2:4021
+679:2:4022
+680:2:4026
+681:2:4027
+682:2:4035
+683:2:4040
+684:2:4041
+685:2:4052
+686:2:4053
+687:2:4054
+688:2:4065
+689:2:4070
+690:2:4071
+691:2:4082
+692:2:4083
+693:2:4084
+694:2:4082
+695:2:4083
+696:2:4084
+697:2:4095
+698:2:4103
+699:0:4533
+700:2:3127
+701:0:4533
+702:2:4109
+703:2:4110
+704:2:4114
+705:2:4115
+706:2:4123
+707:2:4124
+708:2:4128
+709:2:4129
+710:2:4137
+711:2:4142
+712:2:4146
+713:2:4147
+714:2:4155
+715:2:4156
+716:2:4160
+717:2:4161
+718:2:4155
+719:2:4156
+720:2:4160
+721:2:4161
+722:2:4169
+723:2:4174
+724:2:4175
+725:2:4186
+726:2:4187
+727:2:4188
+728:2:4199
+729:2:4204
+730:2:4205
+731:2:4216
+732:2:4217
+733:2:4218
+734:2:4216
+735:2:4217
+736:2:4218
+737:2:4229
+738:0:4533
+739:2:3127
+740:0:4533
+741:1:1028
+742:1:1029
+743:1:1033
+744:1:1034
+745:1:1042
+746:1:1043
+747:1:1047
+748:1:1048
+749:1:1056
+750:1:1061
+751:1:1065
+752:1:1066
+753:1:1074
+754:1:1075
+755:1:1079
+756:1:1080
+757:1:1074
+758:1:1075
+759:1:1079
+760:1:1080
+761:1:1088
+762:1:1093
+763:1:1094
+764:1:1105
+765:1:1106
+766:1:1107
+767:1:1118
+768:1:1123
+769:1:1124
+770:1:1135
+771:1:1136
+772:1:1137
+773:1:1135
+774:1:1136
+775:1:1137
+776:1:1148
+777:1:1155
+778:1:1159
+779:0:4533
+780:1:11
+781:0:4533
+782:2:3975
+783:2:3976
+784:2:3980
+785:2:3981
+786:2:3989
+787:2:3990
+788:2:3994
+789:2:3995
+790:2:4003
+791:2:4008
+792:2:4012
+793:2:4013
+794:2:4021
+795:2:4022
+796:2:4026
+797:2:4027
+798:2:4021
+799:2:4022
+800:2:4026
+801:2:4027
+802:2:4035
+803:2:4040
+804:2:4041
+805:2:4052
+806:2:4053
+807:2:4054
+808:2:4065
+809:2:4070
+810:2:4071
+811:2:4082
+812:2:4083
+813:2:4084
+814:2:4082
+815:2:4083
+816:2:4084
+817:2:4095
+818:2:4103
+819:0:4533
+820:2:3127
+821:0:4533
+822:2:4109
+823:2:4110
+824:2:4114
+825:2:4115
+826:2:4123
+827:2:4124
+828:2:4128
+829:2:4129
+830:2:4137
+831:2:4142
+832:2:4146
+833:2:4147
+834:2:4155
+835:2:4156
+836:2:4160
+837:2:4161
+838:2:4155
+839:2:4156
+840:2:4160
+841:2:4161
+842:2:4169
+843:2:4174
+844:2:4175
+845:2:4186
+846:2:4187
+847:2:4188
+848:2:4199
+849:2:4204
+850:2:4205
+851:2:4216
+852:2:4217
+853:2:4218
+854:2:4216
+855:2:4217
+856:2:4218
+857:2:4229
+858:0:4533
+859:2:3127
+860:0:4533
+861:1:1160
+862:1:1161
+863:1:1165
+864:1:1166
+865:1:1174
+866:1:1175
+867:1:1176
+868:1:1188
+869:1:1193
+870:1:1197
+871:1:1198
+872:1:1206
+873:1:1207
+874:1:1211
+875:1:1212
+876:1:1206
+877:1:1207
+878:1:1211
+879:1:1212
+880:1:1220
+881:1:1225
+882:1:1226
+883:1:1237
+884:1:1238
+885:1:1239
+886:1:1250
+887:1:1255
+888:1:1256
+889:1:1267
+890:1:1268
+891:1:1269
+892:1:1267
+893:1:1268
+894:1:1269
+895:1:1280
+896:0:4533
+897:1:11
+898:0:4533
+899:2:3975
+900:2:3976
+901:2:3980
+902:2:3981
+903:2:3989
+904:2:3990
+905:2:3994
+906:2:3995
+907:2:4003
+908:2:4008
+909:2:4012
+910:2:4013
+911:2:4021
+912:2:4022
+913:2:4026
+914:2:4027
+915:2:4021
+916:2:4022
+917:2:4026
+918:2:4027
+919:2:4035
+920:2:4040
+921:2:4041
+922:2:4052
+923:2:4053
+924:2:4054
+925:2:4065
+926:2:4070
+927:2:4071
+928:2:4082
+929:2:4083
+930:2:4084
+931:2:4082
+932:2:4083
+933:2:4084
+934:2:4095
+935:2:4103
+936:0:4533
+937:2:3127
+938:0:4533
+939:2:4109
+940:2:4110
+941:2:4114
+942:2:4115
+943:2:4123
+944:2:4124
+945:2:4128
+946:2:4129
+947:2:4137
+948:2:4142
+949:2:4146
+950:2:4147
+951:2:4155
+952:2:4156
+953:2:4160
+954:2:4161
+955:2:4155
+956:2:4156
+957:2:4160
+958:2:4161
+959:2:4169
+960:2:4174
+961:2:4175
+962:2:4186
+963:2:4187
+964:2:4188
+965:2:4199
+966:2:4204
+967:2:4205
+968:2:4216
+969:2:4217
+970:2:4218
+971:2:4216
+972:2:4217
+973:2:4218
+974:2:4229
+975:0:4533
+976:2:3127
+977:0:4533
+978:1:1289
+979:0:4533
+980:2:3975
+981:2:3976
+982:2:3980
+983:2:3981
+984:2:3989
+985:2:3990
+986:2:3994
+987:2:3995
+988:2:4003
+989:2:4008
+990:2:4012
+991:2:4013
+992:2:4021
+993:2:4022
+994:2:4026
+995:2:4027
+996:2:4021
+997:2:4022
+998:2:4026
+999:2:4027
+1000:2:4035
+1001:2:4040
+1002:2:4041
+1003:2:4052
+1004:2:4053
+1005:2:4054
+1006:2:4065
+1007:2:4070
+1008:2:4071
+1009:2:4082
+1010:2:4083
+1011:2:4084
+1012:2:4082
+1013:2:4083
+1014:2:4084
+1015:2:4095
+1016:2:4103
+1017:0:4533
+1018:2:3127
+1019:0:4533
+1020:2:4109
+1021:2:4110
+1022:2:4114
+1023:2:4115
+1024:2:4123
+1025:2:4124
+1026:2:4128
+1027:2:4129
+1028:2:4137
+1029:2:4142
+1030:2:4146
+1031:2:4147
+1032:2:4155
+1033:2:4156
+1034:2:4160
+1035:2:4161
+1036:2:4155
+1037:2:4156
+1038:2:4160
+1039:2:4161
+1040:2:4169
+1041:2:4174
+1042:2:4175
+1043:2:4186
+1044:2:4187
+1045:2:4188
+1046:2:4199
+1047:2:4204
+1048:2:4205
+1049:2:4216
+1050:2:4217
+1051:2:4218
+1052:2:4216
+1053:2:4217
+1054:2:4218
+1055:2:4229
+1056:0:4533
+1057:2:3127
+1058:0:4533
+1059:1:3023
+1060:1:3030
+1061:1:3031
+1062:1:3038
+1063:1:3043
+1064:1:3050
+1065:1:3051
+1066:1:3050
+1067:1:3051
+1068:1:3058
+1069:1:3062
+1070:0:4533
+1071:2:3975
+1072:2:3976
+1073:2:3980
+1074:2:3981
+1075:2:3989
+1076:2:3990
+1077:2:3994
+1078:2:3995
+1079:2:4003
+1080:2:4008
+1081:2:4012
+1082:2:4013
+1083:2:4021
+1084:2:4022
+1085:2:4026
+1086:2:4027
+1087:2:4021
+1088:2:4022
+1089:2:4026
+1090:2:4027
+1091:2:4035
+1092:2:4040
+1093:2:4041
+1094:2:4052
+1095:2:4053
+1096:2:4054
+1097:2:4065
+1098:2:4070
+1099:2:4071
+1100:2:4082
+1101:2:4083
+1102:2:4084
+1103:2:4082
+1104:2:4083
+1105:2:4084
+1106:2:4095
+1107:2:4103
+1108:0:4533
+1109:2:3127
+1110:0:4533
+1111:2:4109
+1112:2:4110
+1113:2:4114
+1114:2:4115
+1115:2:4123
+1116:2:4124
+1117:2:4128
+1118:2:4129
+1119:2:4137
+1120:2:4142
+1121:2:4146
+1122:2:4147
+1123:2:4155
+1124:2:4156
+1125:2:4160
+1126:2:4161
+1127:2:4155
+1128:2:4156
+1129:2:4160
+1130:2:4161
+1131:2:4169
+1132:2:4174
+1133:2:4175
+1134:2:4186
+1135:2:4187
+1136:2:4188
+1137:2:4199
+1138:2:4204
+1139:2:4205
+1140:2:4216
+1141:2:4217
+1142:2:4218
+1143:2:4216
+1144:2:4217
+1145:2:4218
+1146:2:4229
+1147:0:4533
+1148:2:3127
+1149:0:4533
+1150:1:1291
+1151:1:1292
+1152:0:4533
+1153:1:11
+1154:0:4533
+1155:2:3975
+1156:2:3976
+1157:2:3980
+1158:2:3981
+1159:2:3989
+1160:2:3990
+1161:2:3994
+1162:2:3995
+1163:2:4003
+1164:2:4008
+1165:2:4012
+1166:2:4013
+1167:2:4021
+1168:2:4022
+1169:2:4026
+1170:2:4027
+1171:2:4021
+1172:2:4022
+1173:2:4026
+1174:2:4027
+1175:2:4035
+1176:2:4040
+1177:2:4041
+1178:2:4052
+1179:2:4053
+1180:2:4054
+1181:2:4065
+1182:2:4070
+1183:2:4071
+1184:2:4082
+1185:2:4083
+1186:2:4084
+1187:2:4082
+1188:2:4083
+1189:2:4084
+1190:2:4095
+1191:2:4103
+1192:0:4533
+1193:2:3127
+1194:0:4533
+1195:2:4109
+1196:2:4110
+1197:2:4114
+1198:2:4115
+1199:2:4123
+1200:2:4124
+1201:2:4128
+1202:2:4129
+1203:2:4137
+1204:2:4142
+1205:2:4146
+1206:2:4147
+1207:2:4155
+1208:2:4156
+1209:2:4160
+1210:2:4161
+1211:2:4155
+1212:2:4156
+1213:2:4160
+1214:2:4161
+1215:2:4169
+1216:2:4174
+1217:2:4175
+1218:2:4186
+1219:2:4187
+1220:2:4188
+1221:2:4199
+1222:2:4204
+1223:2:4205
+1224:2:4216
+1225:2:4217
+1226:2:4218
+1227:2:4216
+1228:2:4217
+1229:2:4218
+1230:2:4229
+1231:0:4533
+1232:2:3127
+1233:0:4533
+1234:1:1293
+1235:1:1294
+1236:1:1298
+1237:1:1299
+1238:1:1307
+1239:1:1308
+1240:1:1312
+1241:1:1313
+1242:1:1321
+1243:1:1326
+1244:1:1330
+1245:1:1331
+1246:1:1339
+1247:1:1340
+1248:1:1344
+1249:1:1345
+1250:1:1339
+1251:1:1340
+1252:1:1344
+1253:1:1345
+1254:1:1353
+1255:1:1358
+1256:1:1359
+1257:1:1370
+1258:1:1371
+1259:1:1372
+1260:1:1383
+1261:1:1388
+1262:1:1389
+1263:1:1400
+1264:1:1401
+1265:1:1402
+1266:1:1400
+1267:1:1401
+1268:1:1402
+1269:1:1413
+1270:0:4533
+1271:1:11
+1272:0:4533
+1273:2:3975
+1274:2:3976
+1275:2:3980
+1276:2:3981
+1277:2:3989
+1278:2:3990
+1279:2:3994
+1280:2:3995
+1281:2:4003
+1282:2:4008
+1283:2:4012
+1284:2:4013
+1285:2:4021
+1286:2:4022
+1287:2:4026
+1288:2:4027
+1289:2:4021
+1290:2:4022
+1291:2:4026
+1292:2:4027
+1293:2:4035
+1294:2:4040
+1295:2:4041
+1296:2:4052
+1297:2:4053
+1298:2:4054
+1299:2:4065
+1300:2:4070
+1301:2:4071
+1302:2:4082
+1303:2:4083
+1304:2:4084
+1305:2:4082
+1306:2:4083
+1307:2:4084
+1308:2:4095
+1309:2:4103
+1310:0:4533
+1311:2:3127
+1312:0:4533
+1313:2:4109
+1314:2:4110
+1315:2:4114
+1316:2:4115
+1317:2:4123
+1318:2:4124
+1319:2:4128
+1320:2:4129
+1321:2:4137
+1322:2:4142
+1323:2:4146
+1324:2:4147
+1325:2:4155
+1326:2:4156
+1327:2:4160
+1328:2:4161
+1329:2:4155
+1330:2:4156
+1331:2:4160
+1332:2:4161
+1333:2:4169
+1334:2:4174
+1335:2:4175
+1336:2:4186
+1337:2:4187
+1338:2:4188
+1339:2:4199
+1340:2:4204
+1341:2:4205
+1342:2:4216
+1343:2:4217
+1344:2:4218
+1345:2:4216
+1346:2:4217
+1347:2:4218
+1348:2:4229
+1349:0:4533
+1350:2:3127
+1351:0:4533
+1352:1:1422
+1353:1:1423
+1354:1:1427
+1355:1:1428
+1356:1:1436
+1357:1:1437
+1358:1:1441
+1359:1:1442
+1360:1:1450
+1361:1:1455
+1362:1:1459
+1363:1:1460
+1364:1:1468
+1365:1:1469
+1366:1:1473
+1367:1:1474
+1368:1:1468
+1369:1:1469
+1370:1:1473
+1371:1:1474
+1372:1:1482
+1373:1:1487
+1374:1:1488
+1375:1:1499
+1376:1:1500
+1377:1:1501
+1378:1:1512
+1379:1:1517
+1380:1:1518
+1381:1:1529
+1382:1:1530
+1383:1:1531
+1384:1:1529
+1385:1:1530
+1386:1:1531
+1387:1:1542
+1388:1:1549
+1389:1:1553
+1390:0:4533
+1391:1:11
+1392:0:4533
+1393:2:3975
+1394:2:3976
+1395:2:3980
+1396:2:3981
+1397:2:3989
+1398:2:3990
+1399:2:3994
+1400:2:3995
+1401:2:4003
+1402:2:4008
+1403:2:4012
+1404:2:4013
+1405:2:4021
+1406:2:4022
+1407:2:4026
+1408:2:4027
+1409:2:4021
+1410:2:4022
+1411:2:4026
+1412:2:4027
+1413:2:4035
+1414:2:4040
+1415:2:4041
+1416:2:4052
+1417:2:4053
+1418:2:4054
+1419:2:4065
+1420:2:4070
+1421:2:4071
+1422:2:4082
+1423:2:4083
+1424:2:4084
+1425:2:4082
+1426:2:4083
+1427:2:4084
+1428:2:4095
+1429:2:4103
+1430:0:4533
+1431:2:3127
+1432:0:4533
+1433:2:4109
+1434:2:4110
+1435:2:4114
+1436:2:4115
+1437:2:4123
+1438:2:4124
+1439:2:4128
+1440:2:4129
+1441:2:4137
+1442:2:4142
+1443:2:4146
+1444:2:4147
+1445:2:4155
+1446:2:4156
+1447:2:4160
+1448:2:4161
+1449:2:4155
+1450:2:4156
+1451:2:4160
+1452:2:4161
+1453:2:4169
+1454:2:4174
+1455:2:4175
+1456:2:4186
+1457:2:4187
+1458:2:4188
+1459:2:4199
+1460:2:4204
+1461:2:4205
+1462:2:4216
+1463:2:4217
+1464:2:4218
+1465:2:4216
+1466:2:4217
+1467:2:4218
+1468:2:4229
+1469:0:4533
+1470:2:3127
+1471:0:4533
+1472:1:1554
+1473:1:1558
+1474:1:1559
+1475:1:1563
+1476:1:1564
+1477:1:1572
+1478:1:1580
+1479:1:1581
+1480:1:1585
+1481:1:1589
+1482:1:1590
+1483:1:1585
+1484:1:1589
+1485:1:1590
+1486:1:1594
+1487:1:1601
+1488:1:1608
+1489:1:1609
+1490:1:1616
+1491:1:1621
+1492:1:1628
+1493:1:1629
+1494:1:1628
+1495:1:1629
+1496:1:1636
+1497:0:4533
+1498:1:11
+1499:0:4533
+1500:2:3975
+1501:2:3976
+1502:2:3980
+1503:2:3981
+1504:2:3989
+1505:2:3990
+1506:2:3994
+1507:2:3995
+1508:2:4003
+1509:2:4008
+1510:2:4012
+1511:2:4013
+1512:2:4021
+1513:2:4022
+1514:2:4026
+1515:2:4027
+1516:2:4021
+1517:2:4022
+1518:2:4026
+1519:2:4027
+1520:2:4035
+1521:2:4040
+1522:2:4041
+1523:2:4052
+1524:2:4053
+1525:2:4054
+1526:2:4065
+1527:2:4070
+1528:2:4071
+1529:2:4082
+1530:2:4083
+1531:2:4084
+1532:2:4082
+1533:2:4083
+1534:2:4084
+1535:2:4095
+1536:2:4103
+1537:0:4533
+1538:2:3127
+1539:0:4533
+1540:2:4109
+1541:2:4110
+1542:2:4114
+1543:2:4115
+1544:2:4123
+1545:2:4124
+1546:2:4128
+1547:2:4129
+1548:2:4137
+1549:2:4142
+1550:2:4146
+1551:2:4147
+1552:2:4155
+1553:2:4156
+1554:2:4160
+1555:2:4161
+1556:2:4155
+1557:2:4156
+1558:2:4160
+1559:2:4161
+1560:2:4169
+1561:2:4174
+1562:2:4175
+1563:2:4186
+1564:2:4187
+1565:2:4188
+1566:2:4199
+1567:2:4204
+1568:2:4205
+1569:2:4216
+1570:2:4217
+1571:2:4218
+1572:2:4216
+1573:2:4217
+1574:2:4218
+1575:2:4229
+1576:0:4533
+1577:2:3127
+1578:0:4533
+1579:1:1646
+1580:1:1647
+1581:1:1651
+1582:1:1652
+1583:1:1660
+1584:1:1661
+1585:1:1665
+1586:1:1666
+1587:1:1674
+1588:1:1679
+1589:1:1683
+1590:1:1684
+1591:1:1692
+1592:1:1693
+1593:1:1697
+1594:1:1698
+1595:1:1692
+1596:1:1693
+1597:1:1697
+1598:1:1698
+1599:1:1706
+1600:1:1711
+1601:1:1712
+1602:1:1723
+1603:1:1724
+1604:1:1725
+1605:1:1736
+1606:1:1741
+1607:1:1742
+1608:1:1753
+1609:1:1754
+1610:1:1755
+1611:1:1753
+1612:1:1754
+1613:1:1755
+1614:1:1766
+1615:0:4533
+1616:1:11
+1617:0:4533
+1618:2:3975
+1619:2:3976
+1620:2:3980
+1621:2:3981
+1622:2:3989
+1623:2:3990
+1624:2:3994
+1625:2:3995
+1626:2:4003
+1627:2:4008
+1628:2:4012
+1629:2:4013
+1630:2:4021
+1631:2:4022
+1632:2:4026
+1633:2:4027
+1634:2:4021
+1635:2:4022
+1636:2:4026
+1637:2:4027
+1638:2:4035
+1639:2:4040
+1640:2:4041
+1641:2:4052
+1642:2:4053
+1643:2:4054
+1644:2:4065
+1645:2:4070
+1646:2:4071
+1647:2:4082
+1648:2:4083
+1649:2:4084
+1650:2:4082
+1651:2:4083
+1652:2:4084
+1653:2:4095
+1654:2:4103
+1655:0:4533
+1656:2:3127
+1657:0:4533
+1658:2:4109
+1659:2:4110
+1660:2:4114
+1661:2:4115
+1662:2:4123
+1663:2:4124
+1664:2:4128
+1665:2:4129
+1666:2:4137
+1667:2:4142
+1668:2:4146
+1669:2:4147
+1670:2:4155
+1671:2:4156
+1672:2:4160
+1673:2:4161
+1674:2:4155
+1675:2:4156
+1676:2:4160
+1677:2:4161
+1678:2:4169
+1679:2:4174
+1680:2:4175
+1681:2:4186
+1682:2:4187
+1683:2:4188
+1684:2:4199
+1685:2:4204
+1686:2:4205
+1687:2:4216
+1688:2:4217
+1689:2:4218
+1690:2:4216
+1691:2:4217
+1692:2:4218
+1693:2:4229
+1694:0:4533
+1695:2:3127
+1696:0:4533
+1697:1:1775
+1698:1:1776
+1699:1:1780
+1700:1:1781
+1701:1:1789
+1702:1:1790
+1703:1:1794
+1704:1:1795
+1705:1:1803
+1706:1:1808
+1707:1:1812
+1708:1:1813
+1709:1:1821
+1710:1:1822
+1711:1:1826
+1712:1:1827
+1713:1:1821
+1714:1:1822
+1715:1:1826
+1716:1:1827
+1717:1:1835
+1718:1:1840
+1719:1:1841
+1720:1:1852
+1721:1:1853
+1722:1:1854
+1723:1:1865
+1724:1:1870
+1725:1:1871
+1726:1:1882
+1727:1:1883
+1728:1:1884
+1729:1:1882
+1730:1:1883
+1731:1:1884
+1732:1:1895
+1733:1:1902
+1734:1:1906
+1735:0:4533
+1736:1:11
+1737:0:4533
+1738:2:3975
+1739:2:3976
+1740:2:3980
+1741:2:3981
+1742:2:3989
+1743:2:3990
+1744:2:3994
+1745:2:3995
+1746:2:4003
+1747:2:4008
+1748:2:4012
+1749:2:4013
+1750:2:4021
+1751:2:4022
+1752:2:4026
+1753:2:4027
+1754:2:4021
+1755:2:4022
+1756:2:4026
+1757:2:4027
+1758:2:4035
+1759:2:4040
+1760:2:4041
+1761:2:4052
+1762:2:4053
+1763:2:4054
+1764:2:4065
+1765:2:4070
+1766:2:4071
+1767:2:4082
+1768:2:4083
+1769:2:4084
+1770:2:4082
+1771:2:4083
+1772:2:4084
+1773:2:4095
+1774:2:4103
+1775:0:4533
+1776:2:3127
+1777:0:4533
+1778:2:4109
+1779:2:4110
+1780:2:4114
+1781:2:4115
+1782:2:4123
+1783:2:4124
+1784:2:4128
+1785:2:4129
+1786:2:4137
+1787:2:4142
+1788:2:4146
+1789:2:4147
+1790:2:4155
+1791:2:4156
+1792:2:4160
+1793:2:4161
+1794:2:4155
+1795:2:4156
+1796:2:4160
+1797:2:4161
+1798:2:4169
+1799:2:4174
+1800:2:4175
+1801:2:4186
+1802:2:4187
+1803:2:4188
+1804:2:4199
+1805:2:4204
+1806:2:4205
+1807:2:4216
+1808:2:4217
+1809:2:4218
+1810:2:4216
+1811:2:4217
+1812:2:4218
+1813:2:4229
+1814:0:4533
+1815:2:3127
+1816:0:4533
+1817:1:1907
+1818:1:1908
+1819:1:1912
+1820:1:1913
+1821:1:1921
+1822:1:1922
+1823:1:1923
+1824:1:1935
+1825:1:1940
+1826:1:1944
+1827:1:1945
+1828:1:1953
+1829:1:1954
+1830:1:1958
+1831:1:1959
+1832:1:1953
+1833:1:1954
+1834:1:1958
+1835:1:1959
+1836:1:1967
+1837:1:1972
+1838:1:1973
+1839:1:1984
+1840:1:1985
+1841:1:1986
+1842:1:1997
+1843:1:2002
+1844:1:2003
+1845:1:2014
+1846:1:2015
+1847:1:2016
+1848:1:2014
+1849:1:2015
+1850:1:2016
+1851:1:2027
+1852:0:4533
+1853:1:11
+1854:0:4533
+1855:2:3975
+1856:2:3976
+1857:2:3980
+1858:2:3981
+1859:2:3989
+1860:2:3990
+1861:2:3994
+1862:2:3995
+1863:2:4003
+1864:2:4008
+1865:2:4012
+1866:2:4013
+1867:2:4021
+1868:2:4022
+1869:2:4026
+1870:2:4027
+1871:2:4021
+1872:2:4022
+1873:2:4026
+1874:2:4027
+1875:2:4035
+1876:2:4040
+1877:2:4041
+1878:2:4052
+1879:2:4060
+1880:2:4061
+1881:2:4065
+1882:2:4070
+1883:2:4071
+1884:2:4082
+1885:2:4083
+1886:2:4084
+1887:2:4082
+1888:2:4083
+1889:2:4084
+1890:2:4095
+1891:2:4103
+1892:0:4533
+1893:2:3127
+1894:0:4533
+1895:2:4109
+1896:2:4110
+1897:2:4114
+1898:2:4115
+1899:2:4123
+1900:2:4124
+1901:2:4128
+1902:2:4129
+1903:2:4137
+1904:2:4142
+1905:2:4146
+1906:2:4147
+1907:2:4155
+1908:2:4156
+1909:2:4160
+1910:2:4161
+1911:2:4155
+1912:2:4156
+1913:2:4160
+1914:2:4161
+1915:2:4169
+1916:2:4174
+1917:2:4175
+1918:2:4186
+1919:2:4194
+1920:2:4195
+1921:2:4199
+1922:2:4204
+1923:2:4205
+1924:2:4216
+1925:2:4217
+1926:2:4218
+1927:2:4216
+1928:2:4217
+1929:2:4218
+1930:2:4229
+1931:0:4533
+1932:2:3127
+1933:0:4533
+1934:1:2036
+1935:1:2037
+1936:0:4533
+1937:1:11
+1938:0:4533
+1939:2:3975
+1940:2:3976
+1941:2:3980
+1942:2:3981
+1943:2:3989
+1944:2:3990
+1945:2:3994
+1946:2:3995
+1947:2:4003
+1948:2:4008
+1949:2:4012
+1950:2:4013
+1951:2:4021
+1952:2:4022
+1953:2:4026
+1954:2:4027
+1955:2:4021
+1956:2:4022
+1957:2:4026
+1958:2:4027
+1959:2:4035
+1960:2:4040
+1961:2:4041
+1962:2:4052
+1963:2:4060
+1964:2:4061
+1965:2:4065
+1966:2:4070
+1967:2:4071
+1968:2:4082
+1969:2:4083
+1970:2:4084
+1971:2:4082
+1972:2:4083
+1973:2:4084
+1974:2:4095
+1975:2:4103
+1976:0:4533
+1977:2:3127
+1978:0:4533
+1979:2:4109
+1980:2:4110
+1981:2:4114
+1982:2:4115
+1983:2:4123
+1984:2:4124
+1985:2:4128
+1986:2:4129
+1987:2:4137
+1988:2:4142
+1989:2:4146
+1990:2:4147
+1991:2:4155
+1992:2:4156
+1993:2:4160
+1994:2:4161
+1995:2:4155
+1996:2:4156
+1997:2:4160
+1998:2:4161
+1999:2:4169
+2000:2:4174
+2001:2:4175
+2002:2:4186
+2003:2:4194
+2004:2:4195
+2005:2:4199
+2006:2:4204
+2007:2:4205
+2008:2:4216
+2009:2:4217
+2010:2:4218
+2011:2:4216
+2012:2:4217
+2013:2:4218
+2014:2:4229
+2015:0:4533
+2016:2:3127
+2017:0:4533
+2018:1:2043
+2019:1:2044
+2020:1:2048
+2021:1:2049
+2022:1:2057
+2023:1:2058
+2024:1:2062
+2025:1:2063
+2026:1:2071
+2027:1:2076
+2028:1:2080
+2029:1:2081
+2030:1:2089
+2031:1:2090
+2032:1:2094
+2033:1:2095
+2034:1:2089
+2035:1:2090
+2036:1:2094
+2037:1:2095
+2038:1:2103
+2039:1:2108
+2040:1:2109
+2041:1:2120
+2042:1:2121
+2043:1:2122
+2044:1:2133
+2045:1:2138
+2046:1:2139
+2047:1:2150
+2048:1:2151
+2049:1:2152
+2050:1:2150
+2051:1:2151
+2052:1:2152
+2053:1:2163
+2054:0:4533
+2055:1:11
+2056:0:4533
+2057:2:3975
+2058:2:3976
+2059:2:3980
+2060:2:3981
+2061:2:3989
+2062:2:3990
+2063:2:3994
+2064:2:3995
+2065:2:4003
+2066:2:4008
+2067:2:4012
+2068:2:4013
+2069:2:4021
+2070:2:4022
+2071:2:4026
+2072:2:4027
+2073:2:4021
+2074:2:4022
+2075:2:4026
+2076:2:4027
+2077:2:4035
+2078:2:4040
+2079:2:4041
+2080:2:4052
+2081:2:4060
+2082:2:4061
+2083:2:4065
+2084:2:4070
+2085:2:4071
+2086:2:4082
+2087:2:4083
+2088:2:4084
+2089:2:4082
+2090:2:4083
+2091:2:4084
+2092:2:4095
+2093:2:4103
+2094:0:4533
+2095:2:3127
+2096:0:4533
+2097:2:4109
+2098:2:4110
+2099:2:4114
+2100:2:4115
+2101:2:4123
+2102:2:4124
+2103:2:4128
+2104:2:4129
+2105:2:4137
+2106:2:4142
+2107:2:4146
+2108:2:4147
+2109:2:4155
+2110:2:4156
+2111:2:4160
+2112:2:4161
+2113:2:4155
+2114:2:4156
+2115:2:4160
+2116:2:4161
+2117:2:4169
+2118:2:4174
+2119:2:4175
+2120:2:4186
+2121:2:4194
+2122:2:4195
+2123:2:4199
+2124:2:4204
+2125:2:4205
+2126:2:4216
+2127:2:4217
+2128:2:4218
+2129:2:4216
+2130:2:4217
+2131:2:4218
+2132:2:4229
+2133:0:4533
+2134:2:3127
+2135:0:4533
+2136:1:2172
+2137:1:2173
+2138:1:2177
+2139:1:2178
+2140:1:2186
+2141:1:2187
+2142:1:2191
+2143:1:2192
+2144:1:2200
+2145:1:2205
+2146:1:2209
+2147:1:2210
+2148:1:2218
+2149:1:2219
+2150:1:2223
+2151:1:2224
+2152:1:2218
+2153:1:2219
+2154:1:2223
+2155:1:2224
+2156:1:2232
+2157:1:2237
+2158:1:2238
+2159:1:2249
+2160:1:2250
+2161:1:2251
+2162:1:2262
+2163:1:2267
+2164:1:2268
+2165:1:2279
+2166:1:2280
+2167:1:2281
+2168:1:2279
+2169:1:2280
+2170:1:2281
+2171:1:2292
+2172:1:2299
+2173:0:4533
+2174:1:11
+2175:0:4533
+2176:2:3975
+2177:2:3976
+2178:2:3980
+2179:2:3981
+2180:2:3989
+2181:2:3990
+2182:2:3994
+2183:2:3995
+2184:2:4003
+2185:2:4008
+2186:2:4012
+2187:2:4013
+2188:2:4021
+2189:2:4022
+2190:2:4026
+2191:2:4027
+2192:2:4021
+2193:2:4022
+2194:2:4026
+2195:2:4027
+2196:2:4035
+2197:2:4040
+2198:2:4041
+2199:2:4052
+2200:2:4060
+2201:2:4061
+2202:2:4065
+2203:2:4070
+2204:2:4071
+2205:2:4082
+2206:2:4083
+2207:2:4084
+2208:2:4082
+2209:2:4083
+2210:2:4084
+2211:2:4095
+2212:2:4103
+2213:0:4533
+2214:2:3127
+2215:0:4533
+2216:2:4109
+2217:2:4110
+2218:2:4114
+2219:2:4115
+2220:2:4123
+2221:2:4124
+2222:2:4128
+2223:2:4129
+2224:2:4137
+2225:2:4142
+2226:2:4146
+2227:2:4147
+2228:2:4155
+2229:2:4156
+2230:2:4160
+2231:2:4161
+2232:2:4155
+2233:2:4156
+2234:2:4160
+2235:2:4161
+2236:2:4169
+2237:2:4174
+2238:2:4175
+2239:2:4186
+2240:2:4194
+2241:2:4195
+2242:2:4199
+2243:2:4204
+2244:2:4205
+2245:2:4216
+2246:2:4217
+2247:2:4218
+2248:2:4216
+2249:2:4217
+2250:2:4218
+2251:2:4229
+2252:0:4533
+2253:2:3127
+2254:0:4533
+2255:1:2435
+2256:1:2439
+2257:1:2440
+2258:1:2444
+2259:1:2445
+2260:1:2453
+2261:1:2461
+2262:1:2462
+2263:1:2466
+2264:1:2470
+2265:1:2471
+2266:1:2466
+2267:1:2470
+2268:1:2471
+2269:1:2475
+2270:1:2482
+2271:1:2489
+2272:1:2490
+2273:1:2497
+2274:1:2502
+2275:1:2509
+2276:1:2510
+2277:1:2509
+2278:1:2510
+2279:1:2517
+2280:0:4533
+2281:1:11
+2282:0:4533
+2283:2:3975
+2284:2:3976
+2285:2:3980
+2286:2:3981
+2287:2:3989
+2288:2:3990
+2289:2:3994
+2290:2:3995
+2291:2:4003
+2292:2:4008
+2293:2:4012
+2294:2:4013
+2295:2:4021
+2296:2:4022
+2297:2:4026
+2298:2:4027
+2299:2:4021
+2300:2:4022
+2301:2:4026
+2302:2:4027
+2303:2:4035
+2304:2:4040
+2305:2:4041
+2306:2:4052
+2307:2:4060
+2308:2:4061
+2309:2:4065
+2310:2:4070
+2311:2:4071
+2312:2:4082
+2313:2:4083
+2314:2:4084
+2315:2:4082
+2316:2:4083
+2317:2:4084
+2318:2:4095
+2319:2:4103
+2320:0:4533
+2321:2:3127
+2322:0:4533
+2323:2:4109
+2324:2:4110
+2325:2:4114
+2326:2:4115
+2327:2:4123
+2328:2:4124
+2329:2:4128
+2330:2:4129
+2331:2:4137
+2332:2:4142
+2333:2:4146
+2334:2:4147
+2335:2:4155
+2336:2:4156
+2337:2:4160
+2338:2:4161
+2339:2:4155
+2340:2:4156
+2341:2:4160
+2342:2:4161
+2343:2:4169
+2344:2:4174
+2345:2:4175
+2346:2:4186
+2347:2:4194
+2348:2:4195
+2349:2:4199
+2350:2:4204
+2351:2:4205
+2352:2:4216
+2353:2:4217
+2354:2:4218
+2355:2:4216
+2356:2:4217
+2357:2:4218
+2358:2:4229
+2359:0:4533
+2360:2:3127
+2361:0:4533
+2362:1:2527
+2363:1:2528
+2364:1:2532
+2365:1:2533
+2366:1:2541
+2367:1:2542
+2368:1:2546
+2369:1:2547
+2370:1:2555
+2371:1:2560
+2372:1:2564
+2373:1:2565
+2374:1:2573
+2375:1:2574
+2376:1:2578
+2377:1:2579
+2378:1:2573
+2379:1:2574
+2380:1:2578
+2381:1:2579
+2382:1:2587
+2383:1:2592
+2384:1:2593
+2385:1:2604
+2386:1:2605
+2387:1:2606
+2388:1:2617
+2389:1:2622
+2390:1:2623
+2391:1:2634
+2392:1:2635
+2393:1:2636
+2394:1:2634
+2395:1:2635
+2396:1:2636
+2397:1:2647
+2398:0:4533
+2399:1:11
+2400:0:4533
+2401:2:3975
+2402:2:3976
+2403:2:3980
+2404:2:3981
+2405:2:3989
+2406:2:3990
+2407:2:3994
+2408:2:3995
+2409:2:4003
+2410:2:4008
+2411:2:4012
+2412:2:4013
+2413:2:4021
+2414:2:4022
+2415:2:4026
+2416:2:4027
+2417:2:4021
+2418:2:4022
+2419:2:4026
+2420:2:4027
+2421:2:4035
+2422:2:4040
+2423:2:4041
+2424:2:4052
+2425:2:4060
+2426:2:4061
+2427:2:4065
+2428:2:4070
+2429:2:4071
+2430:2:4082
+2431:2:4083
+2432:2:4084
+2433:2:4082
+2434:2:4083
+2435:2:4084
+2436:2:4095
+2437:2:4103
+2438:0:4533
+2439:2:3127
+2440:0:4533
+2441:2:4109
+2442:2:4110
+2443:2:4114
+2444:2:4115
+2445:2:4123
+2446:2:4124
+2447:2:4128
+2448:2:4129
+2449:2:4137
+2450:2:4142
+2451:2:4146
+2452:2:4147
+2453:2:4155
+2454:2:4156
+2455:2:4160
+2456:2:4161
+2457:2:4155
+2458:2:4156
+2459:2:4160
+2460:2:4161
+2461:2:4169
+2462:2:4174
+2463:2:4175
+2464:2:4186
+2465:2:4194
+2466:2:4195
+2467:2:4199
+2468:2:4204
+2469:2:4205
+2470:2:4216
+2471:2:4217
+2472:2:4218
+2473:2:4216
+2474:2:4217
+2475:2:4218
+2476:2:4229
+2477:0:4533
+2478:2:3127
+2479:0:4533
+2480:1:2656
+2481:0:4533
+2482:2:3975
+2483:2:3976
+2484:2:3980
+2485:2:3981
+2486:2:3989
+2487:2:3990
+2488:2:3994
+2489:2:3995
+2490:2:4003
+2491:2:4008
+2492:2:4012
+2493:2:4013
+2494:2:4021
+2495:2:4022
+2496:2:4026
+2497:2:4027
+2498:2:4021
+2499:2:4022
+2500:2:4026
+2501:2:4027
+2502:2:4035
+2503:2:4040
+2504:2:4041
+2505:2:4052
+2506:2:4060
+2507:2:4061
+2508:2:4065
+2509:2:4070
+2510:2:4071
+2511:2:4082
+2512:2:4083
+2513:2:4084
+2514:2:4082
+2515:2:4083
+2516:2:4084
+2517:2:4095
+2518:2:4103
+2519:0:4533
+2520:2:3127
+2521:0:4533
+2522:2:4109
+2523:2:4110
+2524:2:4114
+2525:2:4115
+2526:2:4123
+2527:2:4124
+2528:2:4128
+2529:2:4129
+2530:2:4137
+2531:2:4142
+2532:2:4146
+2533:2:4147
+2534:2:4155
+2535:2:4156
+2536:2:4160
+2537:2:4161
+2538:2:4155
+2539:2:4156
+2540:2:4160
+2541:2:4161
+2542:2:4169
+2543:2:4174
+2544:2:4175
+2545:2:4186
+2546:2:4194
+2547:2:4195
+2548:2:4199
+2549:2:4204
+2550:2:4205
+2551:2:4216
+2552:2:4217
+2553:2:4218
+2554:2:4216
+2555:2:4217
+2556:2:4218
+2557:2:4229
+2558:0:4533
+2559:2:3127
+2560:0:4533
+2561:1:3066
+2562:1:3073
+2563:1:3074
+2564:1:3081
+2565:1:3086
+2566:1:3093
+2567:1:3094
+2568:1:3093
+2569:1:3094
+2570:1:3101
+2571:1:3105
+2572:0:4533
+2573:2:3975
+2574:2:3976
+2575:2:3980
+2576:2:3981
+2577:2:3989
+2578:2:3990
+2579:2:3994
+2580:2:3995
+2581:2:4003
+2582:2:4008
+2583:2:4012
+2584:2:4013
+2585:2:4021
+2586:2:4022
+2587:2:4026
+2588:2:4027
+2589:2:4021
+2590:2:4022
+2591:2:4026
+2592:2:4027
+2593:2:4035
+2594:2:4040
+2595:2:4041
+2596:2:4052
+2597:2:4060
+2598:2:4061
+2599:2:4065
+2600:2:4070
+2601:2:4071
+2602:2:4082
+2603:2:4083
+2604:2:4084
+2605:2:4082
+2606:2:4083
+2607:2:4084
+2608:2:4095
+2609:2:4103
+2610:0:4533
+2611:2:3127
+2612:0:4533
+2613:2:4109
+2614:2:4110
+2615:2:4114
+2616:2:4115
+2617:2:4123
+2618:2:4124
+2619:2:4128
+2620:2:4129
+2621:2:4137
+2622:2:4142
+2623:2:4146
+2624:2:4147
+2625:2:4155
+2626:2:4156
+2627:2:4160
+2628:2:4161
+2629:2:4155
+2630:2:4156
+2631:2:4160
+2632:2:4161
+2633:2:4169
+2634:2:4174
+2635:2:4175
+2636:2:4186
+2637:2:4194
+2638:2:4195
+2639:2:4199
+2640:2:4204
+2641:2:4205
+2642:2:4216
+2643:2:4217
+2644:2:4218
+2645:2:4216
+2646:2:4217
+2647:2:4218
+2648:2:4229
+2649:0:4533
+2650:2:3127
+2651:0:4533
+2652:1:2658
+2653:1:2659
+2654:0:4533
+2655:1:11
+2656:0:4533
+2657:2:3975
+2658:2:3976
+2659:2:3980
+2660:2:3981
+2661:2:3989
+2662:2:3990
+2663:2:3994
+2664:2:3995
+2665:2:4003
+2666:2:4008
+2667:2:4012
+2668:2:4013
+2669:2:4021
+2670:2:4022
+2671:2:4026
+2672:2:4027
+2673:2:4021
+2674:2:4022
+2675:2:4026
+2676:2:4027
+2677:2:4035
+2678:2:4040
+2679:2:4041
+2680:2:4052
+2681:2:4060
+2682:2:4061
+2683:2:4065
+2684:2:4070
+2685:2:4071
+2686:2:4082
+2687:2:4083
+2688:2:4084
+2689:2:4082
+2690:2:4083
+2691:2:4084
+2692:2:4095
+2693:2:4103
+2694:0:4533
+2695:2:3127
+2696:0:4533
+2697:2:4109
+2698:2:4110
+2699:2:4114
+2700:2:4115
+2701:2:4123
+2702:2:4124
+2703:2:4128
+2704:2:4129
+2705:2:4137
+2706:2:4142
+2707:2:4146
+2708:2:4147
+2709:2:4155
+2710:2:4156
+2711:2:4160
+2712:2:4161
+2713:2:4155
+2714:2:4156
+2715:2:4160
+2716:2:4161
+2717:2:4169
+2718:2:4174
+2719:2:4175
+2720:2:4186
+2721:2:4194
+2722:2:4195
+2723:2:4199
+2724:2:4204
+2725:2:4205
+2726:2:4216
+2727:2:4217
+2728:2:4218
+2729:2:4216
+2730:2:4217
+2731:2:4218
+2732:2:4229
+2733:0:4533
+2734:2:3127
+2735:0:4533
+2736:1:2660
+2737:1:2664
+2738:1:2665
+2739:1:2669
+2740:1:2673
+2741:1:2674
+2742:1:2678
+2743:1:2686
+2744:1:2687
+2745:1:2691
+2746:1:2695
+2747:1:2696
+2748:1:2691
+2749:1:2695
+2750:1:2696
+2751:1:2700
+2752:1:2707
+2753:1:2714
+2754:1:2715
+2755:1:2722
+2756:1:2727
+2757:1:2734
+2758:1:2735
+2759:1:2734
+2760:1:2735
+2761:1:2742
+2762:0:4533
+2763:1:11
+2764:0:4533
+2765:2:3975
+2766:2:3976
+2767:2:3980
+2768:2:3981
+2769:2:3989
+2770:2:3990
+2771:2:3994
+2772:2:3995
+2773:2:4003
+2774:2:4008
+2775:2:4012
+2776:2:4013
+2777:2:4021
+2778:2:4022
+2779:2:4026
+2780:2:4027
+2781:2:4021
+2782:2:4022
+2783:2:4026
+2784:2:4027
+2785:2:4035
+2786:2:4040
+2787:2:4041
+2788:2:4052
+2789:2:4060
+2790:2:4061
+2791:2:4065
+2792:2:4070
+2793:2:4071
+2794:2:4082
+2795:2:4083
+2796:2:4084
+2797:2:4082
+2798:2:4083
+2799:2:4084
+2800:2:4095
+2801:2:4103
+2802:0:4533
+2803:2:3127
+2804:0:4533
+2805:2:4109
+2806:2:4110
+2807:2:4114
+2808:2:4115
+2809:2:4123
+2810:2:4124
+2811:2:4128
+2812:2:4129
+2813:2:4137
+2814:2:4142
+2815:2:4146
+2816:2:4147
+2817:2:4155
+2818:2:4156
+2819:2:4160
+2820:2:4161
+2821:2:4155
+2822:2:4156
+2823:2:4160
+2824:2:4161
+2825:2:4169
+2826:2:4174
+2827:2:4175
+2828:2:4186
+2829:2:4194
+2830:2:4195
+2831:2:4199
+2832:2:4204
+2833:2:4205
+2834:2:4216
+2835:2:4217
+2836:2:4218
+2837:2:4216
+2838:2:4217
+2839:2:4218
+2840:2:4229
+2841:0:4533
+2842:2:3127
+2843:0:4533
+2844:1:2752
+2845:1:2753
+2846:1:2757
+2847:1:2758
+2848:1:2766
+2849:1:2767
+2850:1:2771
+2851:1:2772
+2852:1:2780
+2853:1:2785
+2854:1:2789
+2855:1:2790
+2856:1:2798
+2857:1:2799
+2858:1:2803
+2859:1:2804
+2860:1:2798
+2861:1:2799
+2862:1:2803
+2863:1:2804
+2864:1:2812
+2865:1:2817
+2866:1:2818
+2867:1:2829
+2868:1:2830
+2869:1:2831
+2870:1:2842
+2871:1:2847
+2872:1:2848
+2873:1:2859
+2874:1:2860
+2875:1:2861
+2876:1:2859
+2877:1:2860
+2878:1:2861
+2879:1:2872
+2880:0:4533
+2881:1:11
+2882:0:4533
+2883:2:3975
+2884:2:3976
+2885:2:3980
+2886:2:3981
+2887:2:3989
+2888:2:3990
+2889:2:3994
+2890:2:3995
+2891:2:4003
+2892:2:4008
+2893:2:4012
+2894:2:4013
+2895:2:4021
+2896:2:4022
+2897:2:4026
+2898:2:4027
+2899:2:4021
+2900:2:4022
+2901:2:4026
+2902:2:4027
+2903:2:4035
+2904:2:4040
+2905:2:4041
+2906:2:4052
+2907:2:4060
+2908:2:4061
+2909:2:4065
+2910:2:4070
+2911:2:4071
+2912:2:4082
+2913:2:4083
+2914:2:4084
+2915:2:4082
+2916:2:4083
+2917:2:4084
+2918:2:4095
+2919:2:4103
+2920:0:4533
+2921:2:3127
+2922:0:4533
+2923:2:4109
+2924:2:4110
+2925:2:4114
+2926:2:4115
+2927:2:4123
+2928:2:4124
+2929:2:4128
+2930:2:4129
+2931:2:4137
+2932:2:4142
+2933:2:4146
+2934:2:4147
+2935:2:4155
+2936:2:4156
+2937:2:4160
+2938:2:4161
+2939:2:4155
+2940:2:4156
+2941:2:4160
+2942:2:4161
+2943:2:4169
+2944:2:4174
+2945:2:4175
+2946:2:4186
+2947:2:4194
+2948:2:4195
+2949:2:4199
+2950:2:4204
+2951:2:4205
+2952:2:4216
+2953:2:4217
+2954:2:4218
+2955:2:4216
+2956:2:4217
+2957:2:4218
+2958:2:4229
+2959:0:4533
+2960:2:3127
+2961:0:4533
+2962:1:2881
+2963:1:2882
+2964:1:2886
+2965:1:2887
+2966:1:2895
+2967:1:2896
+2968:1:2900
+2969:1:2901
+2970:1:2909
+2971:1:2914
+2972:1:2918
+2973:1:2919
+2974:1:2927
+2975:1:2928
+2976:1:2932
+2977:1:2933
+2978:1:2927
+2979:1:2928
+2980:1:2932
+2981:1:2933
+2982:1:2941
+2983:1:2946
+2984:1:2947
+2985:1:2958
+2986:1:2959
+2987:1:2960
+2988:1:2971
+2989:1:2976
+2990:1:2977
+2991:1:2988
+2992:1:2989
+2993:1:2990
+2994:1:2988
+2995:1:2989
+2996:1:2990
+2997:1:3001
+2998:1:3008
+2999:1:3012
+3000:0:4533
+3001:1:11
+3002:0:4533
+3003:2:3975
+3004:2:3976
+3005:2:3980
+3006:2:3981
+3007:2:3989
+3008:2:3990
+3009:2:3994
+3010:2:3995
+3011:2:4003
+3012:2:4008
+3013:2:4012
+3014:2:4013
+3015:2:4021
+3016:2:4022
+3017:2:4026
+3018:2:4027
+3019:2:4021
+3020:2:4022
+3021:2:4026
+3022:2:4027
+3023:2:4035
+3024:2:4040
+3025:2:4041
+3026:2:4052
+3027:2:4060
+3028:2:4061
+3029:2:4065
+3030:2:4070
+3031:2:4071
+3032:2:4082
+3033:2:4083
+3034:2:4084
+3035:2:4082
+3036:2:4083
+3037:2:4084
+3038:2:4095
+3039:2:4103
+3040:0:4533
+3041:2:3127
+3042:0:4533
+3043:2:4109
+3044:2:4110
+3045:2:4114
+3046:2:4115
+3047:2:4123
+3048:2:4124
+3049:2:4128
+3050:2:4129
+3051:2:4137
+3052:2:4142
+3053:2:4146
+3054:2:4147
+3055:2:4155
+3056:2:4156
+3057:2:4160
+3058:2:4161
+3059:2:4155
+3060:2:4156
+3061:2:4160
+3062:2:4161
+3063:2:4169
+3064:2:4174
+3065:2:4175
+3066:2:4186
+3067:2:4194
+3068:2:4195
+3069:2:4199
+3070:2:4204
+3071:2:4205
+3072:2:4216
+3073:2:4217
+3074:2:4218
+3075:2:4216
+3076:2:4217
+3077:2:4218
+3078:2:4229
+3079:0:4533
+3080:2:3127
+3081:0:4533
+3082:1:3013
+3083:0:4533
+3084:1:3021
+3085:0:4533
+3086:1:3109
+3087:0:4533
+3088:1:9
+3089:0:4533
+3090:2:3975
+3091:2:3976
+3092:2:3980
+3093:2:3981
+3094:2:3989
+3095:2:3990
+3096:2:3994
+3097:2:3995
+3098:2:4003
+3099:2:4008
+3100:2:4012
+3101:2:4013
+3102:2:4021
+3103:2:4022
+3104:2:4026
+3105:2:4027
+3106:2:4021
+3107:2:4022
+3108:2:4026
+3109:2:4027
+3110:2:4035
+3111:2:4040
+3112:2:4041
+3113:2:4052
+3114:2:4060
+3115:2:4061
+3116:2:4065
+3117:2:4070
+3118:2:4071
+3119:2:4082
+3120:2:4083
+3121:2:4084
+3122:2:4082
+3123:2:4083
+3124:2:4084
+3125:2:4095
+3126:2:4103
+3127:0:4533
+3128:2:3127
+3129:0:4533
+3130:2:4109
+3131:2:4110
+3132:2:4114
+3133:2:4115
+3134:2:4123
+3135:2:4124
+3136:2:4128
+3137:2:4129
+3138:2:4137
+3139:2:4142
+3140:2:4146
+3141:2:4147
+3142:2:4155
+3143:2:4156
+3144:2:4160
+3145:2:4161
+3146:2:4155
+3147:2:4156
+3148:2:4160
+3149:2:4161
+3150:2:4169
+3151:2:4174
+3152:2:4175
+3153:2:4186
+3154:2:4194
+3155:2:4195
+3156:2:4199
+3157:2:4204
+3158:2:4205
+3159:2:4216
+3160:2:4217
+3161:2:4218
+3162:2:4216
+3163:2:4217
+3164:2:4218
+3165:2:4229
+3166:0:4533
+3167:2:3127
+3168:0:4533
+3169:1:10
+3170:0:4533
+3171:1:11
+3172:0:4533
+3173:2:3975
+3174:2:3976
+3175:2:3980
+3176:2:3981
+3177:2:3989
+3178:2:3990
+3179:2:3994
+3180:2:3995
+3181:2:4003
+3182:2:4008
+3183:2:4012
+3184:2:4013
+3185:2:4021
+3186:2:4022
+3187:2:4026
+3188:2:4027
+3189:2:4021
+3190:2:4022
+3191:2:4026
+3192:2:4027
+3193:2:4035
+3194:2:4040
+3195:2:4041
+3196:2:4052
+3197:2:4060
+3198:2:4061
+3199:2:4065
+3200:2:4070
+3201:2:4071
+3202:2:4082
+3203:2:4083
+3204:2:4084
+3205:2:4082
+3206:2:4083
+3207:2:4084
+3208:2:4095
+3209:2:4103
+3210:0:4533
+3211:2:3127
+3212:0:4533
+3213:2:4109
+3214:2:4110
+3215:2:4114
+3216:2:4115
+3217:2:4123
+3218:2:4124
+3219:2:4128
+3220:2:4129
+3221:2:4137
+3222:2:4142
+3223:2:4146
+3224:2:4147
+3225:2:4155
+3226:2:4156
+3227:2:4160
+3228:2:4161
+3229:2:4155
+3230:2:4156
+3231:2:4160
+3232:2:4161
+3233:2:4169
+3234:2:4174
+3235:2:4175
+3236:2:4186
+3237:2:4194
+3238:2:4195
+3239:2:4199
+3240:2:4204
+3241:2:4205
+3242:2:4216
+3243:2:4217
+3244:2:4218
+3245:2:4216
+3246:2:4217
+3247:2:4218
+3248:2:4229
+3249:0:4533
+3250:2:3127
+3251:0:4533
+3252:1:12
+3253:1:13
+3254:1:17
+3255:1:18
+3256:1:26
+3257:1:27
+3258:1:28
+3259:1:40
+3260:1:45
+3261:1:49
+3262:1:50
+3263:1:58
+3264:1:59
+3265:1:63
+3266:1:64
+3267:1:58
+3268:1:59
+3269:1:63
+3270:1:64
+3271:1:72
+3272:1:77
+3273:1:78
+3274:1:89
+3275:1:90
+3276:1:91
+3277:1:102
+3278:1:107
+3279:1:108
+3280:1:119
+3281:1:120
+3282:1:121
+3283:1:119
+3284:1:120
+3285:1:121
+3286:1:132
+3287:0:4533
+3288:1:11
+3289:0:4533
+3290:2:3975
+3291:2:3976
+3292:2:3980
+3293:2:3981
+3294:2:3989
+3295:2:3990
+3296:2:3994
+3297:2:3995
+3298:2:4003
+3299:2:4008
+3300:2:4012
+3301:2:4013
+3302:2:4021
+3303:2:4022
+3304:2:4026
+3305:2:4027
+3306:2:4021
+3307:2:4022
+3308:2:4026
+3309:2:4027
+3310:2:4035
+3311:2:4040
+3312:2:4041
+3313:2:4052
+3314:2:4060
+3315:2:4061
+3316:2:4065
+3317:2:4070
+3318:2:4071
+3319:2:4082
+3320:2:4083
+3321:2:4084
+3322:2:4082
+3323:2:4083
+3324:2:4084
+3325:2:4095
+3326:2:4103
+3327:0:4533
+3328:2:3127
+3329:0:4533
+3330:2:4109
+3331:2:4110
+3332:2:4114
+3333:2:4115
+3334:2:4123
+3335:2:4124
+3336:2:4128
+3337:2:4129
+3338:2:4137
+3339:2:4142
+3340:2:4146
+3341:2:4147
+3342:2:4155
+3343:2:4156
+3344:2:4160
+3345:2:4161
+3346:2:4155
+3347:2:4156
+3348:2:4160
+3349:2:4161
+3350:2:4169
+3351:2:4174
+3352:2:4175
+3353:2:4186
+3354:2:4194
+3355:2:4195
+3356:2:4199
+3357:2:4204
+3358:2:4205
+3359:2:4216
+3360:2:4217
+3361:2:4218
+3362:2:4216
+3363:2:4217
+3364:2:4218
+3365:2:4229
+3366:0:4533
+3367:2:3127
+3368:0:4533
+3369:1:141
+3370:1:142
+3371:0:4533
+3372:1:11
+3373:0:4533
+3374:2:3975
+3375:2:3976
+3376:2:3980
+3377:2:3981
+3378:2:3989
+3379:2:3990
+3380:2:3994
+3381:2:3995
+3382:2:4003
+3383:2:4008
+3384:2:4012
+3385:2:4013
+3386:2:4021
+3387:2:4022
+3388:2:4026
+3389:2:4027
+3390:2:4021
+3391:2:4022
+3392:2:4026
+3393:2:4027
+3394:2:4035
+3395:2:4040
+3396:2:4041
+3397:2:4052
+3398:2:4060
+3399:2:4061
+3400:2:4065
+3401:2:4070
+3402:2:4071
+3403:2:4082
+3404:2:4083
+3405:2:4084
+3406:2:4082
+3407:2:4083
+3408:2:4084
+3409:2:4095
+3410:2:4103
+3411:0:4533
+3412:2:3127
+3413:0:4533
+3414:2:4109
+3415:2:4110
+3416:2:4114
+3417:2:4115
+3418:2:4123
+3419:2:4124
+3420:2:4128
+3421:2:4129
+3422:2:4137
+3423:2:4142
+3424:2:4146
+3425:2:4147
+3426:2:4155
+3427:2:4156
+3428:2:4160
+3429:2:4161
+3430:2:4155
+3431:2:4156
+3432:2:4160
+3433:2:4161
+3434:2:4169
+3435:2:4174
+3436:2:4175
+3437:2:4186
+3438:2:4194
+3439:2:4195
+3440:2:4199
+3441:2:4204
+3442:2:4205
+3443:2:4216
+3444:2:4217
+3445:2:4218
+3446:2:4216
+3447:2:4217
+3448:2:4218
+3449:2:4229
+3450:0:4533
+3451:2:3127
+3452:0:4533
+3453:1:148
+3454:1:149
+3455:1:153
+3456:1:154
+3457:1:162
+3458:1:163
+3459:1:167
+3460:1:168
+3461:1:176
+3462:1:181
+3463:1:185
+3464:1:186
+3465:1:194
+3466:1:195
+3467:1:199
+3468:1:200
+3469:1:194
+3470:1:195
+3471:1:199
+3472:1:200
+3473:1:208
+3474:1:213
+3475:1:214
+3476:1:225
+3477:1:226
+3478:1:227
+3479:1:238
+3480:1:243
+3481:1:244
+3482:1:255
+3483:1:256
+3484:1:257
+3485:1:255
+3486:1:256
+3487:1:257
+3488:1:268
+3489:0:4533
+3490:1:11
+3491:0:4533
+3492:2:3975
+3493:2:3976
+3494:2:3980
+3495:2:3981
+3496:2:3989
+3497:2:3990
+3498:2:3994
+3499:2:3995
+3500:2:4003
+3501:2:4008
+3502:2:4012
+3503:2:4013
+3504:2:4021
+3505:2:4022
+3506:2:4026
+3507:2:4027
+3508:2:4021
+3509:2:4022
+3510:2:4026
+3511:2:4027
+3512:2:4035
+3513:2:4040
+3514:2:4041
+3515:2:4052
+3516:2:4060
+3517:2:4061
+3518:2:4065
+3519:2:4070
+3520:2:4071
+3521:2:4082
+3522:2:4083
+3523:2:4084
+3524:2:4082
+3525:2:4083
+3526:2:4084
+3527:2:4095
+3528:2:4103
+3529:0:4533
+3530:2:3127
+3531:0:4533
+3532:2:4109
+3533:2:4110
+3534:2:4114
+3535:2:4115
+3536:2:4123
+3537:2:4124
+3538:2:4128
+3539:2:4129
+3540:2:4137
+3541:2:4142
+3542:2:4146
+3543:2:4147
+3544:2:4155
+3545:2:4156
+3546:2:4160
+3547:2:4161
+3548:2:4155
+3549:2:4156
+3550:2:4160
+3551:2:4161
+3552:2:4169
+3553:2:4174
+3554:2:4175
+3555:2:4186
+3556:2:4194
+3557:2:4195
+3558:2:4199
+3559:2:4204
+3560:2:4205
+3561:2:4216
+3562:2:4217
+3563:2:4218
+3564:2:4216
+3565:2:4217
+3566:2:4218
+3567:2:4229
+3568:0:4533
+3569:2:3127
+3570:0:4533
+3571:1:277
+3572:1:278
+3573:1:282
+3574:1:283
+3575:1:291
+3576:1:292
+3577:1:296
+3578:1:297
+3579:1:305
+3580:1:310
+3581:1:314
+3582:1:315
+3583:1:323
+3584:1:324
+3585:1:328
+3586:1:329
+3587:1:323
+3588:1:324
+3589:1:328
+3590:1:329
+3591:1:337
+3592:1:342
+3593:1:343
+3594:1:354
+3595:1:355
+3596:1:356
+3597:1:367
+3598:1:372
+3599:1:373
+3600:1:384
+3601:1:385
+3602:1:386
+3603:1:384
+3604:1:385
+3605:1:386
+3606:1:397
+3607:1:404
+3608:0:4533
+3609:1:11
+3610:0:4533
+3611:2:3975
+3612:2:3976
+3613:2:3980
+3614:2:3981
+3615:2:3989
+3616:2:3990
+3617:2:3994
+3618:2:3995
+3619:2:4003
+3620:2:4008
+3621:2:4012
+3622:2:4013
+3623:2:4021
+3624:2:4022
+3625:2:4026
+3626:2:4027
+3627:2:4021
+3628:2:4022
+3629:2:4026
+3630:2:4027
+3631:2:4035
+3632:2:4040
+3633:2:4041
+3634:2:4052
+3635:2:4060
+3636:2:4061
+3637:2:4065
+3638:2:4070
+3639:2:4071
+3640:2:4082
+3641:2:4083
+3642:2:4084
+3643:2:4082
+3644:2:4083
+3645:2:4084
+3646:2:4095
+3647:2:4103
+3648:0:4533
+3649:2:3127
+3650:0:4533
+3651:2:4109
+3652:2:4110
+3653:2:4114
+3654:2:4115
+3655:2:4123
+3656:2:4124
+3657:2:4128
+3658:2:4129
+3659:2:4137
+3660:2:4142
+3661:2:4146
+3662:2:4147
+3663:2:4155
+3664:2:4156
+3665:2:4160
+3666:2:4161
+3667:2:4155
+3668:2:4156
+3669:2:4160
+3670:2:4161
+3671:2:4169
+3672:2:4174
+3673:2:4175
+3674:2:4186
+3675:2:4194
+3676:2:4195
+3677:2:4199
+3678:2:4204
+3679:2:4205
+3680:2:4216
+3681:2:4217
+3682:2:4218
+3683:2:4216
+3684:2:4217
+3685:2:4218
+3686:2:4229
+3687:0:4533
+3688:2:3127
+3689:0:4533
+3690:1:540
+3691:1:544
+3692:1:545
+3693:1:549
+3694:1:550
+3695:1:558
+3696:1:566
+3697:1:567
+3698:1:571
+3699:1:575
+3700:1:576
+3701:1:571
+3702:1:575
+3703:1:576
+3704:1:580
+3705:1:587
+3706:1:594
+3707:1:595
+3708:1:602
+3709:1:607
+3710:1:614
+3711:1:615
+3712:1:614
+3713:1:615
+3714:1:622
+3715:0:4533
+3716:1:11
+3717:0:4533
+3718:2:3975
+3719:2:3976
+3720:2:3980
+3721:2:3981
+3722:2:3989
+3723:2:3990
+3724:2:3994
+3725:2:3995
+3726:2:4003
+3727:2:4008
+3728:2:4012
+3729:2:4013
+3730:2:4021
+3731:2:4022
+3732:2:4026
+3733:2:4027
+3734:2:4021
+3735:2:4022
+3736:2:4026
+3737:2:4027
+3738:2:4035
+3739:2:4040
+3740:2:4041
+3741:2:4052
+3742:2:4060
+3743:2:4061
+3744:2:4065
+3745:2:4070
+3746:2:4071
+3747:2:4082
+3748:2:4083
+3749:2:4084
+3750:2:4082
+3751:2:4083
+3752:2:4084
+3753:2:4095
+3754:2:4103
+3755:0:4533
+3756:2:3127
+3757:0:4533
+3758:2:4109
+3759:2:4110
+3760:2:4114
+3761:2:4115
+3762:2:4123
+3763:2:4124
+3764:2:4128
+3765:2:4129
+3766:2:4137
+3767:2:4142
+3768:2:4146
+3769:2:4147
+3770:2:4155
+3771:2:4156
+3772:2:4160
+3773:2:4161
+3774:2:4155
+3775:2:4156
+3776:2:4160
+3777:2:4161
+3778:2:4169
+3779:2:4174
+3780:2:4175
+3781:2:4186
+3782:2:4194
+3783:2:4195
+3784:2:4199
+3785:2:4204
+3786:2:4205
+3787:2:4216
+3788:2:4217
+3789:2:4218
+3790:2:4216
+3791:2:4217
+3792:2:4218
+3793:2:4229
+3794:0:4533
+3795:2:3127
+3796:0:4533
+3797:1:632
+3798:1:633
+3799:1:637
+3800:1:638
+3801:1:646
+3802:1:647
+3803:1:651
+3804:1:652
+3805:1:660
+3806:1:665
+3807:1:669
+3808:1:670
+3809:1:678
+3810:1:679
+3811:1:683
+3812:1:684
+3813:1:678
+3814:1:679
+3815:1:683
+3816:1:684
+3817:1:692
+3818:1:697
+3819:1:698
+3820:1:709
+3821:1:710
+3822:1:711
+3823:1:722
+3824:1:727
+3825:1:728
+3826:1:739
+3827:1:740
+3828:1:741
+3829:1:739
+3830:1:740
+3831:1:741
+3832:1:752
+3833:0:4533
+3834:1:11
+3835:0:4533
+3836:2:3975
+3837:2:3976
+3838:2:3980
+3839:2:3981
+3840:2:3989
+3841:2:3990
+3842:2:3994
+3843:2:3995
+3844:2:4003
+3845:2:4008
+3846:2:4012
+3847:2:4013
+3848:2:4021
+3849:2:4022
+3850:2:4026
+3851:2:4027
+3852:2:4021
+3853:2:4022
+3854:2:4026
+3855:2:4027
+3856:2:4035
+3857:2:4040
+3858:2:4041
+3859:2:4052
+3860:2:4060
+3861:2:4061
+3862:2:4065
+3863:2:4070
+3864:2:4071
+3865:2:4082
+3866:2:4083
+3867:2:4084
+3868:2:4082
+3869:2:4083
+3870:2:4084
+3871:2:4095
+3872:2:4103
+3873:0:4533
+3874:2:3127
+3875:0:4533
+3876:2:4109
+3877:2:4110
+3878:2:4114
+3879:2:4115
+3880:2:4123
+3881:2:4124
+3882:2:4128
+3883:2:4129
+3884:2:4137
+3885:2:4142
+3886:2:4146
+3887:2:4147
+3888:2:4155
+3889:2:4156
+3890:2:4160
+3891:2:4161
+3892:2:4155
+3893:2:4156
+3894:2:4160
+3895:2:4161
+3896:2:4169
+3897:2:4174
+3898:2:4175
+3899:2:4186
+3900:2:4194
+3901:2:4195
+3902:2:4199
+3903:2:4204
+3904:2:4205
+3905:2:4216
+3906:2:4217
+3907:2:4218
+3908:2:4216
+3909:2:4217
+3910:2:4218
+3911:2:4229
+3912:0:4533
+3913:2:3127
+3914:0:4533
+3915:1:761
+3916:1:764
+3917:1:765
+3918:0:4533
+3919:1:11
+3920:0:4533
+3921:2:3975
+3922:2:3976
+3923:2:3980
+3924:2:3981
+3925:2:3989
+3926:2:3990
+3927:2:3994
+3928:2:3995
+3929:2:4003
+3930:2:4008
+3931:2:4012
+3932:2:4013
+3933:2:4021
+3934:2:4022
+3935:2:4026
+3936:2:4027
+3937:2:4021
+3938:2:4022
+3939:2:4026
+3940:2:4027
+3941:2:4035
+3942:2:4040
+3943:2:4041
+3944:2:4052
+3945:2:4060
+3946:2:4061
+3947:2:4065
+3948:2:4070
+3949:2:4071
+3950:2:4082
+3951:2:4083
+3952:2:4084
+3953:2:4082
+3954:2:4083
+3955:2:4084
+3956:2:4095
+3957:2:4103
+3958:0:4533
+3959:2:3127
+3960:0:4533
+3961:2:4109
+3962:2:4110
+3963:2:4114
+3964:2:4115
+3965:2:4123
+3966:2:4124
+3967:2:4128
+3968:2:4129
+3969:2:4137
+3970:2:4142
+3971:2:4146
+3972:2:4147
+3973:2:4155
+3974:2:4156
+3975:2:4160
+3976:2:4161
+3977:2:4155
+3978:2:4156
+3979:2:4160
+3980:2:4161
+3981:2:4169
+3982:2:4174
+3983:2:4175
+3984:2:4186
+3985:2:4194
+3986:2:4195
+3987:2:4199
+3988:2:4204
+3989:2:4205
+3990:2:4216
+3991:2:4217
+3992:2:4218
+3993:2:4216
+3994:2:4217
+3995:2:4218
+3996:2:4229
+3997:0:4533
+3998:2:3127
+3999:0:4533
+4000:1:1028
+4001:1:1029
+4002:1:1033
+4003:1:1034
+4004:1:1042
+4005:1:1043
+4006:1:1047
+4007:1:1048
+4008:1:1056
+4009:1:1061
+4010:1:1065
+4011:1:1066
+4012:1:1074
+4013:1:1075
+4014:1:1079
+4015:1:1080
+4016:1:1074
+4017:1:1075
+4018:1:1079
+4019:1:1080
+4020:1:1088
+4021:1:1093
+4022:1:1094
+4023:1:1105
+4024:1:1106
+4025:1:1107
+4026:1:1118
+4027:1:1123
+4028:1:1124
+4029:1:1135
+4030:1:1136
+4031:1:1137
+4032:1:1135
+4033:1:1136
+4034:1:1137
+4035:1:1148
+4036:1:1155
+4037:1:1159
+4038:0:4533
+4039:1:11
+4040:0:4533
+4041:2:3975
+4042:2:3976
+4043:2:3980
+4044:2:3981
+4045:2:3989
+4046:2:3990
+4047:2:3994
+4048:2:3995
+4049:2:4003
+4050:2:4008
+4051:2:4012
+4052:2:4013
+4053:2:4021
+4054:2:4022
+4055:2:4026
+4056:2:4027
+4057:2:4021
+4058:2:4022
+4059:2:4026
+4060:2:4027
+4061:2:4035
+4062:2:4040
+4063:2:4041
+4064:2:4052
+4065:2:4060
+4066:2:4061
+4067:2:4065
+4068:2:4070
+4069:2:4071
+4070:2:4082
+4071:2:4083
+4072:2:4084
+4073:2:4082
+4074:2:4083
+4075:2:4084
+4076:2:4095
+4077:2:4103
+4078:0:4533
+4079:2:3127
+4080:0:4533
+4081:2:4109
+4082:2:4110
+4083:2:4114
+4084:2:4115
+4085:2:4123
+4086:2:4124
+4087:2:4128
+4088:2:4129
+4089:2:4137
+4090:2:4142
+4091:2:4146
+4092:2:4147
+4093:2:4155
+4094:2:4156
+4095:2:4160
+4096:2:4161
+4097:2:4155
+4098:2:4156
+4099:2:4160
+4100:2:4161
+4101:2:4169
+4102:2:4174
+4103:2:4175
+4104:2:4186
+4105:2:4194
+4106:2:4195
+4107:2:4199
+4108:2:4204
+4109:2:4205
+4110:2:4216
+4111:2:4217
+4112:2:4218
+4113:2:4216
+4114:2:4217
+4115:2:4218
+4116:2:4229
+4117:0:4533
+4118:2:3127
+4119:0:4533
+4120:1:1160
+4121:1:1161
+4122:1:1165
+4123:1:1166
+4124:1:1174
+4125:1:1175
+4126:1:1176
+4127:1:1188
+4128:1:1193
+4129:1:1197
+4130:1:1198
+4131:1:1206
+4132:1:1207
+4133:1:1211
+4134:1:1212
+4135:1:1206
+4136:1:1207
+4137:1:1211
+4138:1:1212
+4139:1:1220
+4140:1:1225
+4141:1:1226
+4142:1:1237
+4143:1:1238
+4144:1:1239
+4145:1:1250
+4146:1:1255
+4147:1:1256
+4148:1:1267
+4149:1:1268
+4150:1:1269
+4151:1:1267
+4152:1:1268
+4153:1:1269
+4154:1:1280
+4155:0:4533
+4156:1:11
+4157:0:4533
+4158:2:3975
+4159:2:3976
+4160:2:3980
+4161:2:3981
+4162:2:3989
+4163:2:3990
+4164:2:3994
+4165:2:3995
+4166:2:4003
+4167:2:4008
+4168:2:4012
+4169:2:4013
+4170:2:4021
+4171:2:4022
+4172:2:4026
+4173:2:4027
+4174:2:4021
+4175:2:4022
+4176:2:4026
+4177:2:4027
+4178:2:4035
+4179:2:4040
+4180:2:4041
+4181:2:4052
+4182:2:4060
+4183:2:4061
+4184:2:4065
+4185:2:4070
+4186:2:4071
+4187:2:4082
+4188:2:4083
+4189:2:4084
+4190:2:4082
+4191:2:4083
+4192:2:4084
+4193:2:4095
+4194:2:4103
+4195:0:4533
+4196:2:3127
+4197:0:4533
+4198:2:4109
+4199:2:4110
+4200:2:4114
+4201:2:4115
+4202:2:4123
+4203:2:4124
+4204:2:4128
+4205:2:4129
+4206:2:4137
+4207:2:4142
+4208:2:4146
+4209:2:4147
+4210:2:4155
+4211:2:4156
+4212:2:4160
+4213:2:4161
+4214:2:4155
+4215:2:4156
+4216:2:4160
+4217:2:4161
+4218:2:4169
+4219:2:4174
+4220:2:4175
+4221:2:4186
+4222:2:4194
+4223:2:4195
+4224:2:4199
+4225:2:4204
+4226:2:4205
+4227:2:4216
+4228:2:4217
+4229:2:4218
+4230:2:4216
+4231:2:4217
+4232:2:4218
+4233:2:4229
+4234:0:4533
+4235:2:3127
+4236:0:4533
+4237:1:1289
+4238:0:4533
+4239:2:3975
+4240:2:3976
+4241:2:3980
+4242:2:3981
+4243:2:3989
+4244:2:3990
+4245:2:3994
+4246:2:3995
+4247:2:4003
+4248:2:4008
+4249:2:4012
+4250:2:4013
+4251:2:4021
+4252:2:4022
+4253:2:4026
+4254:2:4027
+4255:2:4021
+4256:2:4022
+4257:2:4026
+4258:2:4027
+4259:2:4035
+4260:2:4040
+4261:2:4041
+4262:2:4052
+4263:2:4060
+4264:2:4061
+4265:2:4065
+4266:2:4070
+4267:2:4071
+4268:2:4082
+4269:2:4083
+4270:2:4084
+4271:2:4082
+4272:2:4083
+4273:2:4084
+4274:2:4095
+4275:2:4103
+4276:0:4533
+4277:2:3127
+4278:0:4533
+4279:2:4109
+4280:2:4110
+4281:2:4114
+4282:2:4115
+4283:2:4123
+4284:2:4124
+4285:2:4128
+4286:2:4129
+4287:2:4137
+4288:2:4142
+4289:2:4146
+4290:2:4147
+4291:2:4155
+4292:2:4156
+4293:2:4160
+4294:2:4161
+4295:2:4155
+4296:2:4156
+4297:2:4160
+4298:2:4161
+4299:2:4169
+4300:2:4174
+4301:2:4175
+4302:2:4186
+4303:2:4194
+4304:2:4195
+4305:2:4199
+4306:2:4204
+4307:2:4205
+4308:2:4216
+4309:2:4217
+4310:2:4218
+4311:2:4216
+4312:2:4217
+4313:2:4218
+4314:2:4229
+4315:0:4533
+4316:2:3127
+4317:0:4533
+4318:1:3023
+4319:1:3030
+4320:1:3031
+4321:1:3038
+4322:1:3043
+4323:1:3050
+4324:1:3051
+4325:1:3050
+4326:1:3051
+4327:1:3058
+4328:1:3062
+4329:0:4533
+4330:2:3975
+4331:2:3976
+4332:2:3980
+4333:2:3981
+4334:2:3989
+4335:2:3990
+4336:2:3994
+4337:2:3995
+4338:2:4003
+4339:2:4008
+4340:2:4012
+4341:2:4013
+4342:2:4021
+4343:2:4022
+4344:2:4026
+4345:2:4027
+4346:2:4021
+4347:2:4022
+4348:2:4026
+4349:2:4027
+4350:2:4035
+4351:2:4040
+4352:2:4041
+4353:2:4052
+4354:2:4060
+4355:2:4061
+4356:2:4065
+4357:2:4070
+4358:2:4071
+4359:2:4082
+4360:2:4083
+4361:2:4084
+4362:2:4082
+4363:2:4083
+4364:2:4084
+4365:2:4095
+4366:2:4103
+4367:0:4533
+4368:2:3127
+4369:0:4533
+4370:2:4109
+4371:2:4110
+4372:2:4114
+4373:2:4115
+4374:2:4123
+4375:2:4124
+4376:2:4128
+4377:2:4129
+4378:2:4137
+4379:2:4142
+4380:2:4146
+4381:2:4147
+4382:2:4155
+4383:2:4156
+4384:2:4160
+4385:2:4161
+4386:2:4155
+4387:2:4156
+4388:2:4160
+4389:2:4161
+4390:2:4169
+4391:2:4174
+4392:2:4175
+4393:2:4186
+4394:2:4194
+4395:2:4195
+4396:2:4199
+4397:2:4204
+4398:2:4205
+4399:2:4216
+4400:2:4217
+4401:2:4218
+4402:2:4216
+4403:2:4217
+4404:2:4218
+4405:2:4229
+4406:0:4533
+4407:2:3127
+4408:0:4533
+4409:1:1291
+4410:1:1292
+4411:0:4533
+4412:1:11
+4413:0:4533
+4414:2:3975
+4415:2:3976
+4416:2:3980
+4417:2:3981
+4418:2:3989
+4419:2:3990
+4420:2:3994
+4421:2:3995
+4422:2:4003
+4423:2:4008
+4424:2:4012
+4425:2:4013
+4426:2:4021
+4427:2:4022
+4428:2:4026
+4429:2:4027
+4430:2:4021
+4431:2:4022
+4432:2:4026
+4433:2:4027
+4434:2:4035
+4435:2:4040
+4436:2:4041
+4437:2:4052
+4438:2:4060
+4439:2:4061
+4440:2:4065
+4441:2:4070
+4442:2:4071
+4443:2:4082
+4444:2:4083
+4445:2:4084
+4446:2:4082
+4447:2:4083
+4448:2:4084
+4449:2:4095
+4450:2:4103
+4451:0:4533
+4452:2:3127
+4453:0:4533
+4454:2:4109
+4455:2:4110
+4456:2:4114
+4457:2:4115
+4458:2:4123
+4459:2:4124
+4460:2:4128
+4461:2:4129
+4462:2:4137
+4463:2:4142
+4464:2:4146
+4465:2:4147
+4466:2:4155
+4467:2:4156
+4468:2:4160
+4469:2:4161
+4470:2:4155
+4471:2:4156
+4472:2:4160
+4473:2:4161
+4474:2:4169
+4475:2:4174
+4476:2:4175
+4477:2:4186
+4478:2:4194
+4479:2:4195
+4480:2:4199
+4481:2:4204
+4482:2:4205
+4483:2:4216
+4484:2:4217
+4485:2:4218
+4486:2:4216
+4487:2:4217
+4488:2:4218
+4489:2:4229
+4490:0:4533
+4491:2:3127
+4492:0:4533
+4493:1:1293
+4494:1:1294
+4495:1:1298
+4496:1:1299
+4497:1:1307
+4498:1:1308
+4499:1:1312
+4500:1:1313
+4501:1:1321
+4502:1:1326
+4503:1:1330
+4504:1:1331
+4505:1:1339
+4506:1:1340
+4507:1:1344
+4508:1:1345
+4509:1:1339
+4510:1:1340
+4511:1:1344
+4512:1:1345
+4513:1:1353
+4514:1:1358
+4515:1:1359
+4516:1:1370
+4517:1:1371
+4518:1:1372
+4519:1:1383
+4520:1:1388
+4521:1:1389
+4522:1:1400
+4523:1:1401
+4524:1:1402
+4525:1:1400
+4526:1:1401
+4527:1:1402
+4528:1:1413
+4529:0:4533
+4530:1:11
+4531:0:4533
+4532:2:3975
+4533:2:3976
+4534:2:3980
+4535:2:3981
+4536:2:3989
+4537:2:3990
+4538:2:3994
+4539:2:3995
+4540:2:4003
+4541:2:4008
+4542:2:4012
+4543:2:4013
+4544:2:4021
+4545:2:4022
+4546:2:4026
+4547:2:4027
+4548:2:4021
+4549:2:4022
+4550:2:4026
+4551:2:4027
+4552:2:4035
+4553:2:4040
+4554:2:4041
+4555:2:4052
+4556:2:4060
+4557:2:4061
+4558:2:4065
+4559:2:4070
+4560:2:4071
+4561:2:4082
+4562:2:4083
+4563:2:4084
+4564:2:4082
+4565:2:4083
+4566:2:4084
+4567:2:4095
+4568:2:4103
+4569:0:4533
+4570:2:3127
+4571:0:4533
+4572:2:4109
+4573:2:4110
+4574:2:4114
+4575:2:4115
+4576:2:4123
+4577:2:4124
+4578:2:4128
+4579:2:4129
+4580:2:4137
+4581:2:4142
+4582:2:4146
+4583:2:4147
+4584:2:4155
+4585:2:4156
+4586:2:4160
+4587:2:4161
+4588:2:4155
+4589:2:4156
+4590:2:4160
+4591:2:4161
+4592:2:4169
+4593:2:4174
+4594:2:4175
+4595:2:4186
+4596:2:4194
+4597:2:4195
+4598:2:4199
+4599:2:4204
+4600:2:4205
+4601:2:4216
+4602:2:4217
+4603:2:4218
+4604:2:4216
+4605:2:4217
+4606:2:4218
+4607:2:4229
+4608:0:4533
+4609:2:3127
+4610:0:4533
+4611:1:1422
+4612:1:1423
+4613:1:1427
+4614:1:1428
+4615:1:1436
+4616:1:1437
+4617:1:1441
+4618:1:1442
+4619:1:1450
+4620:1:1455
+4621:1:1459
+4622:1:1460
+4623:1:1468
+4624:1:1469
+4625:1:1473
+4626:1:1474
+4627:1:1468
+4628:1:1469
+4629:1:1473
+4630:1:1474
+4631:1:1482
+4632:1:1487
+4633:1:1488
+4634:1:1499
+4635:1:1500
+4636:1:1501
+4637:1:1512
+4638:1:1517
+4639:1:1518
+4640:1:1529
+4641:1:1530
+4642:1:1531
+4643:1:1529
+4644:1:1530
+4645:1:1531
+4646:1:1542
+4647:1:1549
+4648:1:1553
+4649:0:4533
+4650:1:11
+4651:0:4533
+4652:2:3975
+4653:2:3976
+4654:2:3980
+4655:2:3981
+4656:2:3989
+4657:2:3990
+4658:2:3994
+4659:2:3995
+4660:2:4003
+4661:2:4008
+4662:2:4012
+4663:2:4013
+4664:2:4021
+4665:2:4022
+4666:2:4026
+4667:2:4027
+4668:2:4021
+4669:2:4022
+4670:2:4026
+4671:2:4027
+4672:2:4035
+4673:2:4040
+4674:2:4041
+4675:2:4052
+4676:2:4060
+4677:2:4061
+4678:2:4065
+4679:2:4070
+4680:2:4071
+4681:2:4082
+4682:2:4083
+4683:2:4084
+4684:2:4082
+4685:2:4083
+4686:2:4084
+4687:2:4095
+4688:2:4103
+4689:0:4533
+4690:2:3127
+4691:0:4533
+4692:2:4109
+4693:2:4110
+4694:2:4114
+4695:2:4115
+4696:2:4123
+4697:2:4124
+4698:2:4128
+4699:2:4129
+4700:2:4137
+4701:2:4142
+4702:2:4146
+4703:2:4147
+4704:2:4155
+4705:2:4156
+4706:2:4160
+4707:2:4161
+4708:2:4155
+4709:2:4156
+4710:2:4160
+4711:2:4161
+4712:2:4169
+4713:2:4174
+4714:2:4175
+4715:2:4186
+4716:2:4194
+4717:2:4195
+4718:2:4199
+4719:2:4204
+4720:2:4205
+4721:2:4216
+4722:2:4217
+4723:2:4218
+4724:2:4216
+4725:2:4217
+4726:2:4218
+4727:2:4229
+4728:0:4533
+4729:2:3127
+4730:0:4533
+4731:1:1554
+4732:1:1558
+4733:1:1559
+4734:1:1563
+4735:1:1564
+4736:1:1572
+4737:1:1580
+4738:1:1581
+4739:1:1585
+4740:1:1589
+4741:1:1590
+4742:1:1585
+4743:1:1589
+4744:1:1590
+4745:1:1594
+4746:1:1601
+4747:1:1608
+4748:1:1609
+4749:1:1616
+4750:1:1621
+4751:1:1628
+4752:1:1629
+4753:1:1628
+4754:1:1629
+4755:1:1636
+4756:0:4533
+4757:1:11
+4758:0:4533
+4759:2:3975
+4760:2:3976
+4761:2:3980
+4762:2:3981
+4763:2:3989
+4764:2:3990
+4765:2:3994
+4766:2:3995
+4767:2:4003
+4768:2:4008
+4769:2:4012
+4770:2:4013
+4771:2:4021
+4772:2:4022
+4773:2:4026
+4774:2:4027
+4775:2:4021
+4776:2:4022
+4777:2:4026
+4778:2:4027
+4779:2:4035
+4780:2:4040
+4781:2:4041
+4782:2:4052
+4783:2:4060
+4784:2:4061
+4785:2:4065
+4786:2:4070
+4787:2:4071
+4788:2:4082
+4789:2:4083
+4790:2:4084
+4791:2:4082
+4792:2:4083
+4793:2:4084
+4794:2:4095
+4795:2:4103
+4796:0:4533
+4797:2:3127
+4798:0:4533
+4799:2:4109
+4800:2:4110
+4801:2:4114
+4802:2:4115
+4803:2:4123
+4804:2:4124
+4805:2:4128
+4806:2:4129
+4807:2:4137
+4808:2:4142
+4809:2:4146
+4810:2:4147
+4811:2:4155
+4812:2:4156
+4813:2:4160
+4814:2:4161
+4815:2:4155
+4816:2:4156
+4817:2:4160
+4818:2:4161
+4819:2:4169
+4820:2:4174
+4821:2:4175
+4822:2:4186
+4823:2:4194
+4824:2:4195
+4825:2:4199
+4826:2:4204
+4827:2:4205
+4828:2:4216
+4829:2:4217
+4830:2:4218
+4831:2:4216
+4832:2:4217
+4833:2:4218
+4834:2:4229
+4835:0:4533
+4836:2:3127
+4837:0:4533
+4838:1:1646
+4839:1:1647
+4840:1:1651
+4841:1:1652
+4842:1:1660
+4843:1:1661
+4844:1:1665
+4845:1:1666
+4846:1:1674
+4847:1:1679
+4848:1:1683
+4849:1:1684
+4850:1:1692
+4851:1:1693
+4852:1:1697
+4853:1:1698
+4854:1:1692
+4855:1:1693
+4856:1:1697
+4857:1:1698
+4858:1:1706
+4859:1:1711
+4860:1:1712
+4861:1:1723
+4862:1:1724
+4863:1:1725
+4864:1:1736
+4865:1:1741
+4866:1:1742
+4867:1:1753
+4868:1:1754
+4869:1:1755
+4870:1:1753
+4871:1:1754
+4872:1:1755
+4873:1:1766
+4874:0:4533
+4875:1:11
+4876:0:4533
+4877:2:3975
+4878:2:3976
+4879:2:3980
+4880:2:3981
+4881:2:3989
+4882:2:3990
+4883:2:3994
+4884:2:3995
+4885:2:4003
+4886:2:4008
+4887:2:4012
+4888:2:4013
+4889:2:4021
+4890:2:4022
+4891:2:4026
+4892:2:4027
+4893:2:4021
+4894:2:4022
+4895:2:4026
+4896:2:4027
+4897:2:4035
+4898:2:4040
+4899:2:4041
+4900:2:4052
+4901:2:4060
+4902:2:4061
+4903:2:4065
+4904:2:4070
+4905:2:4071
+4906:2:4082
+4907:2:4083
+4908:2:4084
+4909:2:4082
+4910:2:4083
+4911:2:4084
+4912:2:4095
+4913:2:4103
+4914:0:4533
+4915:2:3127
+4916:0:4533
+4917:2:4109
+4918:2:4110
+4919:2:4114
+4920:2:4115
+4921:2:4123
+4922:2:4124
+4923:2:4128
+4924:2:4129
+4925:2:4137
+4926:2:4142
+4927:2:4146
+4928:2:4147
+4929:2:4155
+4930:2:4156
+4931:2:4160
+4932:2:4161
+4933:2:4155
+4934:2:4156
+4935:2:4160
+4936:2:4161
+4937:2:4169
+4938:2:4174
+4939:2:4175
+4940:2:4186
+4941:2:4194
+4942:2:4195
+4943:2:4199
+4944:2:4204
+4945:2:4205
+4946:2:4216
+4947:2:4217
+4948:2:4218
+4949:2:4216
+4950:2:4217
+4951:2:4218
+4952:2:4229
+4953:0:4533
+4954:2:3127
+4955:0:4533
+4956:1:1775
+4957:1:1776
+4958:1:1780
+4959:1:1781
+4960:1:1789
+4961:1:1790
+4962:1:1794
+4963:1:1795
+4964:1:1803
+4965:1:1808
+4966:1:1812
+4967:1:1813
+4968:1:1821
+4969:1:1822
+4970:1:1826
+4971:1:1827
+4972:1:1821
+4973:1:1822
+4974:1:1826
+4975:1:1827
+4976:1:1835
+4977:1:1840
+4978:1:1841
+4979:1:1852
+4980:1:1853
+4981:1:1854
+4982:1:1865
+4983:1:1870
+4984:1:1871
+4985:1:1882
+4986:1:1883
+4987:1:1884
+4988:1:1882
+4989:1:1883
+4990:1:1884
+4991:1:1895
+4992:1:1902
+4993:1:1906
+4994:0:4533
+4995:1:11
+4996:0:4533
+4997:2:3975
+4998:2:3976
+4999:2:3980
+5000:2:3981
+5001:2:3989
+5002:2:3990
+5003:2:3994
+5004:2:3995
+5005:2:4003
+5006:2:4008
+5007:2:4012
+5008:2:4013
+5009:2:4021
+5010:2:4022
+5011:2:4026
+5012:2:4027
+5013:2:4021
+5014:2:4022
+5015:2:4026
+5016:2:4027
+5017:2:4035
+5018:2:4040
+5019:2:4041
+5020:2:4052
+5021:2:4060
+5022:2:4061
+5023:2:4065
+5024:2:4070
+5025:2:4071
+5026:2:4082
+5027:2:4083
+5028:2:4084
+5029:2:4082
+5030:2:4083
+5031:2:4084
+5032:2:4095
+5033:2:4103
+5034:0:4533
+5035:2:3127
+5036:0:4533
+5037:2:4109
+5038:2:4110
+5039:2:4114
+5040:2:4115
+5041:2:4123
+5042:2:4124
+5043:2:4128
+5044:2:4129
+5045:2:4137
+5046:2:4142
+5047:2:4146
+5048:2:4147
+5049:2:4155
+5050:2:4156
+5051:2:4160
+5052:2:4161
+5053:2:4155
+5054:2:4156
+5055:2:4160
+5056:2:4161
+5057:2:4169
+5058:2:4174
+5059:2:4175
+5060:2:4186
+5061:2:4194
+5062:2:4195
+5063:2:4199
+5064:2:4204
+5065:2:4205
+5066:2:4216
+5067:2:4217
+5068:2:4218
+5069:2:4216
+5070:2:4217
+5071:2:4218
+5072:2:4229
+5073:0:4533
+5074:2:3127
+5075:0:4533
+5076:1:1907
+5077:1:1908
+5078:1:1912
+5079:1:1913
+5080:1:1921
+5081:1:1922
+5082:1:1923
+5083:1:1935
+5084:1:1940
+5085:1:1944
+5086:1:1945
+5087:1:1953
+5088:1:1954
+5089:1:1958
+5090:1:1959
+5091:1:1953
+5092:1:1954
+5093:1:1958
+5094:1:1959
+5095:1:1967
+5096:1:1972
+5097:1:1973
+5098:1:1984
+5099:1:1985
+5100:1:1986
+5101:1:1997
+5102:1:2002
+5103:1:2003
+5104:1:2014
+5105:1:2015
+5106:1:2016
+5107:1:2014
+5108:1:2015
+5109:1:2016
+5110:1:2027
+5111:0:4533
+5112:1:11
+5113:0:4533
+5114:2:3975
+5115:2:3976
+5116:2:3980
+5117:2:3981
+5118:2:3989
+5119:2:3990
+5120:2:3994
+5121:2:3995
+5122:2:4003
+5123:2:4008
+5124:2:4012
+5125:2:4013
+5126:2:4021
+5127:2:4022
+5128:2:4026
+5129:2:4027
+5130:2:4021
+5131:2:4022
+5132:2:4026
+5133:2:4027
+5134:2:4035
+5135:2:4040
+5136:2:4041
+5137:2:4052
+5138:2:4060
+5139:2:4061
+5140:2:4065
+5141:2:4070
+5142:2:4071
+5143:2:4082
+5144:2:4083
+5145:2:4084
+5146:2:4082
+5147:2:4083
+5148:2:4084
+5149:2:4095
+5150:2:4103
+5151:0:4533
+5152:2:3127
+5153:0:4533
+5154:2:4109
+5155:2:4110
+5156:2:4114
+5157:2:4115
+5158:2:4123
+5159:2:4124
+5160:2:4128
+5161:2:4129
+5162:2:4137
+5163:2:4142
+5164:2:4146
+5165:2:4147
+5166:2:4155
+5167:2:4156
+5168:2:4160
+5169:2:4161
+5170:2:4155
+5171:2:4156
+5172:2:4160
+5173:2:4161
+5174:2:4169
+5175:2:4174
+5176:2:4175
+5177:2:4186
+5178:2:4194
+5179:2:4195
+5180:2:4199
+5181:2:4204
+5182:2:4205
+5183:2:4216
+5184:2:4217
+5185:2:4218
+5186:2:4216
+5187:2:4217
+5188:2:4218
+5189:2:4229
+5190:0:4533
+5191:2:3127
+5192:0:4533
+5193:1:2036
+5194:1:2037
+5195:0:4533
+5196:1:11
+5197:0:4533
+5198:2:3975
+5199:2:3976
+5200:2:3980
+5201:2:3981
+5202:2:3989
+5203:2:3990
+5204:2:3994
+5205:2:3995
+5206:2:4003
+5207:2:4008
+5208:2:4012
+5209:2:4013
+5210:2:4021
+5211:2:4022
+5212:2:4026
+5213:2:4027
+5214:2:4021
+5215:2:4022
+5216:2:4026
+5217:2:4027
+5218:2:4035
+5219:2:4040
+5220:2:4041
+5221:2:4052
+5222:2:4060
+5223:2:4061
+5224:2:4065
+5225:2:4070
+5226:2:4071
+5227:2:4082
+5228:2:4083
+5229:2:4084
+5230:2:4082
+5231:2:4083
+5232:2:4084
+5233:2:4095
+5234:2:4103
+5235:0:4533
+5236:2:3127
+5237:0:4533
+5238:2:4109
+5239:2:4110
+5240:2:4114
+5241:2:4115
+5242:2:4123
+5243:2:4124
+5244:2:4128
+5245:2:4129
+5246:2:4137
+5247:2:4142
+5248:2:4146
+5249:2:4147
+5250:2:4155
+5251:2:4156
+5252:2:4160
+5253:2:4161
+5254:2:4155
+5255:2:4156
+5256:2:4160
+5257:2:4161
+5258:2:4169
+5259:2:4174
+5260:2:4175
+5261:2:4186
+5262:2:4194
+5263:2:4195
+5264:2:4199
+5265:2:4204
+5266:2:4205
+5267:2:4216
+5268:2:4217
+5269:2:4218
+5270:2:4216
+5271:2:4217
+5272:2:4218
+5273:2:4229
+5274:0:4533
+5275:2:3127
+5276:0:4533
+5277:1:2043
+5278:1:2044
+5279:1:2048
+5280:1:2049
+5281:1:2057
+5282:1:2058
+5283:1:2062
+5284:1:2063
+5285:1:2071
+5286:1:2076
+5287:1:2080
+5288:1:2081
+5289:1:2089
+5290:1:2090
+5291:1:2094
+5292:1:2095
+5293:1:2089
+5294:1:2090
+5295:1:2094
+5296:1:2095
+5297:1:2103
+5298:1:2108
+5299:1:2109
+5300:1:2120
+5301:1:2121
+5302:1:2122
+5303:1:2133
+5304:1:2138
+5305:1:2139
+5306:1:2150
+5307:1:2151
+5308:1:2152
+5309:1:2150
+5310:1:2151
+5311:1:2152
+5312:1:2163
+5313:0:4533
+5314:1:11
+5315:0:4533
+5316:2:3975
+5317:2:3976
+5318:2:3980
+5319:2:3981
+5320:2:3989
+5321:2:3990
+5322:2:3994
+5323:2:3995
+5324:2:4003
+5325:2:4008
+5326:2:4012
+5327:2:4013
+5328:2:4021
+5329:2:4022
+5330:2:4026
+5331:2:4027
+5332:2:4021
+5333:2:4022
+5334:2:4026
+5335:2:4027
+5336:2:4035
+5337:2:4040
+5338:2:4041
+5339:2:4052
+5340:2:4060
+5341:2:4061
+5342:2:4065
+5343:2:4070
+5344:2:4071
+5345:2:4082
+5346:2:4083
+5347:2:4084
+5348:2:4082
+5349:2:4083
+5350:2:4084
+5351:2:4095
+5352:2:4103
+5353:0:4533
+5354:2:3127
+5355:0:4533
+5356:2:4109
+5357:2:4110
+5358:2:4114
+5359:2:4115
+5360:2:4123
+5361:2:4124
+5362:2:4128
+5363:2:4129
+5364:2:4137
+5365:2:4142
+5366:2:4146
+5367:2:4147
+5368:2:4155
+5369:2:4156
+5370:2:4160
+5371:2:4161
+5372:2:4155
+5373:2:4156
+5374:2:4160
+5375:2:4161
+5376:2:4169
+5377:2:4174
+5378:2:4175
+5379:2:4186
+5380:2:4194
+5381:2:4195
+5382:2:4199
+5383:2:4204
+5384:2:4205
+5385:2:4216
+5386:2:4217
+5387:2:4218
+5388:2:4216
+5389:2:4217
+5390:2:4218
+5391:2:4229
+5392:0:4533
+5393:2:3127
+5394:0:4533
+5395:1:2172
+5396:1:2173
+5397:1:2177
+5398:1:2178
+5399:1:2186
+5400:1:2187
+5401:1:2191
+5402:1:2192
+5403:1:2200
+5404:1:2205
+5405:1:2209
+5406:1:2210
+5407:1:2218
+5408:1:2219
+5409:1:2223
+5410:1:2224
+5411:1:2218
+5412:1:2219
+5413:1:2223
+5414:1:2224
+5415:1:2232
+5416:1:2237
+5417:1:2238
+5418:1:2249
+5419:1:2250
+5420:1:2251
+5421:1:2262
+5422:1:2267
+5423:1:2268
+5424:1:2279
+5425:1:2280
+5426:1:2281
+5427:1:2279
+5428:1:2280
+5429:1:2281
+5430:1:2292
+5431:1:2299
+5432:0:4533
+5433:1:11
+5434:0:4533
+5435:2:3975
+5436:2:3976
+5437:2:3980
+5438:2:3981
+5439:2:3989
+5440:2:3990
+5441:2:3994
+5442:2:3995
+5443:2:4003
+5444:2:4008
+5445:2:4012
+5446:2:4013
+5447:2:4021
+5448:2:4022
+5449:2:4026
+5450:2:4027
+5451:2:4021
+5452:2:4022
+5453:2:4026
+5454:2:4027
+5455:2:4035
+5456:2:4040
+5457:2:4041
+5458:2:4052
+5459:2:4060
+5460:2:4061
+5461:2:4065
+5462:2:4070
+5463:2:4071
+5464:2:4082
+5465:2:4083
+5466:2:4084
+5467:2:4082
+5468:2:4083
+5469:2:4084
+5470:2:4095
+5471:2:4103
+5472:0:4533
+5473:2:3127
+5474:0:4533
+5475:2:4109
+5476:2:4110
+5477:2:4114
+5478:2:4115
+5479:2:4123
+5480:2:4124
+5481:2:4128
+5482:2:4129
+5483:2:4137
+5484:2:4142
+5485:2:4146
+5486:2:4147
+5487:2:4155
+5488:2:4156
+5489:2:4160
+5490:2:4161
+5491:2:4155
+5492:2:4156
+5493:2:4160
+5494:2:4161
+5495:2:4169
+5496:2:4174
+5497:2:4175
+5498:2:4186
+5499:2:4194
+5500:2:4195
+5501:2:4199
+5502:2:4204
+5503:2:4205
+5504:2:4216
+5505:2:4217
+5506:2:4218
+5507:2:4216
+5508:2:4217
+5509:2:4218
+5510:2:4229
+5511:0:4533
+5512:2:3127
+5513:0:4533
+5514:1:2435
+5515:1:2439
+5516:1:2440
+5517:1:2444
+5518:1:2445
+5519:1:2453
+5520:1:2461
+5521:1:2462
+5522:1:2466
+5523:1:2470
+5524:1:2471
+5525:1:2466
+5526:1:2470
+5527:1:2471
+5528:1:2475
+5529:1:2482
+5530:1:2489
+5531:1:2490
+5532:1:2497
+5533:1:2502
+5534:1:2509
+5535:1:2510
+5536:1:2509
+5537:1:2510
+5538:1:2517
+5539:0:4533
+5540:1:11
+5541:0:4533
+5542:2:3975
+5543:2:3976
+5544:2:3980
+5545:2:3981
+5546:2:3989
+5547:2:3990
+5548:2:3994
+5549:2:3995
+5550:2:4003
+5551:2:4008
+5552:2:4012
+5553:2:4013
+5554:2:4021
+5555:2:4022
+5556:2:4026
+5557:2:4027
+5558:2:4021
+5559:2:4022
+5560:2:4026
+5561:2:4027
+5562:2:4035
+5563:2:4040
+5564:2:4041
+5565:2:4052
+5566:2:4060
+5567:2:4061
+5568:2:4065
+5569:2:4070
+5570:2:4071
+5571:2:4082
+5572:2:4083
+5573:2:4084
+5574:2:4082
+5575:2:4083
+5576:2:4084
+5577:2:4095
+5578:2:4103
+5579:0:4533
+5580:2:3127
+5581:0:4533
+5582:2:4109
+5583:2:4110
+5584:2:4114
+5585:2:4115
+5586:2:4123
+5587:2:4124
+5588:2:4128
+5589:2:4129
+5590:2:4137
+5591:2:4142
+5592:2:4146
+5593:2:4147
+5594:2:4155
+5595:2:4156
+5596:2:4160
+5597:2:4161
+5598:2:4155
+5599:2:4156
+5600:2:4160
+5601:2:4161
+5602:2:4169
+5603:2:4174
+5604:2:4175
+5605:2:4186
+5606:2:4194
+5607:2:4195
+5608:2:4199
+5609:2:4204
+5610:2:4205
+5611:2:4216
+5612:2:4217
+5613:2:4218
+5614:2:4216
+5615:2:4217
+5616:2:4218
+5617:2:4229
+5618:0:4533
+5619:2:3127
+5620:0:4533
+5621:1:2527
+5622:1:2528
+5623:1:2532
+5624:1:2533
+5625:1:2541
+5626:1:2542
+5627:1:2546
+5628:1:2547
+5629:1:2555
+5630:1:2560
+5631:1:2564
+5632:1:2565
+5633:1:2573
+5634:1:2574
+5635:1:2578
+5636:1:2579
+5637:1:2573
+5638:1:2574
+5639:1:2578
+5640:1:2579
+5641:1:2587
+5642:1:2592
+5643:1:2593
+5644:1:2604
+5645:1:2605
+5646:1:2606
+5647:1:2617
+5648:1:2622
+5649:1:2623
+5650:1:2634
+5651:1:2635
+5652:1:2636
+5653:1:2634
+5654:1:2635
+5655:1:2636
+5656:1:2647
+5657:0:4533
+5658:1:11
+5659:0:4533
+5660:2:3975
+5661:2:3976
+5662:2:3980
+5663:2:3981
+5664:2:3989
+5665:2:3990
+5666:2:3994
+5667:2:3995
+5668:2:4003
+5669:2:4008
+5670:2:4012
+5671:2:4013
+5672:2:4021
+5673:2:4022
+5674:2:4026
+5675:2:4027
+5676:2:4021
+5677:2:4022
+5678:2:4026
+5679:2:4027
+5680:2:4035
+5681:2:4040
+5682:2:4041
+5683:2:4052
+5684:2:4060
+5685:2:4061
+5686:2:4065
+5687:2:4070
+5688:2:4071
+5689:2:4082
+5690:2:4083
+5691:2:4084
+5692:2:4082
+5693:2:4083
+5694:2:4084
+5695:2:4095
+5696:2:4103
+5697:0:4533
+5698:2:3127
+5699:0:4533
+5700:2:4109
+5701:2:4110
+5702:2:4114
+5703:2:4115
+5704:2:4123
+5705:2:4124
+5706:2:4128
+5707:2:4129
+5708:2:4137
+5709:2:4142
+5710:2:4146
+5711:2:4147
+5712:2:4155
+5713:2:4156
+5714:2:4160
+5715:2:4161
+5716:2:4155
+5717:2:4156
+5718:2:4160
+5719:2:4161
+5720:2:4169
+5721:2:4174
+5722:2:4175
+5723:2:4186
+5724:2:4194
+5725:2:4195
+5726:2:4199
+5727:2:4204
+5728:2:4205
+5729:2:4216
+5730:2:4217
+5731:2:4218
+5732:2:4216
+5733:2:4217
+5734:2:4218
+5735:2:4229
+5736:0:4533
+5737:2:3127
+5738:0:4533
+5739:1:2656
+5740:0:4533
+5741:2:3975
+5742:2:3976
+5743:2:3980
+5744:2:3981
+5745:2:3989
+5746:2:3990
+5747:2:3994
+5748:2:3995
+5749:2:4003
+5750:2:4008
+5751:2:4012
+5752:2:4013
+5753:2:4021
+5754:2:4022
+5755:2:4026
+5756:2:4027
+5757:2:4021
+5758:2:4022
+5759:2:4026
+5760:2:4027
+5761:2:4035
+5762:2:4040
+5763:2:4041
+5764:2:4052
+5765:2:4060
+5766:2:4061
+5767:2:4065
+5768:2:4070
+5769:2:4071
+5770:2:4082
+5771:2:4083
+5772:2:4084
+5773:2:4082
+5774:2:4083
+5775:2:4084
+5776:2:4095
+5777:2:4103
+5778:0:4533
+5779:2:3127
+5780:0:4533
+5781:2:4109
+5782:2:4110
+5783:2:4114
+5784:2:4115
+5785:2:4123
+5786:2:4124
+5787:2:4128
+5788:2:4129
+5789:2:4137
+5790:2:4142
+5791:2:4146
+5792:2:4147
+5793:2:4155
+5794:2:4156
+5795:2:4160
+5796:2:4161
+5797:2:4155
+5798:2:4156
+5799:2:4160
+5800:2:4161
+5801:2:4169
+5802:2:4174
+5803:2:4175
+5804:2:4186
+5805:2:4194
+5806:2:4195
+5807:2:4199
+5808:2:4204
+5809:2:4205
+5810:2:4216
+5811:2:4217
+5812:2:4218
+5813:2:4216
+5814:2:4217
+5815:2:4218
+5816:2:4229
+5817:0:4533
+5818:2:3127
+5819:0:4533
+5820:1:3066
+5821:1:3073
+5822:1:3074
+5823:1:3081
+5824:1:3086
+5825:1:3093
+5826:1:3094
+5827:1:3093
+5828:1:3094
+5829:1:3101
+5830:1:3105
+5831:0:4533
+5832:2:3975
+5833:2:3976
+5834:2:3980
+5835:2:3981
+5836:2:3989
+5837:2:3990
+5838:2:3994
+5839:2:3995
+5840:2:4003
+5841:2:4008
+5842:2:4012
+5843:2:4013
+5844:2:4021
+5845:2:4022
+5846:2:4026
+5847:2:4027
+5848:2:4021
+5849:2:4022
+5850:2:4026
+5851:2:4027
+5852:2:4035
+5853:2:4040
+5854:2:4041
+5855:2:4052
+5856:2:4060
+5857:2:4061
+5858:2:4065
+5859:2:4070
+5860:2:4071
+5861:2:4082
+5862:2:4083
+5863:2:4084
+5864:2:4082
+5865:2:4083
+5866:2:4084
+5867:2:4095
+5868:2:4103
+5869:0:4533
+5870:2:3127
+5871:0:4533
+5872:2:4109
+5873:2:4110
+5874:2:4114
+5875:2:4115
+5876:2:4123
+5877:2:4124
+5878:2:4128
+5879:2:4129
+5880:2:4137
+5881:2:4142
+5882:2:4146
+5883:2:4147
+5884:2:4155
+5885:2:4156
+5886:2:4160
+5887:2:4161
+5888:2:4155
+5889:2:4156
+5890:2:4160
+5891:2:4161
+5892:2:4169
+5893:2:4174
+5894:2:4175
+5895:2:4186
+5896:2:4194
+5897:2:4195
+5898:2:4199
+5899:2:4204
+5900:2:4205
+5901:2:4216
+5902:2:4217
+5903:2:4218
+5904:2:4216
+5905:2:4217
+5906:2:4218
+5907:2:4229
+5908:0:4533
+5909:2:3127
+5910:0:4533
+5911:1:2658
+5912:1:2659
+5913:0:4533
+5914:1:11
+5915:0:4533
+5916:2:3975
+5917:2:3976
+5918:2:3980
+5919:2:3981
+5920:2:3989
+5921:2:3990
+5922:2:3994
+5923:2:3995
+5924:2:4003
+5925:2:4008
+5926:2:4012
+5927:2:4013
+5928:2:4021
+5929:2:4022
+5930:2:4026
+5931:2:4027
+5932:2:4021
+5933:2:4022
+5934:2:4026
+5935:2:4027
+5936:2:4035
+5937:2:4040
+5938:2:4041
+5939:2:4052
+5940:2:4060
+5941:2:4061
+5942:2:4065
+5943:2:4070
+5944:2:4071
+5945:2:4082
+5946:2:4083
+5947:2:4084
+5948:2:4082
+5949:2:4083
+5950:2:4084
+5951:2:4095
+5952:2:4103
+5953:0:4533
+5954:2:3127
+5955:0:4533
+5956:2:4109
+5957:2:4110
+5958:2:4114
+5959:2:4115
+5960:2:4123
+5961:2:4124
+5962:2:4128
+5963:2:4129
+5964:2:4137
+5965:2:4142
+5966:2:4146
+5967:2:4147
+5968:2:4155
+5969:2:4156
+5970:2:4160
+5971:2:4161
+5972:2:4155
+5973:2:4156
+5974:2:4160
+5975:2:4161
+5976:2:4169
+5977:2:4174
+5978:2:4175
+5979:2:4186
+5980:2:4194
+5981:2:4195
+5982:2:4199
+5983:2:4204
+5984:2:4205
+5985:2:4216
+5986:2:4217
+5987:2:4218
+5988:2:4216
+5989:2:4217
+5990:2:4218
+5991:2:4229
+5992:0:4533
+5993:2:3127
+5994:0:4533
+5995:1:2660
+5996:1:2664
+5997:1:2665
+5998:1:2669
+5999:1:2673
+6000:1:2674
+6001:1:2678
+6002:1:2686
+6003:1:2687
+6004:1:2691
+6005:1:2695
+6006:1:2696
+6007:1:2691
+6008:1:2695
+6009:1:2696
+6010:1:2700
+6011:1:2707
+6012:1:2714
+6013:1:2715
+6014:1:2722
+6015:1:2727
+6016:1:2734
+6017:1:2735
+6018:1:2734
+6019:1:2735
+6020:1:2742
+6021:0:4533
+6022:1:11
+6023:0:4533
+6024:2:3975
+6025:2:3976
+6026:2:3980
+6027:2:3981
+6028:2:3989
+6029:2:3990
+6030:2:3994
+6031:2:3995
+6032:2:4003
+6033:2:4008
+6034:2:4012
+6035:2:4013
+6036:2:4021
+6037:2:4022
+6038:2:4026
+6039:2:4027
+6040:2:4021
+6041:2:4022
+6042:2:4026
+6043:2:4027
+6044:2:4035
+6045:2:4040
+6046:2:4041
+6047:2:4052
+6048:2:4060
+6049:2:4061
+6050:2:4065
+6051:2:4070
+6052:2:4071
+6053:2:4082
+6054:2:4083
+6055:2:4084
+6056:2:4082
+6057:2:4083
+6058:2:4084
+6059:2:4095
+6060:2:4103
+6061:0:4533
+6062:2:3127
+6063:0:4533
+6064:2:4109
+6065:2:4110
+6066:2:4114
+6067:2:4115
+6068:2:4123
+6069:2:4124
+6070:2:4128
+6071:2:4129
+6072:2:4137
+6073:2:4142
+6074:2:4146
+6075:2:4147
+6076:2:4155
+6077:2:4156
+6078:2:4160
+6079:2:4161
+6080:2:4155
+6081:2:4156
+6082:2:4160
+6083:2:4161
+6084:2:4169
+6085:2:4174
+6086:2:4175
+6087:2:4186
+6088:2:4194
+6089:2:4195
+6090:2:4199
+6091:2:4204
+6092:2:4205
+6093:2:4216
+6094:2:4217
+6095:2:4218
+6096:2:4216
+6097:2:4217
+6098:2:4218
+6099:2:4229
+6100:0:4533
+6101:2:3127
+6102:0:4533
+6103:1:2752
+6104:1:2753
+6105:1:2757
+6106:1:2758
+6107:1:2766
+6108:1:2767
+6109:1:2771
+6110:1:2772
+6111:1:2780
+6112:1:2785
+6113:1:2789
+6114:1:2790
+6115:1:2798
+6116:1:2799
+6117:1:2803
+6118:1:2804
+6119:1:2798
+6120:1:2799
+6121:1:2803
+6122:1:2804
+6123:1:2812
+6124:1:2817
+6125:1:2818
+6126:1:2829
+6127:1:2830
+6128:1:2831
+6129:1:2842
+6130:1:2847
+6131:1:2848
+6132:1:2859
+6133:1:2860
+6134:1:2861
+6135:1:2859
+6136:1:2860
+6137:1:2861
+6138:1:2872
+6139:0:4533
+6140:1:11
+6141:0:4533
+6142:2:3975
+6143:2:3976
+6144:2:3980
+6145:2:3981
+6146:2:3989
+6147:2:3990
+6148:2:3994
+6149:2:3995
+6150:2:4003
+6151:2:4008
+6152:2:4012
+6153:2:4013
+6154:2:4021
+6155:2:4022
+6156:2:4026
+6157:2:4027
+6158:2:4021
+6159:2:4022
+6160:2:4026
+6161:2:4027
+6162:2:4035
+6163:2:4040
+6164:2:4041
+6165:2:4052
+6166:2:4060
+6167:2:4061
+6168:2:4065
+6169:2:4070
+6170:2:4071
+6171:2:4082
+6172:2:4083
+6173:2:4084
+6174:2:4082
+6175:2:4083
+6176:2:4084
+6177:2:4095
+6178:2:4103
+6179:0:4533
+6180:2:3127
+6181:0:4533
+6182:2:4109
+6183:2:4110
+6184:2:4114
+6185:2:4115
+6186:2:4123
+6187:2:4124
+6188:2:4128
+6189:2:4129
+6190:2:4137
+6191:2:4142
+6192:2:4146
+6193:2:4147
+6194:2:4155
+6195:2:4156
+6196:2:4160
+6197:2:4161
+6198:2:4155
+6199:2:4156
+6200:2:4160
+6201:2:4161
+6202:2:4169
+6203:2:4174
+6204:2:4175
+6205:2:4186
+6206:2:4194
+6207:2:4195
+6208:2:4199
+6209:2:4204
+6210:2:4205
+6211:2:4216
+6212:2:4217
+6213:2:4218
+6214:2:4216
+6215:2:4217
+6216:2:4218
+6217:2:4229
+6218:0:4533
+6219:2:3127
+6220:0:4533
+6221:1:2881
+6222:1:2882
+6223:1:2886
+6224:1:2887
+6225:1:2895
+6226:1:2896
+6227:1:2900
+6228:1:2901
+6229:1:2909
+6230:1:2914
+6231:1:2918
+6232:1:2919
+6233:1:2927
+6234:1:2928
+6235:1:2932
+6236:1:2933
+6237:1:2927
+6238:1:2928
+6239:1:2932
+6240:1:2933
+6241:1:2941
+6242:1:2946
+6243:1:2947
+6244:1:2958
+6245:1:2959
+6246:1:2960
+6247:1:2971
+6248:1:2976
+6249:1:2977
+6250:1:2988
+6251:1:2989
+6252:1:2990
+6253:1:2988
+6254:1:2989
+6255:1:2990
+6256:1:3001
+6257:1:3008
+6258:1:3012
+6259:0:4533
+6260:1:11
+6261:0:4533
+6262:2:3975
+6263:2:3976
+6264:2:3980
+6265:2:3981
+6266:2:3989
+6267:2:3990
+6268:2:3994
+6269:2:3995
+6270:2:4003
+6271:2:4008
+6272:2:4012
+6273:2:4013
+6274:2:4021
+6275:2:4022
+6276:2:4026
+6277:2:4027
+6278:2:4021
+6279:2:4022
+6280:2:4026
+6281:2:4027
+6282:2:4035
+6283:2:4040
+6284:2:4041
+6285:2:4052
+6286:2:4060
+6287:2:4061
+6288:2:4065
+6289:2:4070
+6290:2:4071
+6291:2:4082
+6292:2:4083
+6293:2:4084
+6294:2:4082
+6295:2:4083
+6296:2:4084
+6297:2:4095
+6298:2:4103
+6299:0:4533
+6300:2:3127
+6301:0:4533
+6302:2:4109
+6303:2:4110
+6304:2:4114
+6305:2:4115
+6306:2:4123
+6307:2:4124
+6308:2:4128
+6309:2:4129
+6310:2:4137
+6311:2:4142
+6312:2:4146
+6313:2:4147
+6314:2:4155
+6315:2:4156
+6316:2:4160
+6317:2:4161
+6318:2:4155
+6319:2:4156
+6320:2:4160
+6321:2:4161
+6322:2:4169
+6323:2:4174
+6324:2:4175
+6325:2:4186
+6326:2:4194
+6327:2:4195
+6328:2:4199
+6329:2:4204
+6330:2:4205
+6331:2:4216
+6332:2:4217
+6333:2:4218
+6334:2:4216
+6335:2:4217
+6336:2:4218
+6337:2:4229
+6338:0:4533
+6339:2:3127
+6340:0:4533
+6341:1:3013
+6342:0:4533
+6343:1:3021
+6344:0:4533
+6345:1:3109
+6346:0:4533
+6347:1:9
+6348:0:4533
+6349:2:3975
+6350:2:3976
+6351:2:3980
+6352:2:3981
+6353:2:3989
+6354:2:3990
+6355:2:3994
+6356:2:3995
+6357:2:4003
+6358:2:4008
+6359:2:4012
+6360:2:4013
+6361:2:4021
+6362:2:4022
+6363:2:4026
+6364:2:4027
+6365:2:4021
+6366:2:4022
+6367:2:4026
+6368:2:4027
+6369:2:4035
+6370:2:4040
+6371:2:4041
+6372:2:4052
+6373:2:4060
+6374:2:4061
+6375:2:4065
+6376:2:4070
+6377:2:4071
+6378:2:4082
+6379:2:4083
+6380:2:4084
+6381:2:4082
+6382:2:4083
+6383:2:4084
+6384:2:4095
+6385:2:4103
+6386:0:4533
+6387:2:3127
+6388:0:4533
+6389:2:4109
+6390:2:4110
+6391:2:4114
+6392:2:4115
+6393:2:4123
+6394:2:4124
+6395:2:4128
+6396:2:4129
+6397:2:4137
+6398:2:4142
+6399:2:4146
+6400:2:4147
+6401:2:4155
+6402:2:4156
+6403:2:4160
+6404:2:4161
+6405:2:4155
+6406:2:4156
+6407:2:4160
+6408:2:4161
+6409:2:4169
+6410:2:4174
+6411:2:4175
+6412:2:4186
+6413:2:4194
+6414:2:4195
+6415:2:4199
+6416:2:4204
+6417:2:4205
+6418:2:4216
+6419:2:4217
+6420:2:4218
+6421:2:4216
+6422:2:4217
+6423:2:4218
+6424:2:4229
+6425:0:4533
+6426:2:3127
+6427:0:4533
+6428:1:10
+6429:0:4533
+6430:1:11
+6431:0:4533
+6432:2:3975
+6433:2:3976
+6434:2:3980
+6435:2:3981
+6436:2:3989
+6437:2:3990
+6438:2:3994
+6439:2:3995
+6440:2:4003
+6441:2:4008
+6442:2:4012
+6443:2:4013
+6444:2:4021
+6445:2:4022
+6446:2:4026
+6447:2:4027
+6448:2:4021
+6449:2:4022
+6450:2:4026
+6451:2:4027
+6452:2:4035
+6453:2:4040
+6454:2:4041
+6455:2:4052
+6456:2:4060
+6457:2:4061
+6458:2:4065
+6459:2:4070
+6460:2:4071
+6461:2:4082
+6462:2:4083
+6463:2:4084
+6464:2:4082
+6465:2:4083
+6466:2:4084
+6467:2:4095
+6468:2:4103
+6469:0:4533
+6470:2:3127
+6471:0:4533
+6472:2:4109
+6473:2:4110
+6474:2:4114
+6475:2:4115
+6476:2:4123
+6477:2:4124
+6478:2:4128
+6479:2:4129
+6480:2:4137
+6481:2:4142
+6482:2:4146
+6483:2:4147
+6484:2:4155
+6485:2:4156
+6486:2:4160
+6487:2:4161
+6488:2:4155
+6489:2:4156
+6490:2:4160
+6491:2:4161
+6492:2:4169
+6493:2:4174
+6494:2:4175
+6495:2:4186
+6496:2:4194
+6497:2:4195
+6498:2:4199
+6499:2:4204
+6500:2:4205
+6501:2:4216
+6502:2:4217
+6503:2:4218
+6504:2:4216
+6505:2:4217
+6506:2:4218
+6507:2:4229
+6508:0:4533
+6509:2:3127
+6510:0:4533
+6511:1:12
+6512:1:13
+6513:1:17
+6514:1:18
+6515:1:26
+6516:1:35
+6517:1:36
+6518:1:40
+6519:1:45
+6520:1:49
+6521:1:50
+6522:1:58
+6523:1:59
+6524:1:63
+6525:1:64
+6526:1:58
+6527:1:59
+6528:1:63
+6529:1:64
+6530:1:72
+6531:1:77
+6532:1:78
+6533:1:89
+6534:1:90
+6535:1:93
+6536:1:94
+6537:1:102
+6538:1:107
+6539:1:108
+6540:1:119
+6541:1:120
+6542:1:121
+6543:1:119
+6544:1:120
+6545:1:121
+6546:1:132
+6547:0:4533
+6548:1:11
+6549:0:4533
+6550:2:3975
+6551:2:3976
+6552:2:3980
+6553:2:3981
+6554:2:3989
+6555:2:3990
+6556:2:3994
+6557:2:3995
+6558:2:4003
+6559:2:4008
+6560:2:4012
+6561:2:4013
+6562:2:4021
+6563:2:4022
+6564:2:4026
+6565:2:4027
+6566:2:4021
+6567:2:4022
+6568:2:4026
+6569:2:4027
+6570:2:4035
+6571:2:4040
+6572:2:4041
+6573:2:4052
+6574:2:4060
+6575:2:4061
+6576:2:4065
+6577:2:4070
+6578:2:4071
+6579:2:4082
+6580:2:4083
+6581:2:4084
+6582:2:4082
+6583:2:4083
+6584:2:4084
+6585:2:4095
+6586:2:4103
+6587:0:4533
+6588:2:3127
+6589:0:4533
+6590:2:4109
+6591:2:4110
+6592:2:4114
+6593:2:4115
+6594:2:4123
+6595:2:4124
+6596:2:4128
+6597:2:4129
+6598:2:4137
+6599:2:4142
+6600:2:4146
+6601:2:4147
+6602:2:4155
+6603:2:4156
+6604:2:4160
+6605:2:4161
+6606:2:4155
+6607:2:4156
+6608:2:4160
+6609:2:4161
+6610:2:4169
+6611:2:4174
+6612:2:4175
+6613:2:4186
+6614:2:4194
+6615:2:4195
+6616:2:4199
+6617:2:4204
+6618:2:4205
+6619:2:4216
+6620:2:4217
+6621:2:4218
+6622:2:4216
+6623:2:4217
+6624:2:4218
+6625:2:4229
+6626:0:4533
+6627:2:3127
+6628:0:4533
+6629:1:141
+6630:1:142
+6631:0:4533
+6632:1:11
+6633:0:4533
+6634:2:3975
+6635:2:3976
+6636:2:3980
+6637:2:3981
+6638:2:3989
+6639:2:3990
+6640:2:3994
+6641:2:3995
+6642:2:4003
+6643:2:4008
+6644:2:4012
+6645:2:4013
+6646:2:4021
+6647:2:4022
+6648:2:4026
+6649:2:4027
+6650:2:4021
+6651:2:4022
+6652:2:4026
+6653:2:4027
+6654:2:4035
+6655:2:4040
+6656:2:4041
+6657:2:4052
+6658:2:4060
+6659:2:4061
+6660:2:4065
+6661:2:4070
+6662:2:4071
+6663:2:4082
+6664:2:4083
+6665:2:4084
+6666:2:4082
+6667:2:4083
+6668:2:4084
+6669:2:4095
+6670:2:4103
+6671:0:4533
+6672:2:3127
+6673:0:4533
+6674:2:4109
+6675:2:4110
+6676:2:4114
+6677:2:4115
+6678:2:4123
+6679:2:4124
+6680:2:4128
+6681:2:4129
+6682:2:4137
+6683:2:4142
+6684:2:4146
+6685:2:4147
+6686:2:4155
+6687:2:4156
+6688:2:4160
+6689:2:4161
+6690:2:4155
+6691:2:4156
+6692:2:4160
+6693:2:4161
+6694:2:4169
+6695:2:4174
+6696:2:4175
+6697:2:4186
+6698:2:4194
+6699:2:4195
+6700:2:4199
+6701:2:4204
+6702:2:4205
+6703:2:4216
+6704:2:4217
+6705:2:4218
+6706:2:4216
+6707:2:4217
+6708:2:4218
+6709:2:4229
+6710:0:4533
+6711:2:3127
+6712:0:4533
+6713:1:148
+6714:1:149
+6715:1:153
+6716:1:154
+6717:1:162
+6718:1:171
+6719:1:172
+6720:1:176
+6721:1:181
+6722:1:185
+6723:1:186
+6724:1:194
+6725:1:195
+6726:1:199
+6727:1:200
+6728:1:194
+6729:1:195
+6730:1:199
+6731:1:200
+6732:1:208
+6733:1:213
+6734:1:214
+6735:1:225
+6736:1:226
+6737:1:229
+6738:1:230
+6739:1:238
+6740:1:243
+6741:1:244
+6742:1:255
+6743:1:256
+6744:1:257
+6745:1:255
+6746:1:256
+6747:1:257
+6748:1:268
+6749:0:4533
+6750:1:11
+6751:0:4533
+6752:2:3975
+6753:2:3976
+6754:2:3980
+6755:2:3981
+6756:2:3989
+6757:2:3990
+6758:2:3994
+6759:2:3995
+6760:2:4003
+6761:2:4008
+6762:2:4012
+6763:2:4013
+6764:2:4021
+6765:2:4022
+6766:2:4026
+6767:2:4027
+6768:2:4021
+6769:2:4022
+6770:2:4026
+6771:2:4027
+6772:2:4035
+6773:2:4040
+6774:2:4041
+6775:2:4052
+6776:2:4060
+6777:2:4061
+6778:2:4065
+6779:2:4070
+6780:2:4071
+6781:2:4082
+6782:2:4083
+6783:2:4084
+6784:2:4082
+6785:2:4083
+6786:2:4084
+6787:2:4095
+6788:2:4103
+6789:0:4533
+6790:2:3127
+6791:0:4533
+6792:2:4109
+6793:2:4110
+6794:2:4114
+6795:2:4115
+6796:2:4123
+6797:2:4124
+6798:2:4128
+6799:2:4129
+6800:2:4137
+6801:2:4142
+6802:2:4146
+6803:2:4147
+6804:2:4155
+6805:2:4156
+6806:2:4160
+6807:2:4161
+6808:2:4155
+6809:2:4156
+6810:2:4160
+6811:2:4161
+6812:2:4169
+6813:2:4174
+6814:2:4175
+6815:2:4186
+6816:2:4194
+6817:2:4195
+6818:2:4199
+6819:2:4204
+6820:2:4205
+6821:2:4216
+6822:2:4217
+6823:2:4218
+6824:2:4216
+6825:2:4217
+6826:2:4218
+6827:2:4229
+6828:0:4533
+6829:2:3127
+6830:0:4533
+6831:1:277
+6832:1:278
+6833:1:282
+6834:1:283
+6835:1:291
+6836:1:300
+6837:1:301
+6838:1:305
+6839:1:310
+6840:1:314
+6841:1:315
+6842:1:323
+6843:1:324
+6844:1:328
+6845:1:329
+6846:1:323
+6847:1:324
+6848:1:328
+6849:1:329
+6850:1:337
+6851:1:342
+6852:1:343
+6853:1:354
+6854:1:355
+6855:1:358
+6856:1:359
+6857:1:367
+6858:1:372
+6859:1:373
+6860:1:384
+6861:1:385
+6862:1:386
+6863:1:384
+6864:1:385
+6865:1:386
+6866:1:397
+6867:1:404
+6868:0:4533
+6869:1:11
+6870:0:4533
+6871:2:3975
+6872:2:3976
+6873:2:3980
+6874:2:3981
+6875:2:3989
+6876:2:3990
+6877:2:3994
+6878:2:3995
+6879:2:4003
+6880:2:4008
+6881:2:4012
+6882:2:4013
+6883:2:4021
+6884:2:4022
+6885:2:4026
+6886:2:4027
+6887:2:4021
+6888:2:4022
+6889:2:4026
+6890:2:4027
+6891:2:4035
+6892:2:4040
+6893:2:4041
+6894:2:4052
+6895:2:4060
+6896:2:4061
+6897:2:4065
+6898:2:4070
+6899:2:4071
+6900:2:4082
+6901:2:4083
+6902:2:4084
+6903:2:4082
+6904:2:4083
+6905:2:4084
+6906:2:4095
+6907:2:4103
+6908:0:4533
+6909:2:3127
+6910:0:4533
+6911:1:540
+6912:1:544
+6913:1:545
+6914:1:549
+6915:1:550
+6916:1:558
+6917:1:566
+6918:1:567
+6919:1:571
+6920:1:575
+6921:1:576
+6922:1:571
+6923:1:575
+6924:1:576
+6925:1:580
+6926:1:587
+6927:1:594
+6928:1:595
+6929:1:602
+6930:1:607
+6931:1:614
+6932:1:615
+6933:1:614
+6934:1:615
+6935:1:622
+6936:0:4533
+6937:1:11
+6938:0:4533
+6939:1:632
+6940:1:633
+6941:1:637
+6942:1:638
+6943:1:646
+6944:1:647
+6945:1:651
+6946:1:652
+6947:1:660
+6948:1:665
+6949:1:669
+6950:1:670
+6951:1:678
+6952:1:679
+6953:1:683
+6954:1:684
+6955:1:678
+6956:1:679
+6957:1:683
+6958:1:684
+6959:1:692
+6960:1:697
+6961:1:698
+6962:1:709
+6963:1:710
+6964:1:711
+6965:1:722
+6966:1:727
+6967:1:728
+6968:1:739
+6969:1:740
+6970:1:741
+6971:1:739
+6972:1:740
+6973:1:741
+6974:1:752
+6975:0:4533
+6976:1:11
+6977:0:4533
+6978:1:761
+6979:1:764
+6980:1:765
+6981:0:4533
+6982:1:11
+6983:0:4533
+6984:1:1028
+6985:1:1029
+6986:1:1033
+6987:1:1034
+6988:1:1042
+6989:1:1043
+6990:1:1047
+6991:1:1048
+6992:1:1056
+6993:1:1061
+6994:1:1065
+6995:1:1066
+6996:1:1074
+6997:1:1075
+6998:1:1079
+6999:1:1080
+7000:1:1074
+7001:1:1075
+7002:1:1079
+7003:1:1080
+7004:1:1088
+7005:1:1093
+7006:1:1094
+7007:1:1105
+7008:1:1106
+7009:1:1107
+7010:1:1118
+7011:1:1123
+7012:1:1124
+7013:1:1135
+7014:1:1136
+7015:1:1137
+7016:1:1135
+7017:1:1136
+7018:1:1137
+7019:1:1148
+7020:1:1155
+7021:1:1159
+7022:0:4533
+7023:1:11
+7024:0:4533
+7025:1:1160
+7026:1:1161
+7027:1:1165
+7028:1:1166
+7029:1:1174
+7030:1:1175
+7031:1:1176
+7032:1:1188
+7033:1:1193
+7034:1:1197
+7035:1:1198
+7036:1:1206
+7037:1:1207
+7038:1:1211
+7039:1:1212
+7040:1:1206
+7041:1:1207
+7042:1:1211
+7043:1:1212
+7044:1:1220
+7045:1:1225
+7046:1:1226
+7047:1:1237
+7048:1:1238
+7049:1:1239
+7050:1:1250
+7051:1:1255
+7052:1:1256
+7053:1:1267
+7054:1:1268
+7055:1:1269
+7056:1:1267
+7057:1:1268
+7058:1:1269
+7059:1:1280
+7060:0:4533
+7061:1:11
+7062:0:4533
+7063:1:1289
+7064:0:4533
+7065:1:3023
+7066:1:3030
+7067:1:3031
+7068:1:3038
+7069:1:3043
+7070:1:3050
+7071:1:3051
+7072:1:3050
+7073:1:3051
+7074:1:3058
+7075:1:3062
+7076:0:4533
+7077:1:1291
+7078:1:1292
+7079:0:4533
+7080:1:11
+7081:0:4533
+7082:1:1293
+7083:1:1294
+7084:1:1298
+7085:1:1299
+7086:1:1307
+7087:1:1308
+7088:1:1312
+7089:1:1313
+7090:1:1321
+7091:1:1326
+7092:1:1330
+7093:1:1331
+7094:1:1339
+7095:1:1340
+7096:1:1344
+7097:1:1345
+7098:1:1339
+7099:1:1340
+7100:1:1344
+7101:1:1345
+7102:1:1353
+7103:1:1358
+7104:1:1359
+7105:1:1370
+7106:1:1371
+7107:1:1372
+7108:1:1383
+7109:1:1388
+7110:1:1389
+7111:1:1400
+7112:1:1401
+7113:1:1402
+7114:1:1400
+7115:1:1401
+7116:1:1402
+7117:1:1413
+7118:0:4533
+7119:1:11
+7120:0:4533
+7121:1:1422
+7122:1:1423
+7123:1:1427
+7124:1:1428
+7125:1:1436
+7126:1:1437
+7127:1:1441
+7128:1:1442
+7129:1:1450
+7130:1:1455
+7131:1:1459
+7132:1:1460
+7133:1:1468
+7134:1:1469
+7135:1:1473
+7136:1:1474
+7137:1:1468
+7138:1:1469
+7139:1:1473
+7140:1:1474
+7141:1:1482
+7142:1:1487
+7143:1:1488
+7144:1:1499
+7145:1:1500
+7146:1:1501
+7147:1:1512
+7148:1:1517
+7149:1:1518
+7150:1:1529
+7151:1:1530
+7152:1:1531
+7153:1:1529
+7154:1:1530
+7155:1:1531
+7156:1:1542
+7157:1:1549
+7158:1:1553
+7159:0:4533
+7160:1:11
+7161:0:4533
+7162:1:1554
+7163:1:1558
+7164:1:1559
+7165:1:1563
+7166:1:1564
+7167:1:1572
+7168:1:1580
+7169:1:1581
+7170:1:1585
+7171:1:1589
+7172:1:1590
+7173:1:1585
+7174:1:1589
+7175:1:1590
+7176:1:1594
+7177:1:1601
+7178:1:1608
+7179:1:1609
+7180:1:1616
+7181:1:1621
+7182:1:1628
+7183:1:1629
+7184:1:1628
+7185:1:1629
+7186:1:1636
+-1:-1:-1
+7187:0:4533
+7188:1:11
+7189:0:4533
+7190:1:1646
+7191:1:1647
+7192:1:1651
+7193:1:1652
+7194:1:1660
+7195:1:1661
+7196:1:1665
+7197:1:1666
+7198:1:1674
+7199:1:1679
+7200:1:1683
+7201:1:1684
+7202:1:1692
+7203:1:1693
+7204:1:1697
+7205:1:1698
+7206:1:1692
+7207:1:1693
+7208:1:1697
+7209:1:1698
+7210:1:1706
+7211:1:1711
+7212:1:1712
+7213:1:1723
+7214:1:1724
+7215:1:1725
+7216:1:1736
+7217:1:1741
+7218:1:1742
+7219:1:1753
+7220:1:1754
+7221:1:1755
+7222:1:1753
+7223:1:1754
+7224:1:1755
+7225:1:1766
+7226:0:4533
+7227:1:11
+7228:0:4533
+7229:1:1775
+7230:1:1776
+7231:1:1780
+7232:1:1781
+7233:1:1789
+7234:1:1790
+7235:1:1794
+7236:1:1795
+7237:1:1803
+7238:1:1808
+7239:1:1812
+7240:1:1813
+7241:1:1821
+7242:1:1822
+7243:1:1826
+7244:1:1827
+7245:1:1821
+7246:1:1822
+7247:1:1826
+7248:1:1827
+7249:1:1835
+7250:1:1840
+7251:1:1841
+7252:1:1852
+7253:1:1853
+7254:1:1854
+7255:1:1865
+7256:1:1870
+7257:1:1871
+7258:1:1882
+7259:1:1883
+7260:1:1884
+7261:1:1882
+7262:1:1883
+7263:1:1884
+7264:1:1895
+7265:1:1902
+7266:1:1906
+7267:0:4533
+7268:1:11
+7269:0:4533
+7270:1:1907
+7271:1:1908
+7272:1:1912
+7273:1:1913
+7274:1:1921
+7275:1:1922
+7276:1:1923
+7277:1:1935
+7278:1:1940
+7279:1:1944
+7280:1:1945
+7281:1:1953
+7282:1:1954
+7283:1:1958
+7284:1:1959
+7285:1:1953
+7286:1:1954
+7287:1:1958
+7288:1:1959
+7289:1:1967
+7290:1:1972
+7291:1:1973
+7292:1:1984
+7293:1:1985
+7294:1:1986
+7295:1:1997
+7296:1:2002
+7297:1:2003
+7298:1:2014
+7299:1:2015
+7300:1:2016
+7301:1:2014
+7302:1:2015
+7303:1:2016
+7304:1:2027
+7305:0:4533
+7306:1:11
+7307:0:4533
+7308:1:2036
+7309:1:2037
+7310:0:4533
+7311:1:11
+7312:0:4533
+7313:1:2043
+7314:1:2044
+7315:1:2048
+7316:1:2049
+7317:1:2057
+7318:1:2058
+7319:1:2062
+7320:1:2063
+7321:1:2071
+7322:1:2076
+7323:1:2080
+7324:1:2081
+7325:1:2089
+7326:1:2090
+7327:1:2094
+7328:1:2095
+7329:1:2089
+7330:1:2090
+7331:1:2094
+7332:1:2095
+7333:1:2103
+7334:1:2108
+7335:1:2109
+7336:1:2120
+7337:1:2121
+7338:1:2122
+7339:1:2133
+7340:1:2138
+7341:1:2139
+7342:1:2150
+7343:1:2151
+7344:1:2152
+7345:1:2150
+7346:1:2151
+7347:1:2152
+7348:1:2163
+7349:0:4533
+7350:1:11
+7351:0:4533
+7352:1:2172
+7353:1:2173
+7354:1:2177
+7355:1:2178
+7356:1:2186
+7357:1:2187
+7358:1:2191
+7359:1:2192
+7360:1:2200
+7361:1:2205
+7362:1:2209
+7363:1:2210
+7364:1:2218
+7365:1:2219
+7366:1:2223
+7367:1:2224
+7368:1:2218
+7369:1:2219
+7370:1:2223
+7371:1:2224
+7372:1:2232
+7373:1:2237
+7374:1:2238
+7375:1:2249
+7376:1:2250
+7377:1:2251
+7378:1:2262
+7379:1:2267
+7380:1:2268
+7381:1:2279
+7382:1:2280
+7383:1:2281
+7384:1:2279
+7385:1:2280
+7386:1:2281
+7387:1:2292
+7388:1:2299
+7389:0:4533
+7390:1:11
+7391:0:4533
+7392:1:2435
+7393:1:2439
+7394:1:2440
+7395:1:2444
+7396:1:2445
+7397:1:2453
+7398:1:2461
+7399:1:2462
+7400:1:2466
+7401:1:2470
+7402:1:2471
+7403:1:2466
+7404:1:2470
+7405:1:2471
+7406:1:2475
+7407:1:2482
+7408:1:2489
+7409:1:2490
+7410:1:2497
+7411:1:2502
+7412:1:2509
+7413:1:2510
+7414:1:2509
+7415:1:2510
+7416:1:2517
+7417:0:4533
+7418:1:11
+7419:0:4533
+7420:1:2527
+7421:1:2528
+7422:1:2532
+7423:1:2533
+7424:1:2541
+7425:1:2542
+7426:1:2546
+7427:1:2547
+7428:1:2555
+7429:1:2560
+7430:1:2564
+7431:1:2565
+7432:1:2573
+7433:1:2574
+7434:1:2578
+7435:1:2579
+7436:1:2573
+7437:1:2574
+7438:1:2578
+7439:1:2579
+7440:1:2587
+7441:1:2592
+7442:1:2593
+7443:1:2604
+7444:1:2605
+7445:1:2606
+7446:1:2617
+7447:1:2622
+7448:1:2623
+7449:1:2634
+7450:1:2635
+7451:1:2636
+7452:1:2634
+7453:1:2635
+7454:1:2636
+7455:1:2647
+7456:0:4533
+7457:1:11
+7458:0:4533
+7459:1:2656
+7460:0:4533
+7461:1:3066
+7462:1:3073
+7463:1:3074
+7464:1:3081
+7465:1:3086
+7466:1:3093
+7467:1:3094
+7468:1:3093
+7469:1:3094
+7470:1:3101
+7471:1:3105
+7472:0:4533
+7473:1:2658
+7474:1:2659
+7475:0:4533
+7476:1:11
+7477:0:4533
+7478:1:2660
+7479:1:2664
+7480:1:2665
+7481:1:2669
+7482:1:2673
+7483:1:2674
+7484:1:2678
+7485:1:2686
+7486:1:2687
+7487:1:2691
+7488:1:2695
+7489:1:2696
+7490:1:2691
+7491:1:2695
+7492:1:2696
+7493:1:2700
+7494:1:2707
+7495:1:2714
+7496:1:2715
+7497:1:2722
+7498:1:2727
+7499:1:2734
+7500:1:2735
+7501:1:2734
+7502:1:2735
+7503:1:2742
+7504:0:4533
+7505:1:11
+7506:0:4533
+7507:1:2752
+7508:1:2753
+7509:1:2757
+7510:1:2758
+7511:1:2766
+7512:1:2767
+7513:1:2771
+7514:1:2772
+7515:1:2780
+7516:1:2785
+7517:1:2789
+7518:1:2790
+7519:1:2798
+7520:1:2799
+7521:1:2803
+7522:1:2804
+7523:1:2798
+7524:1:2799
+7525:1:2803
+7526:1:2804
+7527:1:2812
+7528:1:2817
+7529:1:2818
+7530:1:2829
+7531:1:2830
+7532:1:2831
+7533:1:2842
+7534:1:2847
+7535:1:2848
+7536:1:2859
+7537:1:2860
+7538:1:2861
+7539:1:2859
+7540:1:2860
+7541:1:2861
+7542:1:2872
+7543:0:4533
+7544:1:11
+7545:0:4533
+7546:1:2881
+7547:1:2882
+7548:1:2886
+7549:1:2887
+7550:1:2895
+7551:1:2896
+7552:1:2900
+7553:1:2901
+7554:1:2909
+7555:1:2914
+7556:1:2918
+7557:1:2919
+7558:1:2927
+7559:1:2928
+7560:1:2932
+7561:1:2933
+7562:1:2927
+7563:1:2928
+7564:1:2932
+7565:1:2933
+7566:1:2941
+7567:1:2946
+7568:1:2947
+7569:1:2958
+7570:1:2959
+7571:1:2960
+7572:1:2971
+7573:1:2976
+7574:1:2977
+7575:1:2988
+7576:1:2989
+7577:1:2990
+7578:1:2988
+7579:1:2989
+7580:1:2990
+7581:1:3001
+7582:1:3008
+7583:1:3012
+7584:0:4533
+7585:1:11
+7586:0:4533
+7587:1:3013
+7588:0:4533
+7589:1:3021
+7590:0:4533
+7591:1:3109
+7592:0:4533
+7593:1:9
+7594:0:4533
+7595:1:10
+7596:0:4533
+7597:1:11
+7598:0:4533
+7599:1:12
+7600:1:13
+7601:1:17
+7602:1:18
+7603:1:26
+7604:1:27
+7605:1:28
+7606:1:40
+7607:1:45
+7608:1:49
+7609:1:50
+7610:1:58
+7611:1:59
+7612:1:63
+7613:1:64
+7614:1:58
+7615:1:59
+7616:1:63
+7617:1:64
+7618:1:72
+7619:1:77
+7620:1:78
+7621:1:89
+7622:1:90
+7623:1:91
+7624:1:102
+7625:1:107
+7626:1:108
+7627:1:119
+7628:1:120
+7629:1:121
+7630:1:119
+7631:1:120
+7632:1:121
+7633:1:132
+7634:0:4533
+7635:1:11
+7636:0:4533
+7637:1:141
+7638:1:142
+7639:0:4533
+7640:1:11
+7641:0:4533
+7642:1:148
+7643:1:149
+7644:1:153
+7645:1:154
+7646:1:162
+7647:1:163
+7648:1:167
+7649:1:168
+7650:1:176
+7651:1:181
+7652:1:185
+7653:1:186
+7654:1:194
+7655:1:195
+7656:1:199
+7657:1:200
+7658:1:194
+7659:1:195
+7660:1:199
+7661:1:200
+7662:1:208
+7663:1:213
+7664:1:214
+7665:1:225
+7666:1:226
+7667:1:227
+7668:1:238
+7669:1:243
+7670:1:244
+7671:1:255
+7672:1:256
+7673:1:257
+7674:1:255
+7675:1:256
+7676:1:257
+7677:1:268
+7678:0:4533
+7679:1:11
+7680:0:4533
+7681:1:277
+7682:1:278
+7683:1:282
+7684:1:283
+7685:1:291
+7686:1:292
+7687:1:296
+7688:1:297
+7689:1:305
+7690:1:310
+7691:1:314
+7692:1:315
+7693:1:323
+7694:1:324
+7695:1:328
+7696:1:329
+7697:1:323
+7698:1:324
+7699:1:328
+7700:1:329
+7701:1:337
+7702:1:342
+7703:1:343
+7704:1:354
+7705:1:355
+7706:1:356
+7707:1:367
+7708:1:372
+7709:1:373
+7710:1:384
+7711:1:385
+7712:1:386
+7713:1:384
+7714:1:385
+7715:1:386
+7716:1:397
+7717:1:404
+7718:0:4533
+7719:1:11
+7720:0:4533
+7721:1:540
+7722:1:544
+7723:1:545
+7724:1:549
+7725:1:550
+7726:1:558
+7727:1:566
+7728:1:567
+7729:1:571
+7730:1:575
+7731:1:576
+7732:1:571
+7733:1:575
+7734:1:576
+7735:1:580
+7736:1:587
+7737:1:594
+7738:1:595
+7739:1:602
+7740:1:607
+7741:1:614
+7742:1:615
+7743:1:614
+7744:1:615
+7745:1:622
+7746:0:4533
+7747:2:4109
+7748:2:4110
+7749:2:4114
+7750:2:4115
+7751:2:4123
+7752:2:4124
+7753:2:4128
+7754:2:4129
+7755:2:4137
+7756:2:4142
+7757:2:4146
+7758:2:4147
+7759:2:4155
+7760:2:4156
+7761:2:4160
+7762:2:4161
+7763:2:4155
+7764:2:4156
+7765:2:4160
+7766:2:4161
+7767:2:4169
+7768:2:4174
+7769:2:4175
+7770:2:4186
+7771:2:4194
+7772:2:4195
+7773:2:4199
+7774:2:4204
+7775:2:4205
+7776:2:4216
+7777:2:4217
+7778:2:4218
+7779:2:4216
+7780:2:4217
+7781:2:4218
+7782:2:4229
+7783:0:4533
+7784:2:3127
+7785:0:4533
+7786:1:11
+7787:0:4533
+7788:1:632
+7789:1:633
+7790:1:637
+7791:1:638
+7792:1:646
+7793:1:647
+7794:1:651
+7795:1:652
+7796:1:660
+7797:1:665
+7798:1:669
+7799:1:670
+7800:1:678
+7801:1:679
+7802:1:683
+7803:1:684
+7804:1:678
+7805:1:679
+7806:1:683
+7807:1:684
+7808:1:692
+7809:1:697
+7810:1:698
+7811:1:709
+7812:1:710
+7813:1:711
+7814:1:722
+7815:1:727
+7816:1:728
+7817:1:739
+7818:1:740
+7819:1:741
+7820:1:739
+7821:1:740
+7822:1:741
+7823:1:752
+7824:0:4533
+7825:2:3975
+7826:2:3976
+7827:2:3980
+7828:2:3981
+7829:2:3989
+7830:2:3990
+7831:2:3994
+7832:2:3995
+7833:2:4003
+7834:2:4008
+7835:2:4012
+7836:2:4013
+7837:2:4021
+7838:2:4022
+7839:2:4026
+7840:2:4027
+7841:2:4021
+7842:2:4022
+7843:2:4026
+7844:2:4027
+7845:2:4035
+7846:2:4040
+7847:2:4041
+7848:2:4052
+7849:2:4060
+7850:2:4061
+7851:2:4065
+7852:2:4070
+7853:2:4071
+7854:2:4082
+7855:2:4083
+7856:2:4084
+7857:2:4082
+7858:2:4083
+7859:2:4084
+7860:2:4095
+7861:2:4103
+7862:0:4533
+7863:2:3127
+7864:0:4533
+7865:1:11
+7866:0:4533
+7867:1:1160
+7868:1:1161
+7869:1:1165
+7870:1:1166
+7871:1:1174
+7872:1:1175
+7873:1:1179
+7874:1:1180
+7875:1:1188
+7876:1:1193
+7877:1:1197
+7878:1:1198
+7879:1:1206
+7880:1:1207
+7881:1:1211
+7882:1:1212
+7883:1:1206
+7884:1:1207
+7885:1:1211
+7886:1:1212
+7887:1:1220
+7888:1:1225
+7889:1:1226
+7890:1:1237
+7891:1:1238
+7892:1:1239
+7893:1:1250
+7894:1:1255
+7895:1:1256
+7896:1:1267
+7897:1:1268
+7898:1:1269
+7899:1:1267
+7900:1:1268
+7901:1:1269
+7902:1:1280
+7903:0:4533
+7904:1:11
+7905:0:4533
+7906:2:4109
+7907:2:4110
+7908:2:4114
+7909:2:4115
+7910:2:4123
+7911:2:4124
+7912:2:4128
+7913:2:4129
+7914:2:4137
+7915:2:4142
+7916:2:4146
+7917:2:4147
+7918:2:4155
+7919:2:4156
+7920:2:4160
+7921:2:4161
+7922:2:4155
+7923:2:4156
+7924:2:4160
+7925:2:4161
+7926:2:4169
+7927:2:4174
+7928:2:4175
+7929:2:4186
+7930:2:4194
+7931:2:4195
+7932:2:4199
+7933:2:4204
+7934:2:4205
+7935:2:4216
+7936:2:4217
+7937:2:4218
+7938:2:4216
+7939:2:4217
+7940:2:4218
+7941:2:4229
+7942:0:4533
+7943:2:3127
+7944:0:4533
+7945:2:3975
+7946:2:3976
+7947:2:3980
+7948:2:3981
+7949:2:3989
+7950:2:3990
+7951:2:3994
+7952:2:3995
+7953:2:4003
+7954:2:4008
+7955:2:4012
+7956:2:4013
+7957:2:4021
+7958:2:4022
+7959:2:4026
+7960:2:4027
+7961:2:4021
+7962:2:4022
+7963:2:4026
+7964:2:4027
+7965:2:4035
+7966:2:4040
+7967:2:4041
+7968:2:4052
+7969:2:4060
+7970:2:4061
+7971:2:4065
+7972:2:4070
+7973:2:4071
+7974:2:4082
+7975:2:4083
+7976:2:4084
+7977:2:4082
+7978:2:4083
+7979:2:4084
+7980:2:4095
+7981:2:4103
+7982:0:4533
+7983:2:3127
+7984:0:4533
+7985:1:761
+7986:1:764
+7987:1:765
+7988:0:4533
+7989:1:11
+7990:0:4533
+7991:2:4109
+7992:2:4110
+7993:2:4114
+7994:2:4115
+7995:2:4123
+7996:2:4124
+7997:2:4128
+7998:2:4129
+7999:2:4137
+8000:2:4142
+8001:2:4146
+8002:2:4147
+8003:2:4155
+8004:2:4156
+8005:2:4160
+8006:2:4161
+8007:2:4155
+8008:2:4156
+8009:2:4160
+8010:2:4161
+8011:2:4169
+8012:2:4174
+8013:2:4175
+8014:2:4186
+8015:2:4194
+8016:2:4195
+8017:2:4199
+8018:2:4204
+8019:2:4205
+8020:2:4216
+8021:2:4217
+8022:2:4218
+8023:2:4216
+8024:2:4217
+8025:2:4218
+8026:2:4229
+8027:0:4533
+8028:2:3127
+8029:0:4533
+8030:2:3975
+8031:2:3976
+8032:2:3980
+8033:2:3981
+8034:2:3989
+8035:2:3990
+8036:2:3994
+8037:2:3995
+8038:2:4003
+8039:2:4008
+8040:2:4012
+8041:2:4013
+8042:2:4021
+8043:2:4022
+8044:2:4026
+8045:2:4027
+8046:2:4021
+8047:2:4022
+8048:2:4026
+8049:2:4027
+8050:2:4035
+8051:2:4040
+8052:2:4041
+8053:2:4052
+8054:2:4060
+8055:2:4061
+8056:2:4065
+8057:2:4070
+8058:2:4071
+8059:2:4082
+8060:2:4083
+8061:2:4084
+8062:2:4082
+8063:2:4083
+8064:2:4084
+8065:2:4095
+8066:2:4103
+8067:0:4533
+8068:2:3127
+8069:0:4533
+8070:1:1028
+8071:1:1029
+8072:1:1033
+8073:1:1034
+8074:1:1042
+8075:1:1043
+8076:1:1047
+8077:1:1048
+8078:1:1056
+8079:1:1061
+8080:1:1065
+8081:1:1066
+8082:1:1074
+8083:1:1075
+8084:1:1079
+8085:1:1080
+8086:1:1074
+8087:1:1075
+8088:1:1079
+8089:1:1080
+8090:1:1088
+8091:1:1093
+8092:1:1094
+8093:1:1105
+8094:1:1106
+8095:1:1107
+8096:1:1118
+8097:1:1123
+8098:1:1124
+8099:1:1135
+8100:1:1136
+8101:1:1137
+8102:1:1135
+8103:1:1136
+8104:1:1137
+8105:1:1148
+8106:1:1155
+8107:1:1159
+8108:0:4533
+8109:1:11
+8110:0:4533
+8111:2:4109
+8112:2:4110
+8113:2:4114
+8114:2:4115
+8115:2:4123
+8116:2:4124
+8117:2:4128
+8118:2:4129
+8119:2:4137
+8120:2:4142
+8121:2:4146
+8122:2:4147
+8123:2:4155
+8124:2:4156
+8125:2:4160
+8126:2:4161
+8127:2:4155
+8128:2:4156
+8129:2:4160
+8130:2:4161
+8131:2:4169
+8132:2:4174
+8133:2:4175
+8134:2:4186
+8135:2:4194
+8136:2:4195
+8137:2:4199
+8138:2:4204
+8139:2:4205
+8140:2:4216
+8141:2:4217
+8142:2:4218
+8143:2:4216
+8144:2:4217
+8145:2:4218
+8146:2:4229
+8147:0:4533
+8148:2:3127
+8149:0:4533
+8150:2:3975
+8151:2:3976
+8152:2:3980
+8153:2:3981
+8154:2:3989
+8155:2:3990
+8156:2:3994
+8157:2:3995
+8158:2:4003
+8159:2:4008
+8160:2:4012
+8161:2:4013
+8162:2:4021
+8163:2:4022
+8164:2:4026
+8165:2:4027
+8166:2:4021
+8167:2:4022
+8168:2:4026
+8169:2:4027
+8170:2:4035
+8171:2:4040
+8172:2:4041
+8173:2:4052
+8174:2:4060
+8175:2:4061
+8176:2:4065
+8177:2:4070
+8178:2:4071
+8179:2:4082
+8180:2:4083
+8181:2:4084
+8182:2:4082
+8183:2:4083
+8184:2:4084
+8185:2:4095
+8186:2:4103
+8187:0:4533
+8188:2:3127
+8189:0:4533
+8190:1:1289
+8191:0:4533
+8192:2:4109
+8193:2:4110
+8194:2:4114
+8195:2:4115
+8196:2:4123
+8197:2:4124
+8198:2:4128
+8199:2:4129
+8200:2:4137
+8201:2:4142
+8202:2:4146
+8203:2:4147
+8204:2:4155
+8205:2:4156
+8206:2:4160
+8207:2:4161
+8208:2:4155
+8209:2:4156
+8210:2:4160
+8211:2:4161
+8212:2:4169
+8213:2:4174
+8214:2:4175
+8215:2:4186
+8216:2:4194
+8217:2:4195
+8218:2:4199
+8219:2:4204
+8220:2:4205
+8221:2:4216
+8222:2:4217
+8223:2:4218
+8224:2:4216
+8225:2:4217
+8226:2:4218
+8227:2:4229
+8228:0:4533
+8229:2:3127
+8230:0:4533
+8231:2:3975
+8232:2:3976
+8233:2:3980
+8234:2:3981
+8235:2:3989
+8236:2:3990
+8237:2:3994
+8238:2:3995
+8239:2:4003
+8240:2:4008
+8241:2:4012
+8242:2:4013
+8243:2:4021
+8244:2:4022
+8245:2:4026
+8246:2:4027
+8247:2:4021
+8248:2:4022
+8249:2:4026
+8250:2:4027
+8251:2:4035
+8252:2:4040
+8253:2:4041
+8254:2:4052
+8255:2:4060
+8256:2:4061
+8257:2:4065
+8258:2:4070
+8259:2:4071
+8260:2:4082
+8261:2:4083
+8262:2:4084
+8263:2:4082
+8264:2:4083
+8265:2:4084
+8266:2:4095
+8267:2:4103
+8268:0:4533
+8269:2:3127
+8270:0:4533
+8271:1:3023
+8272:1:3030
+8273:1:3033
+8274:1:3034
+8275:1:3038
+8276:1:3043
+8277:1:3050
+8278:1:3051
+8279:1:3050
+8280:1:3051
+8281:1:3058
+8282:1:3062
+8283:0:4533
+8284:2:4109
+8285:2:4110
+8286:2:4114
+8287:2:4115
+8288:2:4123
+8289:2:4124
+8290:2:4128
+8291:2:4129
+8292:2:4137
+8293:2:4142
+8294:2:4146
+8295:2:4147
+8296:2:4155
+8297:2:4156
+8298:2:4160
+8299:2:4161
+8300:2:4155
+8301:2:4156
+8302:2:4160
+8303:2:4161
+8304:2:4169
+8305:2:4174
+8306:2:4175
+8307:2:4186
+8308:2:4194
+8309:2:4195
+8310:2:4199
+8311:2:4204
+8312:2:4205
+8313:2:4216
+8314:2:4217
+8315:2:4218
+8316:2:4216
+8317:2:4217
+8318:2:4218
+8319:2:4229
+8320:0:4533
+8321:2:3127
+8322:0:4533
+8323:2:3975
+8324:2:3976
+8325:2:3980
+8326:2:3981
+8327:2:3989
+8328:2:3990
+8329:2:3994
+8330:2:3995
+8331:2:4003
+8332:2:4008
+8333:2:4012
+8334:2:4013
+8335:2:4021
+8336:2:4022
+8337:2:4026
+8338:2:4027
+8339:2:4021
+8340:2:4022
+8341:2:4026
+8342:2:4027
+8343:2:4035
+8344:2:4040
+8345:2:4041
+8346:2:4052
+8347:2:4060
+8348:2:4061
+8349:2:4065
+8350:2:4070
+8351:2:4071
+8352:2:4082
+8353:2:4083
+8354:2:4084
+8355:2:4082
+8356:2:4083
+8357:2:4084
+8358:2:4095
+8359:2:4103
+8360:0:4533
+8361:2:3127
+8362:0:4533
+8363:1:1291
+8364:1:1292
+8365:0:4533
+8366:1:11
+8367:0:4533
+8368:2:4109
+8369:2:4110
+8370:2:4114
+8371:2:4115
+8372:2:4123
+8373:2:4124
+8374:2:4128
+8375:2:4129
+8376:2:4137
+8377:2:4142
+8378:2:4146
+8379:2:4147
+8380:2:4155
+8381:2:4156
+8382:2:4160
+8383:2:4161
+8384:2:4155
+8385:2:4156
+8386:2:4160
+8387:2:4161
+8388:2:4169
+8389:2:4174
+8390:2:4175
+8391:2:4186
+8392:2:4194
+8393:2:4195
+8394:2:4199
+8395:2:4204
+8396:2:4205
+8397:2:4216
+8398:2:4217
+8399:2:4218
+8400:2:4216
+8401:2:4217
+8402:2:4218
+8403:2:4229
+8404:0:4533
+8405:2:3127
+8406:0:4533
+8407:2:3975
+8408:2:3976
+8409:2:3980
+8410:2:3981
+8411:2:3989
+8412:2:3990
+8413:2:3994
+8414:2:3995
+8415:2:4003
+8416:2:4008
+8417:2:4012
+8418:2:4013
+8419:2:4021
+8420:2:4022
+8421:2:4026
+8422:2:4027
+8423:2:4021
+8424:2:4022
+8425:2:4026
+8426:2:4027
+8427:2:4035
+8428:2:4040
+8429:2:4041
+8430:2:4052
+8431:2:4060
+8432:2:4061
+8433:2:4065
+8434:2:4070
+8435:2:4071
+8436:2:4082
+8437:2:4083
+8438:2:4084
+8439:2:4082
+8440:2:4083
+8441:2:4084
+8442:2:4095
+8443:2:4103
+8444:0:4533
+8445:2:3127
+8446:0:4533
+8447:1:1293
+8448:1:1294
+8449:1:1298
+8450:1:1299
+8451:1:1307
+8452:1:1308
+8453:1:1309
+8454:1:1321
+8455:1:1326
+8456:1:1330
+8457:1:1331
+8458:1:1339
+8459:1:1340
+8460:1:1344
+8461:1:1345
+8462:1:1339
+8463:1:1340
+8464:1:1344
+8465:1:1345
+8466:1:1353
+8467:1:1358
+8468:1:1359
+8469:1:1370
+8470:1:1371
+8471:1:1372
+8472:1:1383
+8473:1:1388
+8474:1:1389
+8475:1:1400
+8476:1:1401
+8477:1:1402
+8478:1:1400
+8479:1:1401
+8480:1:1402
+8481:1:1413
+8482:0:4533
+8483:2:4109
+8484:2:4110
+8485:2:4114
+8486:2:4115
+8487:2:4123
+8488:2:4124
+8489:2:4128
+8490:2:4129
+8491:2:4137
+8492:2:4142
+8493:2:4146
+8494:2:4147
+8495:2:4155
+8496:2:4156
+8497:2:4160
+8498:2:4161
+8499:2:4155
+8500:2:4156
+8501:2:4160
+8502:2:4161
+8503:2:4169
+8504:2:4174
+8505:2:4175
+8506:2:4186
+8507:2:4194
+8508:2:4195
+8509:2:4199
+8510:2:4204
+8511:2:4205
+8512:2:4216
+8513:2:4217
+8514:2:4218
+8515:2:4216
+8516:2:4217
+8517:2:4218
+8518:2:4229
+8519:0:4533
+8520:2:3127
+8521:0:4533
+8522:1:11
+8523:0:4533
+8524:1:1422
+8525:1:1423
+8526:1:1427
+8527:1:1428
+8528:1:1436
+8529:1:1437
+8530:1:1441
+8531:1:1442
+8532:1:1450
+8533:1:1455
+8534:1:1459
+8535:1:1460
+8536:1:1468
+8537:1:1469
+8538:1:1473
+8539:1:1474
+8540:1:1468
+8541:1:1469
+8542:1:1473
+8543:1:1474
+8544:1:1482
+8545:1:1487
+8546:1:1488
+8547:1:1499
+8548:1:1500
+8549:1:1501
+8550:1:1512
+8551:1:1517
+8552:1:1518
+8553:1:1529
+8554:1:1530
+8555:1:1531
+8556:1:1529
+8557:1:1530
+8558:1:1531
+8559:1:1542
+8560:1:1549
+8561:1:1553
+8562:0:4533
+8563:2:3975
+8564:2:3976
+8565:2:3980
+8566:2:3981
+8567:2:3989
+8568:2:3990
+8569:2:3994
+8570:2:3995
+8571:2:4003
+8572:2:4008
+8573:2:4012
+8574:2:4013
+8575:2:4021
+8576:2:4022
+8577:2:4026
+8578:2:4027
+8579:2:4021
+8580:2:4022
+8581:2:4026
+8582:2:4027
+8583:2:4035
+8584:2:4040
+8585:2:4041
+8586:2:4052
+8587:2:4060
+8588:2:4061
+8589:2:4065
+8590:2:4070
+8591:2:4071
+8592:2:4082
+8593:2:4083
+8594:2:4084
+8595:2:4082
+8596:2:4083
+8597:2:4084
+8598:2:4095
+8599:2:4103
+8600:0:4533
+8601:2:3127
+8602:0:4533
+8603:1:11
+8604:0:4533
+8605:2:4109
+8606:2:4110
+8607:2:4114
+8608:2:4115
+8609:2:4123
+8610:2:4124
+8611:2:4128
+8612:2:4129
+8613:2:4137
+8614:2:4142
+8615:2:4146
+8616:2:4147
+8617:2:4155
+8618:2:4156
+8619:2:4160
+8620:2:4161
+8621:2:4155
+8622:2:4156
+8623:2:4160
+8624:2:4161
+8625:2:4169
+8626:2:4174
+8627:2:4175
+8628:2:4186
+8629:2:4194
+8630:2:4195
+8631:2:4199
+8632:2:4204
+8633:2:4205
+8634:2:4216
+8635:2:4217
+8636:2:4218
+8637:2:4216
+8638:2:4217
+8639:2:4218
+8640:2:4229
+8641:0:4533
+8642:2:3127
+8643:0:4533
+8644:2:3975
+8645:2:3976
+8646:2:3980
+8647:2:3981
+8648:2:3989
+8649:2:3990
+8650:2:3994
+8651:2:3995
+8652:2:4003
+8653:2:4008
+8654:2:4012
+8655:2:4013
+8656:2:4021
+8657:2:4022
+8658:2:4026
+8659:2:4027
+8660:2:4021
+8661:2:4022
+8662:2:4026
+8663:2:4027
+8664:2:4035
+8665:2:4040
+8666:2:4041
+8667:2:4052
+8668:2:4060
+8669:2:4061
+8670:2:4065
+8671:2:4070
+8672:2:4071
+8673:2:4082
+8674:2:4083
+8675:2:4084
+8676:2:4082
+8677:2:4083
+8678:2:4084
+8679:2:4095
+8680:2:4103
+8681:0:4533
+8682:2:3127
+8683:0:4533
+8684:1:1554
+8685:1:1558
+8686:1:1559
+8687:1:1563
+8688:1:1564
+8689:1:1572
+8690:1:1580
+8691:1:1581
+8692:1:1585
+8693:1:1589
+8694:1:1590
+8695:1:1585
+8696:1:1589
+8697:1:1590
+8698:1:1594
+8699:1:1601
+8700:1:1608
+8701:1:1609
+8702:1:1616
+8703:1:1621
+8704:1:1628
+8705:1:1629
+8706:1:1628
+8707:1:1629
+8708:1:1636
This page took 1.076357 seconds and 4 git commands to generate.