[PATCH 2/6] formal/spinhint: Employ new scheme for code snippet

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



>From 7c319159fddc42f02836e23581a73facd5d54b47 Mon Sep 17 00:00:00 2001
From: Akira Yokosawa <akiyks@xxxxxxxxx>
Date: Thu, 31 Jan 2019 00:08:30 +0900
Subject: [PATCH 2/6] formal/spinhint: Employ new scheme for code snippet

Other than simple transformations, this commit includes the following
changes:

    o Move "listing" environment to outside of "enumerate"
      environment. This is to avoid slight behavior change of
      "VerbatimL" environment inside "enumerate".

      ("VerbatimN" looks OK inside "enumerate".)

    o Embed the unoptimized definition of sum_unordered into
      CodeSamples/formal/promela/qrcu.spin using the
      "#ifndef FCV_SNIPPET" construct, rather than putting
      it in spinhint.tex. Luckily, we don't reference the
      optimized definition as a code snippet.
      (Related to Quick Quiz 12.3)

    o Substitute white spaces for tab characters in snippets
      which appear in the middle of a line.

    o Enclose "do-od" and "if-fi" in \co{} macros.

Signed-off-by: Akira Yokosawa <akiyks@xxxxxxxxx>
---
 CodeSamples/formal/promela/atomicincrement.spin |   2 +
 CodeSamples/formal/promela/increment.spin       |  46 +-
 CodeSamples/formal/promela/lock.h               |  16 +-
 CodeSamples/formal/promela/lock.spin            |  46 +-
 CodeSamples/formal/promela/qrcu.spin            |  95 ++--
 formal/spinhint.tex                             | 681 +++++++-----------------
 6 files changed, 318 insertions(+), 568 deletions(-)

diff --git a/CodeSamples/formal/promela/atomicincrement.spin b/CodeSamples/formal/promela/atomicincrement.spin
index 5f4f774..ebeedb2 100644
--- a/CodeSamples/formal/promela/atomicincrement.spin
+++ b/CodeSamples/formal/promela/atomicincrement.spin
@@ -3,6 +3,7 @@
 byte counter = 0;
 byte progress[NUMPROCS];
 
+//\begin{snippet}[labelbase=ln:formal:promela:atomicincrement:incrementer,commandchars=\\\@\$]
 proctype incrementer(byte me)
 {
 	int temp;
@@ -13,6 +14,7 @@ proctype incrementer(byte me)
 	}
 	progress[me] = 1;
 }
+//\end{snippet}
 
 init {
 	int i = 0;
diff --git a/CodeSamples/formal/promela/increment.spin b/CodeSamples/formal/promela/increment.spin
index d82bab1..263d4bd 100644
--- a/CodeSamples/formal/promela/increment.spin
+++ b/CodeSamples/formal/promela/increment.spin
@@ -1,40 +1,42 @@
-#define NUMPROCS 3
+//\begin{snippet}[labelbase=ln:formal:promela:increment:whole,commandchars=\\\@\$]
+#define NUMPROCS 2		//\lnlbl{nprocs}
 
-byte counter = 0;
-byte progress[NUMPROCS];
+byte counter = 0;		//\lnlbl{count}
+byte progress[NUMPROCS];	//\lnlbl{prog}
 
-proctype incrementer(byte me)
+proctype incrementer(byte me)	//\lnlbl{proc:b}
 {
 	int temp;
 
-	temp = counter;
-	counter = temp + 1;
-	progress[me] = 1;
-}
+	temp = counter;		//\lnlbl{incr:b}
+	counter = temp + 1;	//\lnlbl{incr:e}
+	progress[me] = 1;	//\lnlbl{setprog}
+}				//\lnlbl{proc:e}
 
-init {
+init {				//\lnlbl{init:b}
 	int i = 0;
 	int sum = 0;
 
-	atomic {
+	atomic {		//\lnlbl{doinit:b}
 		i = 0;
-		do
-		:: i < NUMPROCS ->
+		do		//\lnlbl{dood1:b}
+		:: i < NUMPROCS ->	//\lnlbl{block1:b}
 			progress[i] = 0;
 			run incrementer(i);
-			i++;
-		:: i >= NUMPROCS -> break;
-		od;
-	}
-	atomic {
+			i++;		//\lnlbl{block1:e}
+		:: i >= NUMPROCS -> break;	//\lnlbl{block2}
+		od;		//\lnlbl{dood1:e}
+	}			//\lnlbl{doinit:e}
+	atomic {		//\lnlbl{assert:b}
 		i = 0;
 		sum = 0;
-		do
+		do		//\lnlbl{dood2:b}
 		:: i < NUMPROCS ->
 			sum = sum + progress[i];
 			i++
 		:: i >= NUMPROCS -> break;
-		od;
-		assert(sum < NUMPROCS || counter == NUMPROCS);
-	}
-}
+		od;		//\lnlbl{dood2:e}
+		assert(sum < NUMPROCS || counter == NUMPROCS);	//\lnlbl{assert}
+	}			//\lnlbl{assert:e}
+}				//\lnlbl{init:e}
+//\end{snippet}
diff --git a/CodeSamples/formal/promela/lock.h b/CodeSamples/formal/promela/lock.h
index 069945d..aa046df 100644
--- a/CodeSamples/formal/promela/lock.h
+++ b/CodeSamples/formal/promela/lock.h
@@ -1,14 +1,16 @@
+//\begin{snippet}[labelbase=ln:formal:promela:lock:whole,commandchars=\!\[\]]
 #define spin_lock(mutex) \
-	do \
-	:: 1 -> atomic { \
+	do /* \lnlbl{dood:b} */\
+	:: 1 -> atomic { /* \lnlbl{one} */\
 			if \
-			:: mutex == 0 -> \
-				mutex = 1; \
-				break \
-			:: else -> skip \
+			:: mutex == 0 -> /* \lnlbl{notheld} */\
+				mutex = 1; /* \lnlbl{acq} */\
+				break /* \lnlbl{break} */\
+			:: else -> skip /* \lnlbl{held} */\
 			fi \
 		} \
-	od
+	od /* \lnlbl{dood:e} */
 
 #define spin_unlock(mutex) \
 	mutex = 0
+//\end{snippet}
diff --git a/CodeSamples/formal/promela/lock.spin b/CodeSamples/formal/promela/lock.spin
index 0057cec..4bbcbd5 100644
--- a/CodeSamples/formal/promela/lock.spin
+++ b/CodeSamples/formal/promela/lock.spin
@@ -1,35 +1,36 @@
+//\begin{snippet}[labelbase=ln:formal:promela:lock:spin,commandchars=\\\@\$]
 #include "lock.h"
 
-#define N_LOCKERS 3
+#define N_LOCKERS 3			//\lnlbl{nlockers}
 
-bit mutex = 0;
-bit havelock[N_LOCKERS];
-int sum;
+bit mutex = 0;				//\lnlbl{mutex}
+bit havelock[N_LOCKERS];		//\lnlbl{array}
+int sum;				//\lnlbl{sum}
 
-proctype locker(byte me)
+proctype locker(byte me)		//\lnlbl{locker:b}
 {
 	do
 	:: 1 ->
-		spin_lock(mutex);
-		havelock[me] = 1;
-		havelock[me] = 0;
-		spin_unlock(mutex)
+		spin_lock(mutex);	//\lnlbl{locker:lock}
+		havelock[me] = 1;	//\lnlbl{locker:claim}
+		havelock[me] = 0;	//\lnlbl{locker:unclaim}
+		spin_unlock(mutex)	//\lnlbl{locker:unlock}
 	od
-}
+}					//\lnlbl{locker:e}
 
-init {
+init {					//\lnlbl{init:b}
 	int i = 0;
 	int j;
 
 end:	do 
 	:: i < N_LOCKERS ->
-		havelock[i] = 0;
-		run locker(i);
-		i++
-	:: i >= N_LOCKERS ->
-		sum = 0;
-		j = 0;
-		atomic {
+		havelock[i] = 0;	//\lnlbl{init:array}
+		run locker(i);		//\lnlbl{init:start}
+		i++			//\lnlbl{init:next}
+	:: i >= N_LOCKERS ->		//\lnlbl{init:chkassert}
+		sum = 0;		//\lnlbl{init:sum}
+		j = 0;			//\lnlbl{init:j}
+		atomic {		//\lnlbl{init:atm:b}
 			do
 			:: j < N_LOCKERS ->
 				sum = sum + havelock[j];
@@ -37,8 +38,9 @@ end:	do
 			:: j >= N_LOCKERS ->
 				break
 			od
-		}
-		assert(sum <= 1);
-		break
+		}			//\lnlbl{init:atm:e}
+		assert(sum <= 1);	//\lnlbl{init:assert}
+		break			//\lnlbl{init:break}
 	od
-}
+}					//\lnlbl{init:e}
+//\end{snippet}
diff --git a/CodeSamples/formal/promela/qrcu.spin b/CodeSamples/formal/promela/qrcu.spin
index 220e135..74315c9 100644
--- a/CodeSamples/formal/promela/qrcu.spin
+++ b/CodeSamples/formal/promela/qrcu.spin
@@ -1,3 +1,4 @@
+//\begin{snippet}[labelbase=ln:formal:promela:qrcu:gvar,commandchars=\\\{\}]
 #include "lock.h"
 
 #define N_QRCU_READERS 2
@@ -7,28 +8,33 @@ bit idx = 0;
 byte ctr[2];
 byte readerprogress[N_QRCU_READERS];
 bit mutex = 0;
+//\end{snippet}
 
+//\begin{snippet}[labelbase=ln:formal:promela:qrcu:reader,commandchars=\\\@\$]
 proctype qrcu_reader(byte me)
 {
 	int myidx;
 
-	do
-	:: 1 ->
-		myidx = idx;
-		atomic {
+	do				//\lnlbl{do}
+	:: 1 ->				//\lnlbl{one}
+		myidx = idx;		//\lnlbl{curidx}
+		atomic {		//\lnlbl{atm:b}
 			if
 			:: ctr[myidx] > 0 ->
 				ctr[myidx]++;
 				break
 			:: else -> skip
 			fi
-		}
-	od;
-	readerprogress[me] = 1;
-	readerprogress[me] = 2;
-	atomic { ctr[myidx]-- }
+		}			//\lnlbl{atm:e}
+	od;				//\lnlbl{od}
+	readerprogress[me] = 1;		//\lnlbl{cs:entry}
+	readerprogress[me] = 2;		//\lnlbl{cs:exit}
+	atomic { ctr[myidx]-- }		//\lnlbl{atm:dec}
 }
+//\end{snippet}
 
+//\begin{snippet}[labelbase=ln:formal:promela:qrcu:sum_unordered,commandchars=\!\@\$]
+#ifndef FCV_SNIPPET
 #define sum_unordered \
 	atomic { \
 		if \
@@ -41,19 +47,37 @@ proctype qrcu_reader(byte me)
 		fi; \
 	} \
 	sum = sum + ctr[i]
+#else /* #ifndef FCV_SNIPPET */
+#define sum_unordered \
+	atomic { /* \lnlbl{fetch:b} */\
+		do /* \lnlbl{do} */\
+		:: 1 -> /* \lnlbl{g1} */\
+			sum = ctr[0]; \
+			i = 1; \
+			break \
+		:: 1 -> /* \lnlbl{g2} */\
+			sum = ctr[1]; \
+			i = 0; \
+			break \
+		od; /* \lnlbl{od} */\
+	} /* \lnlbl{fetch:e} */\
+	sum = sum + ctr[i] /* \lnlbl{sum_other} */
+#endif /* #ifndef FCV_SNIPPET */
+//\end{snippet}
 
+//\begin{snippet}[labelbase=ln:formal:promela:qrcu:updater,keepcomment=yes,commandchars=\\\@\$]
 proctype qrcu_updater(byte me)
 {
 	int i;
 	byte readerstart[N_QRCU_READERS];
 	int sum;
 
-	do
+	do					//\lnlbl{do}
 	:: 1 ->
 
 		/* Snapshot reader state. */
 
-		atomic {
+		atomic {			//\lnlbl{atm1:b}
 			i = 0;
 			do
 			:: i < N_QRCU_READERS ->
@@ -62,65 +86,68 @@ proctype qrcu_updater(byte me)
 			:: i >= N_QRCU_READERS ->
 				break
 			od
-		}
+		}				//\lnlbl{atm1:e}
 
-		sum_unordered;
-		if
+		sum_unordered;			//\lnlbl{sum_unord}
+		if				//\lnlbl{reinvoke:b}
 		:: sum <= 1 -> sum_unordered
 		:: else -> skip
-		fi;
-		if
+		fi;				//\lnlbl{reinvoke:e}
+		if				//\lnlbl{slow:b}
 		:: sum > 1 ->
-			spin_lock(mutex);
-			atomic { ctr[!idx]++ }
+			spin_lock(mutex);	//\lnlbl{acq}
+			atomic { ctr[!idx]++ }	//\lnlbl{flip_idx:b}
 			idx = !idx;
-			atomic { ctr[!idx]-- }
-			do
+			atomic { ctr[!idx]-- }	//\lnlbl{flip_idx:e}
+			do			//\lnlbl{wait:b}
 			:: ctr[!idx] > 0 -> skip
 			:: ctr[!idx] == 0 -> break
-			od;
-			spin_unlock(mutex);
+			od;			//\lnlbl{wait:e}
+			spin_unlock(mutex);	//\lnlbl{rel}
 		:: else -> skip
-		fi;
+		fi;				//\lnlbl{slow:e}
 
 		/* Verify reader progress. */
 
-		atomic {
+		atomic {			//\lnlbl{atm2:b}
 			i = 0;
 			sum = 0;
 			do
 			:: i < N_QRCU_READERS ->
 				sum = sum + (readerstart[i] == 1 &&
-					     readerprogress[i] == 1);
+				             readerprogress[i] == 1);
 				i++
 			:: i >= N_QRCU_READERS ->
-				assert(sum == 0);
+				assert(sum == 0);	//\lnlbl{assert}
 				break
 			od
-		}
-	od
+		}				//\lnlbl{atm2:e}
+	od					//\lnlbl{od}
 }
+//\end{snippet}
 
+//\begin{snippet}[labelbase=ln:formal:promela:qrcu:init,commandchars=\\\@\$]
 init {
 	int i;
 
 	atomic {
-		ctr[idx] = 1;
-		ctr[!idx] = 0;
-		i = 0;
+		ctr[idx] = 1;			//\lnlbl{i_ctr:b}
+		ctr[!idx] = 0;			//\lnlbl{i_ctr:e}
+		i = 0;				//\lnlbl{spn_r:b}
 		do
 		:: i < N_QRCU_READERS ->
 			readerprogress[i] = 0;
 			run qrcu_reader(i);
 			i++
 		:: i >= N_QRCU_READERS -> break
-		od;
-		i = 0;
+		od;				//\lnlbl{spn_r:e}
+		i = 0;				//\lnlbl{spn_u:b}
 		do
 		:: i < N_QRCU_UPDATERS ->
 			run qrcu_updater(i);
 			i++
 		:: i >= N_QRCU_UPDATERS -> break
-		od
+		od				//\lnlbl{spn_u:e}
 	}
 }
+//\end{snippet}
diff --git a/formal/spinhint.tex b/formal/spinhint.tex
index 11c2c7d..5ba9f04 100644
--- a/formal/spinhint.tex
+++ b/formal/spinhint.tex
@@ -62,115 +62,76 @@ more complex uses.
 \label{sec:formal:Promela Warm-Up: Non-Atomic Increment}
 
 \begin{listing}[tbp]
-{ \scriptsize
-\begin{verbbox}
-  1 #define NUMPROCS 2
-  2
-  3 byte counter = 0;
-  4 byte progress[NUMPROCS];
-  5
-  6 proctype incrementer(byte me)
-  7 {
-  8   int temp;
-  9
- 10   temp = counter;
- 11   counter = temp + 1;
- 12   progress[me] = 1;
- 13 }
- 14
- 15 init {
- 16   int i = 0;
- 17   int sum = 0;
- 18
- 19   atomic {
- 20     i = 0;
- 21     do
- 22     :: i < NUMPROCS ->
- 23       progress[i] = 0;
- 24       run incrementer(i);
- 25       i++
- 26     :: i >= NUMPROCS -> break
- 27     od;
- 28   }
- 29   atomic {
- 30     i = 0;
- 31     sum = 0;
- 32     do
- 33     :: i < NUMPROCS ->
- 34       sum = sum + progress[i];
- 35       i++
- 36     :: i >= NUMPROCS -> break
- 37     od;
- 38     assert(sum < NUMPROCS || counter == NUMPROCS)
- 39   }
- 40 }
-\end{verbbox}
-}
-\centering
-\theverbbox
+\input{CodeSamples/formal/promela/increment@xxxxxxxxx}
 \caption{Promela Code for Non-Atomic Increment}
 \label{lst:analysis:Promela Code for Non-Atomic Increment}
 \end{listing}
 
+\begin{lineref}[ln:formal:promela:increment:whole]
 Listing~\ref{lst:analysis:Promela Code for Non-Atomic Increment}
 demonstrates the textbook race condition
 resulting from non-atomic increment.
-Line~1 defines the number of processes to run (we will vary this
-to see the effect on state space), line~3 defines the counter,
-and line~4 is used to implement the assertion that appears on
-lines~29-39.
+Line~\lnref{nprocs} defines the number of processes to run (we will vary this
+to see the effect on state space), line~\lnref{count} defines the counter,
+and line~\lnref{prog} is used to implement the assertion that appears on
+lines~\lnref{assert:b}-\lnref{assert:e}.
 
-Lines~6-13 define a process that increments the counter non-atomically.
+Lines~\lnref{proc:b}-\lnref{proc:e} define a process that increments
+the counter non-atomically.
 The argument \co{me} is the process number, set by the initialization
 block later in the code.
 Because simple Promela statements are each assumed atomic, we must
-break the increment into the two statements on lines~10-11.
-The assignment on line~12 marks the process's completion.
+break the increment into the two statements on
+lines~\lnref{incr:b}-\lnref{incr:e}.
+The assignment on line~\lnref{setprog} marks the process's completion.
 Because the Spin system will fully search the state space, including
 all possible sequences of states, there is no need for the loop
 that would be used for conventional testing.
 
-Lines~15-40 are the initialization block, which is executed first.
-Lines~19-28 actually do the initialization, while lines~29-39
+Lines~\lnref{init:b}-\lnref{init:e} are the initialization block,
+which is executed first.
+Lines~\lnref{doinit:b}-\lnref{doinit:e} actually do the initialization,
+while lines~\lnref{assert:b}-\lnref{assert:e}
 perform the assertion.
 Both are atomic blocks in order to avoid unnecessarily increasing
 the state space: because they are not part of the algorithm proper,
 we lose no verification coverage by making them atomic.
 
-The do-od construct on lines~21-27 implements a Promela loop,
+The \co{do-od} construct on lines~\lnref{dood1:b}-\lnref{dood1:e}
+implements a Promela loop,
 which can be thought of as a C {\tt for (;;)} loop containing a
 \co{switch} statement that allows expressions in case labels.
 The condition blocks (prefixed by {\tt ::})
 are scanned non-deterministically,
 though in this case only one of the conditions can possibly hold at a given
 time.
-The first block of the do-od from lines~22-25 initializes the i-th
+The first block of the \co{do-od} from
+lines~\lnref{block1:b}-\lnref{block1:e}
+initializes the i-th
 incrementer's progress cell, runs the i-th incrementer's process, and
 then increments the variable \co{i}.
-The second block of the do-od on line~26 exits the loop once
+The second block of the \co{do-od} on
+line~\lnref{block2} exits the loop once
 these processes have been started.
 
-The atomic block on lines~29-39 also contains a similar do-od
+The atomic block on lines~\lnref{assert:b}-\lnref{assert:e} also contains
+a similar \co{do-od}
 loop that sums up the progress counters.
-The {\tt assert()} statement on line~38 verifies that if all processes
+The \co{assert()} statement on line~\lnref{assert} verifies that
+if all processes
 have been completed, then all counts have been correctly recorded.
+\end{lineref}
 
 You can build and run this program as follows:
 
-\vspace{5pt}
-\begin{minipage}[t]{\columnwidth}
-\scriptsize
-\begin{verbatim}
-spin -a increment.spin		# Translate the model to C
-cc -DSAFETY -o pan pan.c	# Compile the model
-./pan				# Run the model
-\end{verbatim}
-\end{minipage}
-\vspace{5pt}
+\begin{VerbatimU}
+spin -a increment.spin      # Translate the model to C
+cc -DSAFETY -o pan pan.c    # Compile the model
+./pan                       # Run the model
+\end{VerbatimU}
 
 \begin{listing*}[tbp]
-{ \scriptsize
-\begin{verbbox}
+\begin{VerbatimL}[numbers=none]
 pan: assertion violated ((sum<2)||(counter==2)) (at depth 20)
 pan: wrote increment.spin.trail
 (Spin Version 4.2.5 -- 2 April 2005)
@@ -191,10 +152,7 @@ State-vector 40 byte, depth reached 22, errors: 1
 hash conflicts: 0 (resolved)
 
 2.622  memory usage (Mbyte)
-\end{verbbox}
-}
-\centering
-\theverbbox
+\end{VerbatimL}
 \caption{Non-Atomic Increment spin Output}
 \label{lst:analysis:Non-Atomic Increment spin Output}
 \end{listing*}
@@ -214,18 +172,12 @@ The final line shows memory usage.
 
 The \co{trail} file may be rendered human-readable as follows:
 
-\vspace{5pt}
-\begin{minipage}[t]{\columnwidth}
-\scriptsize
-\begin{verbatim}
+\begin{VerbatimU}
 spin -t -p increment.spin
-\end{verbatim}
-\end{minipage}
-\vspace{5pt}
+\end{VerbatimU}
 
 \begin{listing*}[htbp]
-{ \scriptsize
-\begin{verbbox}
+\begin{VerbatimL}[numbers=none]
 Starting :init: with pid 0
  1: proc 0 (:init:) line 20 "increment.spin" (state 1) [i = 0]
  2: proc 0 (:init:) line 22 "increment.spin" (state 2) [((i<2))]
@@ -268,10 +220,7 @@ spin: trail ends after 21 steps
                 progress[1] = 1
 21: proc 0 (:init:) line 40 "increment.spin" (state 24) <valid end state>
 3 processes created
-\end{verbbox}
-}
-\centering
-\theverbbox
+\end{VerbatimL}
 \caption{Non-Atomic Increment Error Trail}
 \label{lst:analysis:Non-Atomic Increment Error Trail}
 \end{listing*}
@@ -287,29 +236,13 @@ The assertion then triggered, after which the global state is displayed.
 \label{sec:formal:Promela Warm-Up: Atomic Increment}
 
 \begin{listing}[htbp]
-{ \scriptsize
-\begin{verbbox}
-  1 proctype incrementer(byte me)
-  2 {
-  3   int temp;
-  4
-  5   atomic {
-  6     temp = counter;
-  7     counter = temp + 1;
-  8   }
-  9   progress[me] = 1;
- 10 }
-\end{verbbox}
-}
-\centering
-\theverbbox
+\input{CodeSamples/formal/promela/atomicincrement@xxxxxxxxxxxxxxx}
 \caption{Promela Code for Atomic Increment}
 \label{lst:analysis:Promela Code for Atomic Increment}
 \end{listing}
 
 \begin{listing}[htbp]
-{ \scriptsize
-\begin{verbbox}
+\begin{VerbatimL}[numbers=none]
 (Spin Version 4.2.5 -- 2 April 2005)
         + Partial Order Reduction
 
@@ -332,10 +265,7 @@ unreached in proctype incrementer
         (0 of 5 states)
 unreached in proctype :init:
         (0 of 24 states)
-\end{verbbox}
-}
-\centering
-\theverbbox
+\end{VerbatimL}
 \caption{Atomic Increment spin Output}
 \label{lst:analysis:Atomic Increment spin Output}
 \end{listing}
@@ -516,19 +446,14 @@ The following tricks can help you to abuse Promela safely:
 	matters (e.g., unprotected by locks), but where you have
 	no memory barriers.  This can be modeled in Promela as follows:
 
-\vspace{5pt}
-\begin{minipage}[t]{\columnwidth}
-\scriptsize
-\begin{verbatim}
-  1 if
-  2 :: 1 -> r1 = x;
-  3   r2 = y
-  4 :: 1 -> r2 = y;
-  5   r1 = x
-  6 fi
-\end{verbatim}
-\end{minipage}
-\vspace{5pt}
+\begin{VerbatimN}[samepage=true]
+if
+:: 1 -> r1 = x;
+        r2 = y
+:: 1 -> r2 = y;
+        r1 = x
+fi
+\end{VerbatimN}
 
 	The two branches of the \co{if} statement will be selected
 	nondeterministically, since they both are available.
@@ -539,52 +464,6 @@ The following tricks can help you to abuse Promela safely:
 	if used too heavily.
 	In addition, it requires you to anticipate possible reorderings.
 
-\begin{listing}[tbp]
-{ \scriptsize
-\begin{verbbox}
-  1 i = 0;
-  2 sum = 0;
-  3 do
-  4 :: i < N_QRCU_READERS ->
-  5   sum = sum + (readerstart[i] == 1 &&
-  6     readerprogress[i] == 1);
-  7   i++
-  8 :: i >= N_QRCU_READERS ->
-  9   assert(sum == 0);
- 10   break
- 11 od
-\end{verbbox}
-}
-\centering
-\theverbbox
-\caption{Complex Promela Assertion}
-\label{lst:analysis:Complex Promela Assertion}
-\end{listing}
-
-\begin{listing}[tbp]
-{ \scriptsize
-\begin{verbbox}
-  1 atomic {
-  2   i = 0;
-  3   sum = 0;
-  4   do
-  5   :: i < N_QRCU_READERS ->
-  6     sum = sum + (readerstart[i] == 1 &&
-  7       readerprogress[i] == 1);
-  8     i++
-  9   :: i >= N_QRCU_READERS ->
- 10     assert(sum == 0);
- 11     break
- 12   od
- 13 }
-\end{verbbox}
-}
-\centering
-\theverbbox
-\caption{Atomic Block for Complex Promela Assertion}
-\label{lst:analysis:Atomic Block for Complex Promela Assertion}
-\end{listing}
-
 \item	State reduction.  If you have complex assertions, evaluate
 	them under \co{atomic}.  After all, they are not part of the
 	algorithm.  One example of a complex assertion (to be discussed
@@ -604,55 +483,77 @@ The following tricks can help you to abuse Promela safely:
 	combinatorial explosion.
 \end{enumerate}
 
+\begin{listing}[tbp]
+\begin{VerbatimL}
+i = 0;
+sum = 0;
+do
+:: i < N_QRCU_READERS ->
+	sum = sum + (readerstart[i] == 1 &&
+	             readerprogress[i] == 1);
+	i++
+:: i >= N_QRCU_READERS ->
+	assert(sum == 0);
+	break
+od
+\end{VerbatimL}
+\caption{Complex Promela Assertion}
+\label{lst:analysis:Complex Promela Assertion}
+\end{listing}
+
+\begin{listing}[tbp]
+\begin{VerbatimL}
+atomic {
+	i = 0;
+	sum = 0;
+	do
+	:: i < N_QRCU_READERS ->
+		sum = sum + (readerstart[i] == 1 &&
+		             readerprogress[i] == 1);
+		i++
+	:: i >= N_QRCU_READERS ->
+		assert(sum == 0);
+		break
+	od
+}
+\end{VerbatimL}
+\caption{Atomic Block for Complex Promela Assertion}
+\label{lst:analysis:Atomic Block for Complex Promela Assertion}
+\end{listing}
+
 Now we are ready for more complex examples.
 
 \subsection{Promela Example: Locking}
 \label{sec:formal:Promela Example: Locking}
 
 \begin{listing}[tbp]
-{ \scriptsize
-\begin{verbbox}
-  1 #define spin_lock(mutex) \
-  2   do \
-  3   :: 1 -> atomic { \
-  4       if \
-  5       :: mutex == 0 -> \
-  6         mutex = 1; \
-  7         break \
-  8       :: else -> skip \
-  9       fi \
- 10     } \
- 11   od
- 12
- 13 #define spin_unlock(mutex) \
- 14   mutex = 0
-\end{verbbox}
-}
-\centering
-\theverbbox
+\input{CodeSamples/formal/promela/lock@xxxxxxxxx}
 \caption{Promela Code for Spinlock}
 \label{lst:analysis:Promela Code for Spinlock}
 \end{listing}
 
+\begin{lineref}[ln:formal:promela:lock:whole]
 Since locks are generally useful, \co{spin_lock()} and
 \co{spin_unlock()}
 macros are provided in \path{lock.h}, which may be included from
 multiple Promela models, as shown in
 Listing~\ref{lst:analysis:Promela Code for Spinlock}.
-The \co{spin_lock()} macro contains an infinite do-od loop
-spanning lines~2-11,
-courtesy of the single guard expression of ``1'' on line~3.
+The \co{spin_lock()} macro contains an infinite \co{do-od} loop
+spanning lines~\lnref{dood:b}-\lnref{dood:e},
+courtesy of the single guard expression of ``1'' on line~\lnref{one}.
 The body of this loop is a single atomic block that contains
-an if-fi statement.
-The if-fi construct is similar to the do-od construct, except
+an \co{if-fi} statement.
+The \co{if-fi} construct is similar to the \co{do-od} construct, except
 that it takes a single pass rather than looping.
-If the lock is not held on line~5, then line~6 acquires it and
-line~7 breaks out of the enclosing do-od loop (and also exits
+If the lock is not held on line~\lnref{notheld}, then
+line~\lnref{acq} acquires it and
+line~\lnref{break} breaks out of the enclosing \co{do-od} loop (and also exits
 the atomic block).
-On the other hand, if the lock is already held on line~8,
-we do nothing (\co{skip}), and fall out of the if-fi and the
+On the other hand, if the lock is already held on line~\lnref{held},
+we do nothing (\co{skip}), and fall out of the \co{if-fi} and the
 atomic block so as to take another pass through the outer
 loop, repeating until the lock is available.
+\end{lineref}
 
 The \co{spin_unlock()} macro simply marks the lock as no
 longer held.
@@ -668,81 +569,39 @@ As noted earlier, and as will be seen in a later example,
 weak memory ordering must be explicitly coded.
 
 \begin{listing}[tb]
-{ \scriptsize
-\begin{verbbox}
-  1 #include "lock.h"
-  2
-  3 #define N_LOCKERS 3
-  4
-  5 bit mutex = 0;
-  6 bit havelock[N_LOCKERS];
-  7 int sum;
-  8
-  9 proctype locker(byte me)
- 10 {
- 11   do
- 12   :: 1 ->
- 13     spin_lock(mutex);
- 14     havelock[me] = 1;
- 15     havelock[me] = 0;
- 16     spin_unlock(mutex)
- 17   od
- 18 }
- 19
- 20 init {
- 21   int i = 0;
- 22   int j;
- 23
- 24 end:  do
- 25   :: i < N_LOCKERS ->
- 26     havelock[i] = 0;
- 27     run locker(i);
- 28     i++
- 29   :: i >= N_LOCKERS ->
- 30     sum = 0;
- 31     j = 0;
- 32     atomic {
- 33       do
- 34       :: j < N_LOCKERS ->
- 35         sum = sum + havelock[j];
- 36         j = j + 1
- 37       :: j >= N_LOCKERS ->
- 38         break
- 39       od
- 40     }
- 41     assert(sum <= 1);
- 42     break
- 43   od
- 44 }
-\end{verbbox}
-}
-\centering
-\theverbbox
+\input{CodeSamples/formal/promela/lock@xxxxxxxx}
 \caption{Promela Code to Test Spinlocks}
 \label{lst:analysis:Promela Code to Test Spinlocks}
 \end{listing}
 
+\begin{lineref}[ln:formal:promela:lock:spin]
 These macros are tested by the Promela code shown in
 Listing~\ref{lst:analysis:Promela Code to Test Spinlocks}.
 This code is similar to that used to test the increments,
 with the number of locking processes defined by the \co{N_LOCKERS}
-macro definition on line~3.
-The mutex itself is defined on line~5, an array to track the lock owner
-on line~6, and line~7 is used by assertion
+macro definition on line~\lnref{nlockers}.
+The mutex itself is defined on line~\lnref{mutex},
+an array to track the lock owner
+on line~\lnref{array}, and line~\lnref{sum} is used by assertion
 code to verify that only one process holds the lock.
-
-The locker process is on lines~9-18, and simply loops forever
-acquiring the lock on line~13, claiming it on line~14,
-unclaiming it on line~15, and releasing it on line~16.
-
-The init block on lines~20-44 initializes the current locker's
-havelock array entry on line~26, starts the current locker on
-line~27, and advances to the next locker on line~28.
-Once all locker processes are spawned, the do-od loop
-moves to line~29, which checks the assertion.
-Lines~30 and~31 initialize the control variables,
-lines~32-40 atomically sum the havelock array entries,
-line~41 is the assertion, and line~42 exits the loop.
+\end{lineref}
+
+\begin{lineref}[ln:formal:promela:lock:spin:locker]
+The locker process is on lines~\lnref{b}-\lnref{e}, and simply loops forever
+acquiring the lock on line~\lnref{lock}, claiming it on line~\lnref{claim},
+unclaiming it on line~\lnref{unclaim}, and releasing it on line~\lnref{unlock}.
+\end{lineref}
+
+\begin{lineref}[ln:formal:promela:lock:spin:init]
+The init block on lines~\lnref{b}-\lnref{e} initializes the current locker's
+havelock array entry on line~\lnref{array}, starts the current locker on
+line~\lnref{start}, and advances to the next locker on line~\lnref{next}.
+Once all locker processes are spawned, the \co{do-od} loop
+moves to line~\lnref{chkassert}, which checks the assertion.
+Lines~\lnref{sum} and~\lnref{j} initialize the control variables,
+lines~\lnref{atm:b}-\lnref{atm:e} atomically sum the havelock array entries,
+line~\lnref{assert} is the assertion, and line~\lnref{break} exits the loop.
+\end{lineref}
 
 We can run this model by placing the two code fragments of
 Listings~\ref{lst:analysis:Promela Code for Spinlock}
@@ -750,20 +609,14 @@ and~\ref{lst:analysis:Promela Code to Test Spinlocks} into
 files named \path{lock.h} and \path{lock.spin}, respectively, and then running
 the following commands:
 
-\vspace{5pt}
-\begin{minipage}[t]{\columnwidth}
-\scriptsize
-\begin{verbatim}
+\begin{VerbatimU}
 spin -a lock.spin
 cc -DSAFETY -o pan pan.c
 ./pan
-\end{verbatim}
-\end{minipage}
-\vspace{5pt}
+\end{VerbatimU}
 
 \begin{listing}[htbp]
-{ \scriptsize
-\begin{verbbox}
+\begin{VerbatimL}[numbers=none]
 (Spin Version 4.2.5 -- 2 April 2005)
         + Partial Order Reduction
 
@@ -787,10 +640,7 @@ unreached in proctype locker
         (1 of 20 states)
 unreached in proctype :init:
         (0 of 22 states)
-\end{verbbox}
-}
-\centering
-\theverbbox
+\end{VerbatimL}
 \caption{Output for Spinlock Test}
 \label{lst:analysis:Output for Spinlock Test}
 \end{listing}
@@ -863,16 +713,11 @@ latencies of most other RCU implementations.
 
 	For example:
 
-\vspace{5pt}
-\begin{minipage}[t]{\columnwidth}
-\scriptsize
-\begin{verbatim}
+\begin{VerbatimU}
 idx = qrcu_read_lock(&my_qrcu_struct);
 /* read-side critical section. */
 qrcu_read_unlock(&my_qrcu_struct, idx);
-\end{verbatim}
-\end{minipage}
-\vspace{5pt}
+\end{VerbatimU}
 
 \item	There is a \co{synchronize_qrcu()} primitive that blocks until
 	all pre-existing QRCU read-side critical sections complete,
@@ -894,21 +739,7 @@ but has not yet been included in the Linux kernel as of
 April 2008.
 
 \begin{listing}[htbp]
-{ \scriptsize
-\begin{verbbox}
-  1 #include "lock.h"
-  2
-  3 #define N_QRCU_READERS 2
-  4 #define N_QRCU_UPDATERS 2
-  5
-  6 bit idx = 0;
-  7 byte ctr[2];
-  8 byte readerprogress[N_QRCU_READERS];
-  9 bit mutex = 0;
-\end{verbbox}
-}
-\centering
-\theverbbox
+\input{CodeSamples/formal/promela/qrcu@xxxxxxxx}
 \caption{QRCU Global Variables}
 \label{lst:analysis:QRCU Global Variables}
 \end{listing}
@@ -937,194 +768,104 @@ indicating the state of the corresponding reader:
 Finally, the \co{mutex} variable is used to serialize updaters' slowpaths.
 
 \begin{listing}[htbp]
-{ \scriptsize
-\begin{verbbox}
-  1 proctype qrcu_reader(byte me)
-  2 {
-  3   int myidx;
-  4
-  5   do
-  6   :: 1 ->
-  7     myidx = idx;
-  8     atomic {
-  9       if
- 10       :: ctr[myidx] > 0 ->
- 11         ctr[myidx]++;
- 12         break
- 13       :: else -> skip
- 14       fi
- 15     }
- 16   od;
- 17   readerprogress[me] = 1;
- 18   readerprogress[me] = 2;
- 19   atomic { ctr[myidx]-- }
- 20 }
-\end{verbbox}
-}
-\centering
-\theverbbox
+\input{CodeSamples/formal/promela/qrcu@xxxxxxxxxx}
 \caption{QRCU Reader Process}
 \label{lst:analysis:QRCU Reader Process}
 \end{listing}
 
+\begin{lineref}[ln:formal:promela:qrcu:reader]
 QRCU readers are modeled by the \co{qrcu_reader()} process shown in
 Listing~\ref{lst:analysis:QRCU Reader Process}.
-A do-od loop spans lines~5-16, with a single guard of ``1''
-on line~6 that makes it an infinite loop.
-Line~7 captures the current value of the global index, and lines~8-15
+A \co{do-od} loop spans lines~\lnref{do}-\lnref{od},
+with a single guard of ``1''
+on line~\lnref{one} that makes it an infinite loop.
+Line~\lnref{curidx} captures the current value of the global index,
+and lines~\lnref{atm:b}-\lnref{atm:e}
 atomically increment it (and break from the infinite loop)
 if its value was non-zero (\co{atomic_inc_not_zero()}).
-Line~17 marks entry into the RCU read-side critical section, and
-line~18 marks exit from this critical section, both lines for the benefit of
-the {\tt assert()} statement that we shall encounter later.
-Line~19 atomically decrements the same counter that we incremented,
+Line~\lnref{cs:entry} marks entry into the RCU read-side critical section, and
+line~\lnref{cs:exit} marks exit from this critical section,
+both lines for the benefit of
+the \co{assert()} statement that we shall encounter later.
+Line~\lnref{atm:dec} atomically decrements the same counter that we incremented,
 thereby exiting the RCU read-side critical section.
+\end{lineref}
 
 \begin{listing}[htbp]
-{ \scriptsize
-\begin{verbbox}
-  1 #define sum_unordered \
-  2   atomic { \
-  3     do \
-  4     :: 1 -> \
-  5       sum = ctr[0]; \
-  6       i = 1; \
-  7       break \
-  8     :: 1 -> \
-  9       sum = ctr[1]; \
- 10       i = 0; \
- 11       break \
- 12     od; \
- 13   } \
- 14   sum = sum + ctr[i]
-\end{verbbox}
-}
-\centering
-\theverbbox
+\input{CodeSamples/formal/promela/qrcu@sum_unordered.fcv}
 \caption{QRCU Unordered Summation}
 \label{lst:analysis:QRCU Unordered Summation}
 \end{listing}
 
+\begin{lineref}[ln:formal:promela:qrcu:sum_unordered]
 The C-preprocessor macro shown in
 Listing~\ref{lst:analysis:QRCU Unordered Summation}
 sums the pair of counters so as to emulate weak memory ordering.
-Lines~2-13 fetch one of the counters, and line~14 fetches the other
+Lines~\lnref{fetch:b}-\lnref{fetch:e} fetch one of the counters,
+and line~\lnref{sum_other} fetches the other
 of the pair and sums them.
-The atomic block consists of a single do-od statement.
-This do-od statement (spanning lines~3-12) is unusual in that
+The atomic block consists of a single \co{do-od} statement.
+This \co{do-od} statement (spanning lines~\lnref{do}-\lnref{od}) is unusual in that
 it contains two unconditional
-branches with guards on lines~4 and~8, which causes Promela to
+branches with guards on lines~\lnref{g1} and~\lnref{g2}, which causes Promela to
 non-deterministically choose one of the two (but again, the full
 state-space search causes Promela to eventually make all possible
 choices in each applicable situation).
 The first branch fetches the zero-th counter and sets \co{i} to 1 (so
-that line~14 will fetch the first counter), while the second
+that line~\lnref{sum_other} will fetch the first counter), while the second
 branch does the opposite, fetching the first counter and setting \co{i}
-to 0 (so that line~14 will fetch the second counter).
+to 0 (so that line~\lnref{sum_other} will fetch the second counter).
+\end{lineref}
 
 \QuickQuiz{}
-	Is there a more straightforward way to code the do-od statement?
+	Is there a more straightforward way to code the \co{do-od} statement?
 \QuickQuizAnswer{
 	Yes.
-	Replace it with {\tt if-fi} and remove the two {\tt break} statements.
+	Replace it with \co{if-fi} and remove the two \co{break} statements.
 } \QuickQuizEnd
 
 \begin{listing}[htbp]
-{ \scriptsize
-\begin{verbbox}
-  1 proctype qrcu_updater(byte me)
-  2 {
-  3   int i;
-  4   byte readerstart[N_QRCU_READERS];
-  5   int sum;
-  6
-  7   do
-  8   :: 1 ->
-  9
- 10     /* Snapshot reader state. */
- 11
- 12     atomic {
- 13       i = 0;
- 14       do
- 15       :: i < N_QRCU_READERS ->
- 16         readerstart[i] = readerprogress[i];
- 17         i++
- 18       :: i >= N_QRCU_READERS ->
- 19         break
- 20       od
- 21     }
- 22
- 23     sum_unordered;
- 24     if
- 25     :: sum <= 1 -> sum_unordered
- 26     :: else -> skip
- 27     fi;
- 28     if
- 29     :: sum > 1 ->
- 30       spin_lock(mutex);
- 31       atomic { ctr[!idx]++ }
- 32       idx = !idx;
- 33       atomic { ctr[!idx]-- }
- 34       do
- 35       :: ctr[!idx] > 0 -> skip
- 36       :: ctr[!idx] == 0 -> break
- 37       od;
- 38       spin_unlock(mutex);
- 39     :: else -> skip
- 40     fi;
- 41
- 42     /* Verify reader progress. */
- 43
- 44     atomic {
- 45       i = 0;
- 46       sum = 0;
- 47       do
- 48       :: i < N_QRCU_READERS ->
- 49         sum = sum + (readerstart[i] == 1 &&
- 50                readerprogress[i] == 1);
- 51         i++
- 52       :: i >= N_QRCU_READERS ->
- 53         assert(sum == 0);
- 54         break
- 55       od
- 56     }
- 57   od
- 58 }
-\end{verbbox}
-}
-\centering
-\theverbbox
+\input{CodeSamples/formal/promela/qrcu@xxxxxxxxxxx}
 \caption{QRCU Updater Process}
 \label{lst:analysis:QRCU Updater Process}
 \end{listing}
 
+\begin{lineref}[ln:formal:promela:qrcu:updater]
 With the \co{sum_unordered} macro in place, we can now proceed
 to the update-side process shown in
 Listing~\ref{lst:analysis:QRCU Updater Process}.
 The update-side process repeats indefinitely, with the corresponding
-do-od loop ranging over lines~7-57.
-Each pass through the loop first snapshots the global {\tt readerprogress}
-array into the local {\tt readerstart} array on lines~12-21.
-This snapshot will be used for the assertion on line~53.
-Line~23 invokes \co{sum_unordered}, and then lines~24-27
+\co{do-od} loop ranging over lines~\lnref{do}-\lnref{od}.
+Each pass through the loop first snapshots the global \co{readerprogress}
+array into the local \co{readerstart} array on
+lines~\lnref{atm1:b}-\lnref{atm1:e}.
+This snapshot will be used for the assertion on line~\lnref{assert}.
+Line~\lnref{sum_unord} invokes \co{sum_unordered}, and then
+lines~\lnref{reinvoke:b}-\lnref{reinvoke:e}
 re-invoke \co{sum_unordered} if the fastpath is potentially
 usable.
 
-Lines~28-40 execute the slowpath code if need be, with
-lines~30 and~38 acquiring and releasing the update-side lock,
-lines~31-33 flipping the index, and lines~34-37 waiting for
+Lines~\lnref{slow:b}-\lnref{slow:e} execute the slowpath code if need be, with
+lines~\lnref{acq} and~\lnref{rel} acquiring and releasing the update-side lock,
+lines~\lnref{flip_idx:b}-\lnref{flip_idx:e} flipping the index, and
+lines~\lnref{wait:b}-\lnref{wait:e} waiting for
 all pre-existing readers to complete.
 
-Lines~44-56 then compare the current values in the {\tt readerprogress}
-array to those collected in the {\tt readerstart} array,
+Lines~\lnref{atm2:b}-\lnref{atm2:e} then compare the current values
+in the \co{readerprogress}
+array to those collected in the \co{readerstart} array,
 forcing an assertion failure should any readers that started before
 this update still be in progress.
+\end{lineref}
 
 \QuickQuiz{}
-	Why are there atomic blocks at lines~12-21
-	and lines~44-56, when the operations within those atomic
+	\begin{lineref}[ln:formal:promela:qrcu:updater]
+	Why are there atomic blocks at lines~\lnref{atm1:b}-\lnref{atm1:e}
+	and lines~\lnref{atm2:b}-\lnref{atm2:e}, when the operations
+	within those atomic
 	blocks have no atomic implementation on any current
 	production microprocessor?
+	\end{lineref}
 \QuickQuizAnswer{
 	Because those operations are for the benefit of the
 	assertion only.  They are not part of the algorithm itself.
@@ -1134,8 +875,11 @@ this update still be in progress.
 } \QuickQuizEnd
 
 \QuickQuiz{}
-	Is the re-summing of the counters on lines~24-27
+	\begin{lineref}[ln:formal:promela:qrcu:updater]
+	Is the re-summing of the counters on
+        lines~\lnref{reinvoke:b}-\lnref{reinvoke:e}
 	\emph{really} necessary?
+        \end{lineref}
 \QuickQuizAnswer{
 	Yes.  To see this, delete these lines and run the model.
 
@@ -1143,17 +887,17 @@ this update still be in progress.
 
 	\begin{enumerate}
 	\item	One process is within its RCU read-side critical
-		section, so that the value of {\tt ctr[0]} is zero and
-		the value of {\tt ctr[1]} is two.
+		section, so that the value of \co{ctr[0]} is zero and
+		the value of \co{ctr[1]} is two.
 	\item	An updater starts executing, and sees that the sum of
 		the counters is two so that the fastpath cannot be
 		executed.  It therefore acquires the lock.
 	\item	A second updater starts executing, and fetches the value
-		of {\tt ctr[0]}, which is zero.
-	\item	The first updater adds one to {\tt ctr[0]}, flips
+		of \co{ctr[0]}, which is zero.
+	\item	The first updater adds one to \co{ctr[0]}, flips
 		the index (which now becomes zero), then subtracts
-		one from {\tt ctr[1]} (which now becomes one).
-	\item	The second updater fetches the value of {\tt ctr[1]},
+		one from \co{ctr[1]} (which now becomes one).
+	\item	The second updater fetches the value of \co{ctr[1]},
 		which is now one.
 	\item	The second updater now incorrectly concludes that it
 		is safe to proceed on the fastpath, despite the fact
@@ -1162,45 +906,21 @@ this update still be in progress.
 } \QuickQuizEnd
 
 \begin{listing}[htbp]
-{ \scriptsize
-\begin{verbbox}
-  1 init {
-  2   int i;
-  3
-  4   atomic {
-  5     ctr[idx] = 1;
-  6     ctr[!idx] = 0;
-  7     i = 0;
-  8     do
-  9     :: i < N_QRCU_READERS ->
- 10       readerprogress[i] = 0;
- 11       run qrcu_reader(i);
- 12       i++
- 13     :: i >= N_QRCU_READERS -> break
- 14     od;
- 15     i = 0;
- 16     do
- 17     :: i < N_QRCU_UPDATERS ->
- 18       run qrcu_updater(i);
- 19       i++
- 20     :: i >= N_QRCU_UPDATERS -> break
- 21     od
- 22   }
- 23 }
-\end{verbbox}
-}
-\centering
-\theverbbox
+\input{CodeSamples/formal/promela/qrcu@xxxxxxxx}
 \caption{QRCU Initialization Process}
 \label{lst:analysis:QRCU Initialization Process}
 \end{listing}
 
+\begin{lineref}[ln:formal:promela:qrcu:init]
 All that remains is the initialization block shown in
 Listing~\ref{lst:analysis:QRCU Initialization Process}.
-This block simply initializes the counter pair on lines~5-6,
-spawns the reader processes on lines~7-14, and spawns the updater
-processes on lines~15-21.
+This block simply initializes the counter pair on
+lines~\lnref{i_ctr:b}-\lnref{i_ctr:e},
+spawns the reader processes on
+lines~\lnref{spn_r:b}-\lnref{spn_r:e}, and spawns the updater
+processes on lines~\lnref{spn_u:b}-\lnref{spn_u:e}.
 This is all done within an atomic block to reduce state space.
+\end{lineref}
 
 \subsubsection{Running the QRCU Example}
 \label{sec:formal:Running the QRCU Example}
@@ -1211,16 +931,11 @@ for \co{spin_lock()} and \co{spin_unlock()} into a file named
 \path{lock.h}.
 Then use the following commands to build and run the QRCU model:
 
-\vspace{5pt}
-\begin{minipage}[t]{\columnwidth}
-\scriptsize
-\begin{verbatim}
+\begin{VerbatimU}
 spin -a qrcu.spin
 cc -DSAFETY -o pan pan.c
 ./pan
-\end{verbatim}
-\end{minipage}
-\vspace{5pt}
+\end{VerbatimU}
 
 \begin{table}
 \rowcolors{1}{}{lightgray}
-- 
2.7.4





[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux