[PATCH -perfbook 4/5] together/applyrcu: Use \clnref{} and its friends in Section 13.5.10

Akira Yokosawa <[email protected]> Tue, 7 Oct 2025 23:57:23 +0900
Newsgroups org.kernel.vger.perfbook
Message-ID <[email protected]>
Signed-off-by: Akira Yokosawa <[email protected]>
---
 .../formal/herd/C-double-check-rcu-2.litmus   | 32 +++++++++----------
 together/applyrcu.tex                         | 32 +++++++++++--------
 2 files changed, 34 insertions(+), 30 deletions(-)

diff --git a/CodeSamples/formal/herd/C-double-check-rcu-2.litmus b/CodeSamples/formal/herd/C-double-check-rcu-2.litmus
index e23bc081..ff7a1dd3 100644
--- a/CodeSamples/formal/herd/C-double-check-rcu-2.litmus
+++ b/CodeSamples/formal/herd/C-double-check-rcu-2.litmus
@@ -12,24 +12,24 @@ P0(int *a, int *b, int **p)
 	int *r1;
 	int r2;
 
-	rcu_read_lock();
-	r1 = rcu_dereference(*p);
-	if (r1) {
-		r2 = *r1;
-		rcu_read_unlock();
+	rcu_read_lock();		//\lnlbl[P0:lock]
+	r1 = rcu_dereference(*p);	//\lnlbl[P0:load]
+	if (r1) {			//\lnlbl[P0:if]
+		r2 = *r1;		//\lnlbl[P0:deref]
+		rcu_read_unlock();	//\lnlbl[P0:unl:1]
 	} else {
-		rcu_read_unlock();
-		*a = 1;
-		r1 = xchg(p, a);
-		if (r1) {
-			synchronize_rcu();
-			*r1 = 0; // Emulate kfree();
+		rcu_read_unlock();	//\lnlbl[P0:unl:2]
+		*a = 1;			//\lnlbl[P0:init:a]
+		r1 = xchg(p, a);	//\lnlbl[P0:xchg]
+		if (r1) {				//\lnlbl[P0:if:2]
+			synchronize_rcu();		//\lnlbl[P0:sync]
+			*r1 = 0; // Emulate kfree();	//\lnlbl[P0:free]
 		}
 		r2 = 1;
 	}
 }
 
-P1(int *a, int *b, int **p)
+P1(int *a, int *b, int **p)		//\lnlbl[P1:b]
 {
 	int *r1;
 	int r2;
@@ -49,11 +49,11 @@ P1(int *a, int *b, int **p)
 		}
 		r2 = 1;
 	}
-}
+}					//\lnlbl[P1:e]
 
 //\end[snippet]
-locations [0:r1; 1:r1; a; b; p]
+locations [0:r1; 1:r1; a; b; p]		(* \lnlbl[loc] *)
 (* Reader better not see freed element!!! *)
-exists (0:r2=0 \/ 1:r2=0 \/
+exists (0:r2=0 \/ 1:r2=0 \/		(* \lnlbl[ex:1] *)
 	(* Better only be one in use! *)
-	(a=1 /\ b=1) \/ (a=0 /\ b=0))
+	(a=1 /\ b=1) \/ (a=0 /\ b=0))	(* \lnlbl[ex:2] *)
diff --git a/together/applyrcu.tex b/together/applyrcu.tex
index ff462a3b..455bf2a1 100644
--- a/together/applyrcu.tex
+++ b/together/applyrcu.tex
@@ -957,31 +957,35 @@ avoid disrupting concurrent readers, for example, as shown in
 
 The fastpath covers the common case where initialization has already
 completed.
-Line~14 begins an RCU read-side critical section, and line~15 fetches
+\begin{fcvref}[ln:formal:C-double-check-rcu-2:whole:P0]
+\Clnref{lock} begins an RCU read-side critical section, and \clnref{load} fetches
 the current pointer.
-If line~16 determines that this pointer is non-\co{NULL}, then
-initialization is complete, so that line~17 fetches the element's contents
-and line~18 exits the critical section.
+If \clnref{if} determines that this pointer is non-\co{NULL}, then
+initialization is complete, so that \clnref{deref} fetches the element's contents
+and \clnref{unl:1} exits the critical section.
 
-Otherwise, line~16 will see the pre-initialization \co{NULL} pointer
-and transfer control to line~20, which exits the RCU read-side critical
+Otherwise, \clnref{if} will see the pre-initialization \co{NULL} pointer
+and transfer control to \clnref{unl:2}, which exits the RCU read-side critical
 section.
-Line~21 initializes the element (abstracting away any required allocation),
-line~22 atomically exchanges the pointer to this element with the global
+\Clnref{init:a} initializes the element (abstracting away any required allocation),
+\clnref{xchg} atomically exchanges the pointer to this element with the global
 pointer \co{p}, returning the old value in \co{r1}.
-If line~23 determines that \co{r1} was non-\co{NULL}, then line~24
-waits for any readers accessing the old element to finish and line~25
+If \clnref{if:2} determines that \co{r1} was non-\co{NULL}, then \clnref{sync}
+waits for any readers accessing the old element to finish and \clnref{free}
 emulates a \co{kfree()}.
 Either way, \co{r2} is set to the initial value of 1.
+\end{fcvref}
 
-Lines~31-51 operate in the same manner, but using element \co{b} instead
+\begin{fcvref}[ln:formal:C-double-check-rcu-2:whole]
+\Clnrefrange{P1:b}{P1:e} operate in the same manner, but using element \co{b} instead
 of \co{a}.
 
-Line~53 displays all variables to ease debugging of the litmus test.
-Line~55 verifies that both processes obtain an initialized value,
-and line~57 verifies that there are no memory leaks and that at least
+\Clnref{loc} displays all variables to ease debugging of the litmus test.
+\Clnref{ex:1} verifies that both processes obtain an initialized value,
+and \clnref{ex:2} verifies that there are no memory leaks and that at least
 one element remains in use.
 Running \co{herd} confirms that this code satisfies these constraints.
+\end{fcvref}
 
 \QuickQuiz{
 	But wouldn't memory allocation also be forbidden in such
-- 
2.43.0