All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/7] count, toolsoftrade: Employ new code-snippet scheme (cont.)
@ 2018-10-26 15:22 Akira Yokosawa
  2018-10-26 15:24 ` [PATCH 1/7] count: Employ new scheme for inline code snippets Akira Yokosawa
                   ` (7 more replies)
  0 siblings, 8 replies; 10+ messages in thread
From: Akira Yokosawa @ 2018-10-26 15:22 UTC (permalink / raw)
  To: Paul E. McKenney; +Cc: perfbook, Akira Yokosawa

Hi Paul,

This is a set of simple conversions of code snippets to the new scheme
in count and toolsoftrade.  There is no change in the code under CodeSamples,
but there are a few visual changes in the pdf output which reflect the
actual code samples.

Patch #7 fixes an unintended change in indent width made in the previous
patch set.

        Thanks, Akira
--
Akira Yokosawa (7):
  count: Employ new scheme for inline code snippets
  toolsoftrade: Use 'VerbatimU' for inline snippets
  toolsoftrade: Employ new scheme for snippets of lock.c
  toolsoftrade: Employ new scheme for snippet of rwlockscale.c
  toolsoftrade: Employ new scheme for snippet of compiler barriers
  toolsoftrade: Employ new scheme for snippets of threadcreate.c
  count: Fix indent in count_lim_atomic.c

 CodeSamples/api-pthreads/api-pthreads.h |   7 +-
 CodeSamples/count/count_lim_atomic.c    |   2 +-
 CodeSamples/intro/threadcreate.c        |  20 +-
 CodeSamples/toolsoftrade/lock.c         |  76 +++---
 CodeSamples/toolsoftrade/rwlockscale.c  |  54 ++--
 count/count.tex                         |  89 +++---
 toolsoftrade/toolsoftrade.tex           | 460 ++++++++------------------------
 7 files changed, 253 insertions(+), 455 deletions(-)

-- 
2.7.4


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/7] count: Employ new scheme for inline code snippets
  2018-10-26 15:22 [PATCH 0/7] count, toolsoftrade: Employ new code-snippet scheme (cont.) Akira Yokosawa
@ 2018-10-26 15:24 ` Akira Yokosawa
  2018-10-26 15:24 ` [PATCH 2/7] toolsoftrade: Use 'VerbatimU' for inline snippets Akira Yokosawa
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Akira Yokosawa @ 2018-10-26 15:24 UTC (permalink / raw)
  To: Paul E. McKenney; +Cc: perfbook, Akira Yokosawa

From c8ed9b923cfdc68403998cd154f07f7834ad4edb Mon Sep 17 00:00:00 2001
From: Akira Yokosawa <akiyks@gmail.com>
Date: Sun, 14 Oct 2018 10:50:24 +0900
Subject: [PATCH 1/7] count: Employ new scheme for inline code snippets

Signed-off-by: Akira Yokosawa <akiyks@gmail.com>
---
 count/count.tex | 89 +++++++++++++++++++++++++++++----------------------------
 1 file changed, 46 insertions(+), 43 deletions(-)

diff --git a/count/count.tex b/count/count.tex
index 4d13394..0f35042 100644
--- a/count/count.tex
+++ b/count/count.tex
@@ -2679,30 +2679,33 @@ when updating the counter, and to write-acquire that same reader-writer
 lock when checking the counter.
 Code for doing I/O might be as follows:
 
-\vspace{5pt}
-\begin{minipage}[t]{\columnwidth}
-\small
-\begin{verbatim}
-  1 read_lock(&mylock);
-  2 if (removing) {
-  3   read_unlock(&mylock);
-  4   cancel_io();
-  5 } else {
-  6   add_count(1);
-  7   read_unlock(&mylock);
-  8   do_io();
-  9   sub_count(1);
- 10 }
-\end{verbatim}
-\end{minipage}
-\vspace{5pt}
-
-Line~1 read-acquires the lock, and either line~3 or~7 releases it.
-Line~2 checks to see if the device is being removed, and, if so,
-line~3 releases the lock and line~4 cancels the I/O, or takes whatever
+\begin{linelabel}[ln:count:inline:I/O]
+\begin{VerbatimN}[commandchars=\\\[\]]
+read_lock(&mylock);		\lnlbl[acq]
+if (removing) {			\lnlbl[check]
+	read_unlock(&mylock);	\lnlbl[rel1]
+	cancel_io();		\lnlbl[cancel]
+} else {
+	add_count(1);		\lnlbl[inc]
+	read_unlock(&mylock);	\lnlbl[rel2]
+	do_io();		\lnlbl[do]
+	sub_count(1);		\lnlbl[dec]
+}
+\end{VerbatimN}
+\end{linelabel}
+
+\begin{lineref}[ln:count:inline:I/O]
+Line~\lnref{acq} read-acquires the lock, and either
+line~\lnref{rel1} or~\lnref{rel2} releases it.
+Line~\lnref{check} checks to see if the device is being removed, and, if so,
+line~\lnref{rel1} releases the lock and
+line~\lnref{cancel} cancels the I/O, or takes whatever
 action is appropriate given that the device is to be removed.
-Otherwise, line~6 increments the access count, line~7 releases the
-lock, line~8 performs the I/O, and line~9 decrements the access count.
+Otherwise, line~\lnref{inc} increments the access count,
+line~\lnref{rel2} releases the
+lock, line~\lnref{do} performs the I/O, and
+line~\lnref{dec} decrements the access count.
+\end{lineref}
 
 \QuickQuiz{}
 	This is ridiculous!
@@ -2717,27 +2720,27 @@ lock, line~8 performs the I/O, and line~9 decrements the access count.
 
 The code to remove the device might be as follows:
 
-\vspace{5pt}
-\begin{minipage}[t]{\columnwidth}
-\small
-\begin{verbatim}
-  1 write_lock(&mylock);
-  2 removing = 1;
-  3 sub_count(mybias);
-  4 write_unlock(&mylock);
-  5 while (read_count() != 0) {
-  6   poll(NULL, 0, 1);
-  7 }
-  8 remove_device();
-\end{verbatim}
-\end{minipage}
-\vspace{5pt}
-
-Line~1 write-acquires the lock and line~4 releases it.
-Line~2 notes that the device is being removed, and the loop spanning
-lines~5-7 wait for any I/O operations to complete.
-Finally, line~8 does any additional processing needed to prepare for
+\begin{linelabel}[ln:count:inline:remove]
+\begin{VerbatimN}[commandchars=\\\[\]]
+write_lock(&mylock);		\lnlbl[acq]
+removing = 1;			\lnlbl[note]
+sub_count(mybias);
+write_unlock(&mylock);		\lnlbl[rel]
+while (read_count() != 0) {	\lnlbl[loop:b]
+	poll(NULL, 0, 1);
+}				\lnlbl[loop:e]
+remove_device();		\lnlbl[remove]
+\end{VerbatimN}
+\end{linelabel}
+
+\begin{lineref}[ln:count:inline:remove]
+Line~\lnref{acq} write-acquires the lock and
+line~\lnref{rel} releases it.
+Line~\lnref{note} notes that the device is being removed, and the loop spanning
+lines~\lnref{loop:b}-\lnref{loop:e} wait for any I/O operations to complete.
+Finally, line~\lnref{remove} does any additional processing needed to prepare for
 device removal.
+\end{lineref}
 
 \QuickQuiz{}
 	What other issues would need to be accounted for in a real system?
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/7] toolsoftrade: Use 'VerbatimU' for inline snippets
  2018-10-26 15:22 [PATCH 0/7] count, toolsoftrade: Employ new code-snippet scheme (cont.) Akira Yokosawa
  2018-10-26 15:24 ` [PATCH 1/7] count: Employ new scheme for inline code snippets Akira Yokosawa
@ 2018-10-26 15:24 ` Akira Yokosawa
  2018-10-26 15:26 ` [PATCH 3/7] toolsoftrade: Employ new scheme for snippets of lock.c Akira Yokosawa
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Akira Yokosawa @ 2018-10-26 15:24 UTC (permalink / raw)
  To: Paul E. McKenney; +Cc: perfbook, Akira Yokosawa

From f65277139c063f4b44987edb0eee40ade1957df2 Mon Sep 17 00:00:00 2001
From: Akira Yokosawa <akiyks@gmail.com>
Date: Sun, 14 Oct 2018 14:54:14 +0900
Subject: [PATCH 2/7] toolsoftrade: Use 'VerbatimU' for inline snippets

Signed-off-by: Akira Yokosawa <akiyks@gmail.com>
---
 toolsoftrade/toolsoftrade.tex | 90 ++++++++++---------------------------------
 1 file changed, 20 insertions(+), 70 deletions(-)

diff --git a/toolsoftrade/toolsoftrade.tex b/toolsoftrade/toolsoftrade.tex
index 6896997..601829c 100644
--- a/toolsoftrade/toolsoftrade.tex
+++ b/toolsoftrade/toolsoftrade.tex
@@ -88,14 +88,9 @@ of \co{cat} execute sequentially.
 \QuickQuizAnswer{
 	One straightforward approach is the shell pipeline:
 
-\begin{minipage}[t]{\columnwidth}
-\vspace{0.1ex}
-\small
-\begin{verbatim}
+\begin{VerbatimU}
 grep $pattern1 | sed -e 's/a/b/' | sort
-\end{verbatim}
-\vspace{0.1ex}
-\end{minipage}
+\end{VerbatimU}
 
 	For a sufficiently large input file,
 	\co{grep} will pattern-match in parallel with \co{sed}
@@ -648,15 +643,10 @@ Lines~7-11 create a thread running \co{lock_writer()}.
 Lines~12-19 wait for both threads to complete.
 The output of this code fragment is as follows:
 
-\vspace{5pt}
-\begin{minipage}[t]{\columnwidth}
-\scriptsize
-\begin{verbatim}
+\begin{VerbatimU}
 Creating two threads using same lock:
 lock_reader(): x = 0
-\end{verbatim}
-\end{minipage}
-\vspace{5pt}
+\end{VerbatimU}
 
 Because both threads are using the same lock, the \co{lock_reader()}
 thread cannot see any of the intermediate values of \co{x} produced
@@ -718,18 +708,13 @@ shows a similar code fragment, but this time using different locks:
 \co{lock_writer()}.
 The output of this code fragment is as follows:
 
-\vspace{5pt}
-\begin{minipage}[t]{\columnwidth}
-\scriptsize
-\begin{verbatim}
+\begin{VerbatimU}
 Creating two threads w/different locks:
 lock_reader(): x = 0
 lock_reader(): x = 1
 lock_reader(): x = 2
 lock_reader(): x = 3
-\end{verbatim}
-\end{minipage}
-\vspace{5pt}
+\end{VerbatimU}
 
 Because the two threads are using different locks, they do not exclude
 each other, and can run concurrently.
@@ -1144,16 +1129,11 @@ If you instead need the new value, you can instead use the
 	For example, one could implement \co{__sync_nand_and_fetch()}
 	in terms of \co{__sync_fetch_and_nand()} as follows:
 
-\vspace{5pt}
-\begin{minipage}[t]{\columnwidth}
-\scriptsize
-\begin{verbatim}
+\begin{VerbatimU}
 tmp = v;
 ret = __sync_fetch_and_nand(p, tmp);
 ret = ~ret & tmp;
-\end{verbatim}
-\end{minipage}
-\vspace{5pt}
+\end{VerbatimU}
 
 	It is similarly possible to implement \co{__sync_fetch_and_add()},
 	\co{__sync_fetch_and_sub()}, and \co{__sync_fetch_and_xor()}
@@ -1615,16 +1595,11 @@ allowing other threads to acquire it.
 A spinlock named \co{mutex} may be used to protect a variable
 \co{counter} as follows:
 
-\vspace{5pt}
-\begin{minipage}[t]{\columnwidth}
-\small
-\begin{verbatim}
+\begin{VerbatimU}
 spin_lock(&mutex);
 counter++;
 spin_unlock(&mutex);
-\end{verbatim}
-\end{minipage}
-\vspace{5pt}
+\end{VerbatimU}
 
 \QuickQuiz{}
 	What problems could occur if the variable {\tt counter} were
@@ -1633,16 +1608,11 @@ spin_unlock(&mutex);
 	On CPUs with load-store architectures, incrementing {\tt counter}
 	might compile into something like the following:
 
-\vspace{5pt}
-\begin{minipage}[t]{\columnwidth}
-\small
-\begin{verbatim}
+\begin{VerbatimU}
 LOAD counter,r0
 INC r0
 STORE r0,counter
-\end{verbatim}
-\end{minipage}
-\vspace{5pt}
+\end{VerbatimU}
 
 	On such machines, two threads might simultaneously load the
 	value of {\tt counter}, each increment it, and each store the
@@ -2505,51 +2475,31 @@ Section~\ref{sec:count:Statistical Counters},
 it is helpful to implement such a counter using a per-thread variable.
 Such a variable can be defined as follows:
 
-\vspace{5pt}
-\begin{minipage}[t]{\columnwidth}
-\small
-\begin{verbatim}
+\begin{VerbatimU}
 DEFINE_PER_THREAD(int, counter);
-\end{verbatim}
-\end{minipage}
-\vspace{5pt}
+\end{VerbatimU}
 
 The counter must be initialized as follows:
 
-\vspace{5pt}
-\begin{minipage}[t]{\columnwidth}
-\small
-\begin{verbatim}
+\begin{VerbatimU}
 init_per_thread(counter, 0);
-\end{verbatim}
-\end{minipage}
-\vspace{5pt}
+\end{VerbatimU}
 
 A thread can increment its instance of this counter as follows:
 
-\vspace{5pt}
-\begin{minipage}[t]{\columnwidth}
-\small
-\begin{verbatim}
+\begin{VerbatimU}
 p_counter = &__get_thread_var(counter);
 WRITE_ONCE(*p_counter, *p_counter + 1);
-\end{verbatim}
-\end{minipage}
-\vspace{5pt}
+\end{VerbatimU}
 
 The value of the counter is then the sum of its instances.
 A snapshot of the value of the counter can thus be collected
 as follows:
 
-\vspace{5pt}
-\begin{minipage}[t]{\columnwidth}
-\small
-\begin{verbatim}
+\begin{VerbatimU}
 for_each_thread(t)
   sum += READ_ONCE(per_thread(counter, t));
-\end{verbatim}
-\end{minipage}
-\vspace{5pt}
+\end{VerbatimU}
 
 Again, it is possible to gain a similar effect using other mechanisms,
 but per-thread variables combine convenience and high performance,
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/7] toolsoftrade: Employ new scheme for snippets of lock.c
  2018-10-26 15:22 [PATCH 0/7] count, toolsoftrade: Employ new code-snippet scheme (cont.) Akira Yokosawa
  2018-10-26 15:24 ` [PATCH 1/7] count: Employ new scheme for inline code snippets Akira Yokosawa
  2018-10-26 15:24 ` [PATCH 2/7] toolsoftrade: Use 'VerbatimU' for inline snippets Akira Yokosawa
@ 2018-10-26 15:26 ` Akira Yokosawa
  2018-10-26 15:27 ` [PATCH 4/7] toolsoftrade: Employ new scheme for snippet of rwlockscale.c Akira Yokosawa
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Akira Yokosawa @ 2018-10-26 15:26 UTC (permalink / raw)
  To: Paul E. McKenney; +Cc: perfbook, Akira Yokosawa

From 4bf3961a5c8501a9983a196119038b74cff7a18d Mon Sep 17 00:00:00 2001
From: Akira Yokosawa <akiyks@gmail.com>
Date: Sun, 14 Oct 2018 16:23:34 +0900
Subject: [PATCH 3/7] toolsoftrade: Employ new scheme for snippets of lock.c

NOTE: Several "if" statements, which are too wide for 2c layout,
are divided into a statement to get error code and a simple "if"
statement.

Signed-off-by: Akira Yokosawa <akiyks@gmail.com>
---
 CodeSamples/toolsoftrade/lock.c |  76 +++++++++--------
 toolsoftrade/toolsoftrade.tex   | 175 +++++++++++-----------------------------
 2 files changed, 89 insertions(+), 162 deletions(-)

diff --git a/CodeSamples/toolsoftrade/lock.c b/CodeSamples/toolsoftrade/lock.c
index 6bb3c23..7b56c0f 100644
--- a/CodeSamples/toolsoftrade/lock.c
+++ b/CodeSamples/toolsoftrade/lock.c
@@ -26,62 +26,64 @@
 #include <errno.h>
 #include "../api.h"
 
-pthread_mutex_t lock_a = PTHREAD_MUTEX_INITIALIZER;
-pthread_mutex_t lock_b = PTHREAD_MUTEX_INITIALIZER;
+//\begin{snippet}[labelbase=ln:toolsoftrade:lock:reader_writer,commandchars=\$\[\]]
+pthread_mutex_t lock_a = PTHREAD_MUTEX_INITIALIZER;	//\lnlbl{lock_a}
+pthread_mutex_t lock_b = PTHREAD_MUTEX_INITIALIZER;	//\lnlbl{lock_b}
 
-int x = 0;
+int x = 0;						//\lnlbl{x}
 
-void *lock_reader(void *arg)
+void *lock_reader(void *arg)				//\lnlbl{reader:b}
 {
 	int en;
 	int i;
 	int newx = -1;
 	int oldx = -1;
-	pthread_mutex_t *pmlp = (pthread_mutex_t *)arg;
+	pthread_mutex_t *pmlp = (pthread_mutex_t *)arg;	//\lnlbl{reader:cast}
 
-	if ((en = pthread_mutex_lock(pmlp)) != 0) {
+	if ((en = pthread_mutex_lock(pmlp)) != 0) {	//\lnlbl{reader:acq:b}
 		fprintf(stderr, "lock_reader:pthread_mutex_lock: %s\n",
 			strerror(en));
 		exit(EXIT_FAILURE);
-	}
-	for (i = 0; i < 100; i++) {
-		newx = READ_ONCE(x);
+	}						//\lnlbl{reader:acq:e}
+	for (i = 0; i < 100; i++) {			//\lnlbl{reader:loop:b}
+		newx = READ_ONCE(x);			//\lnlbl{reader:read_x}
 		if (newx != oldx) {
 			printf("lock_reader(): x = %d\n", newx);
 		}
 		oldx = newx;
-		poll(NULL, 0, 1);
-	}
-	if ((en = pthread_mutex_unlock(pmlp)) != 0) {
+		poll(NULL, 0, 1);			//\lnlbl{reader:sleep}
+	}						//\lnlbl{reader:loop:e}
+	if ((en = pthread_mutex_unlock(pmlp)) != 0) {	//\lnlbl{reader:rel:b}
 		fprintf(stderr, "lock_reader:pthread_mutex_lock: %s\n",
 			strerror(en));
 		exit(EXIT_FAILURE);
-	}
-	return NULL;
-}
+	}						//\lnlbl{reader:rel:e}
+	return NULL;					//\lnlbl{reader:return}
+}							//\lnlbl{reader:e}
 
-void *lock_writer(void *arg)
+void *lock_writer(void *arg)				//\lnlbl{writer:b}
 {
 	int en;
 	int i;
-	pthread_mutex_t *pmlp = (pthread_mutex_t *)arg;
+	pthread_mutex_t *pmlp = (pthread_mutex_t *)arg;	//\lnlbl{writer:cast}
 
-	if ((en = pthread_mutex_lock(pmlp)) != 0) {
+	if ((en = pthread_mutex_lock(pmlp)) != 0) {	//\lnlbl{writer:acq:b}
 		fprintf(stderr, "lock_writer:pthread_mutex_lock: %s\n",
 			strerror(en));
 		exit(EXIT_FAILURE);
-	}
-	for (i = 0; i < 3; i++) {
-		WRITE_ONCE(x, READ_ONCE(x) + 1);
+	}						//\lnlbl{writer:acq:e}
+	for (i = 0; i < 3; i++) {			//\lnlbl{writer:loop:b}
+		WRITE_ONCE(x, READ_ONCE(x) + 1);	//\lnlbl{writer:inc}
 		poll(NULL, 0, 5);
-	}
-	if ((en = pthread_mutex_unlock(pmlp)) != 0) {
+	}						//\lnlbl{writer:loop:e}
+	if ((en = pthread_mutex_unlock(pmlp)) != 0) {	//\lnlbl{writer:rel:b}
 		fprintf(stderr, "lock_writer:pthread_mutex_lock: %s\n",
 			strerror(en));
 		exit(EXIT_FAILURE);
-	}
+	}						//\lnlbl{writer:rel:e}
 	return NULL;
-}
+}							//\lnlbl{writer:e}
+//\end{snippet}
 
 int main(int argc, char *argv[])
 {
@@ -90,31 +92,38 @@ int main(int argc, char *argv[])
 	pthread_t tid2;
 	void *vp;
 
+//\begin{snippet}[labelbase=ln:toolsoftrade:lock:same_lock,commandchars=\$\[\]]
 	printf("Creating two threads using same lock:\n");
-	if ((en = pthread_create(&tid1, NULL, lock_reader, &lock_a)) != 0) {
+	en = pthread_create(&tid1, NULL, lock_reader, &lock_a);	//\lnlbl{cr:reader:b}
+	if (en != 0) {
 		fprintf(stderr, "pthread_create: %s\n", strerror(en));
 		exit(EXIT_FAILURE);
-	}
-	if ((en = pthread_create(&tid2, NULL, lock_writer, &lock_a)) != 0) {
+	}							//\lnlbl{cr:reader:e}
+	en = pthread_create(&tid2, NULL, lock_writer, &lock_a); //\lnlbl{cr:writer:b}
+	if (en != 0) {
 		fprintf(stderr, "pthread_create: %s\n", strerror(en));
 		exit(EXIT_FAILURE);
-	}
-	if ((en = pthread_join(tid1, &vp)) != 0) {
+	}							//\lnlbl{cr:writer:e}
+	if ((en = pthread_join(tid1, &vp)) != 0) {	//\lnlbl{wait:b}
 		fprintf(stderr, "pthread_join: %s\n", strerror(en));
 		exit(EXIT_FAILURE);
 	}
 	if ((en = pthread_join(tid2, &vp)) != 0) {
 		fprintf(stderr, "pthread_join: %s\n", strerror(en));
 		exit(EXIT_FAILURE);
-	}
+	}						//\lnlbl{wait:e}
+//\end{snippet}
 
+//\begin{snippet}[labelbase=ln:toolsoftrade:lock:diff_lock,commandchars=\$\[\]]
 	printf("Creating two threads w/different locks:\n");
 	x = 0;
-	if ((en = pthread_create(&tid1, NULL, lock_reader, &lock_a)) != 0) {
+	en = pthread_create(&tid1, NULL, lock_reader, &lock_a);
+	if (en != 0) {
 		fprintf(stderr, "pthread_create: %s\n", strerror(en));
 		exit(EXIT_FAILURE);
 	}
-	if ((en = pthread_create(&tid2, NULL, lock_writer, &lock_b)) != 0) {
+	en = pthread_create(&tid2, NULL, lock_writer, &lock_b);
+	if (en != 0) {
 		fprintf(stderr, "pthread_create: %s\n", strerror(en));
 		exit(EXIT_FAILURE);
 	}
@@ -126,6 +135,7 @@ int main(int argc, char *argv[])
 		fprintf(stderr, "pthread_join: %s\n", strerror(en));
 		exit(EXIT_FAILURE);
 	}
+//\end{snippet}
 
 	return EXIT_SUCCESS;
 }
diff --git a/toolsoftrade/toolsoftrade.tex b/toolsoftrade/toolsoftrade.tex
index 601829c..e699b6e 100644
--- a/toolsoftrade/toolsoftrade.tex
+++ b/toolsoftrade/toolsoftrade.tex
@@ -460,82 +460,32 @@ lock~\cite{Hoare74}.
 } \QuickQuizEnd
 
 \begin{listing}[tbp]
-{ \scriptsize
-\begin{verbbox}
-  1 pthread_mutex_t lock_a = PTHREAD_MUTEX_INITIALIZER;
-  2 pthread_mutex_t lock_b = PTHREAD_MUTEX_INITIALIZER;
-  3 int x = 0;
-  4 
-  5 void *lock_reader(void *arg)
-  6 {
-  7   int i;
-  8   int newx = -1;
-  9   int oldx = -1;
- 10   pthread_mutex_t *pmlp = (pthread_mutex_t *)arg;
- 11 
- 12   if (pthread_mutex_lock(pmlp) != 0) {
- 13     perror("lock_reader:pthread_mutex_lock");
- 14     exit(EXIT_FAILURE);
- 15   }
- 16   for (i = 0; i < 100; i++) {
- 17     newx = READ_ONCE(x);
- 18     if (newx != oldx) {
- 19       printf("lock_reader(): x = %d\n", newx);
- 20     }
- 21     oldx = newx;
- 22     poll(NULL, 0, 1);
- 23   }
- 24   if (pthread_mutex_unlock(pmlp) != 0) {
- 25     perror("lock_reader:pthread_mutex_unlock");
- 26     exit(EXIT_FAILURE);
- 27   }
- 28   return NULL;
- 29 }
- 30 
- 31 void *lock_writer(void *arg)
- 32 {
- 33   int i;
- 34   pthread_mutex_t *pmlp = (pthread_mutex_t *)arg;
- 35 
- 36   if (pthread_mutex_lock(pmlp) != 0) {
- 37     perror("lock_writer:pthread_mutex_lock");
- 38     exit(EXIT_FAILURE);
- 39   }
- 40   for (i = 0; i < 3; i++) {
- 41     WRITE_ONCE(x, READ_ONCE(x) + 1);
- 42     poll(NULL, 0, 5);
- 43   }
- 44   if (pthread_mutex_unlock(pmlp) != 0) {
- 45     perror("lock_writer:pthread_mutex_unlock");
- 46     exit(EXIT_FAILURE);
- 47   }
- 48   return NULL;
- 49 }
-\end{verbbox}
-}
-\centering
-\theverbbox
+\input{CodeSamples/toolsoftrade/lock@reader_writer.fcv}
 \caption{Demonstration of Exclusive Locks}
 \label{lst:toolsoftrade:Demonstration of Exclusive Locks}
 \end{listing}
 
+\begin{lineref}[ln:toolsoftrade:lock:reader_writer]
 This exclusive-locking property is demonstrated using the code shown in
 Listing~\ref{lst:toolsoftrade:Demonstration of Exclusive Locks}
 (\path{lock.c}).
-Line~1 defines and initializes a POSIX lock named \co{lock_a}, while
-line~2 similarly defines and initializes a lock named \co{lock_b}.
-Line~3 defines and initializes a shared variable~\co{x}.
+Line~\lnref{lock_a} defines and initializes a POSIX lock named \co{lock_a}, while
+line~\lnref{lock_b} similarly defines and initializes a lock named \co{lock_b}.
+Line~\lnref{x} defines and initializes a shared variable~\co{x}.
+\end{lineref}
 
-Lines~5-28 defines a function \co{lock_reader()} which repeatedly
+\begin{lineref}[ln:toolsoftrade:lock:reader_writer:reader]
+Lines~\lnref{b}-\lnref{e} defines a function \co{lock_reader()} which repeatedly
 reads the shared variable \co{x} while holding
 the lock specified by \co{arg}.
-Line~10 casts \co{arg} to a pointer to a \co{pthread_mutex_t}, as
+Line~\lnref{cast} casts \co{arg} to a pointer to a \co{pthread_mutex_t}, as
 required by the \co{pthread_mutex_lock()} and \co{pthread_mutex_unlock()}
 primitives.
+\end{lineref}
 
 \QuickQuiz{}
 	Why not simply make the argument to \co{lock_reader()}
-	on line~5 of
+	on line~\ref{ln:toolsoftrade:lock:reader_writer:reader:b} of
 	Listing~\ref{lst:toolsoftrade:Demonstration of Exclusive Locks}
 	be a pointer to a \co{pthread_mutex_t}?
 \QuickQuizAnswer{
@@ -547,9 +497,12 @@ primitives.
 } \QuickQuizEnd
 
 \QuickQuiz{}
-	What is the \co{READ_ONCE()} on lines~17 and~41 and the
-	\co{WRITE_ONCE()} on line~41 of
+	\begin{lineref}[ln:toolsoftrade:lock:reader_writer]
+	What is the \co{READ_ONCE()} on
+        lines~\lnref{reader:read_x} and~\lnref{writer:inc} and the
+	\co{WRITE_ONCE()} on line~\lnref{writer:inc} of
 	Listing~\ref{lst:toolsoftrade:Demonstration of Exclusive Locks}?
+	\end{lineref}
 \QuickQuizAnswer{
 	These macros constrain the compiler so as to prevent it from
 	carrying out optimizations that would be problematic for concurrently
@@ -569,16 +522,21 @@ primitives.
 	Chapter~\ref{chp:Advanced Synchronization: Memory Ordering}.
 } \QuickQuizEnd
 
-Lines~12-15 acquire the specified \co{pthread_mutex_t}, checking
+\begin{lineref}[ln:toolsoftrade:lock:reader_writer:reader]
+Lines~\lnref{acq:b}-\lnref{acq:e} acquire the specified
+\co{pthread_mutex_t}, checking
 for errors and exiting the program if any occur.
-Lines~16-23 repeatedly check the value of \co{x}, printing the new value
+Lines~\lnref{loop:b}-\lnref{loop:e} repeatedly check the value of \co{x},
+printing the new value
 each time that it changes.
-Line~22 sleeps for one millisecond, which allows this demonstration
+Line~\lnref{sleep} sleeps for one millisecond, which allows this demonstration
 to run nicely on a uniprocessor machine.
-Lines~24-27 release the \co{pthread_mutex_t}, again checking for
+Lines~\lnref{rel:b}-\lnref{rel:e} release the \co{pthread_mutex_t},
+again checking for
 errors and exiting the program if any occur.
-Finally, line~28 returns \co{NULL}, again to match the function type
+Finally, line~\lnref{return} returns \co{NULL}, again to match the function type
 required by \co{pthread_create()}.
+\end{lineref}
 
 \QuickQuiz{}
 	Writing four lines of code for each acquisition and release
@@ -593,55 +551,39 @@ required by \co{pthread_create()}.
 	\co{spin_lock()} and \co{spin_unlock()} APIs.
 } \QuickQuizEnd
 
-Lines~31-49 of
+\begin{lineref}[ln:toolsoftrade:lock:reader_writer:writer]
+Lines~\lnref{b}-\lnref{e} of
 Listing~\ref{lst:toolsoftrade:Demonstration of Exclusive Locks}
 shows \co{lock_writer()}, which
 periodically update the shared variable \co{x} while holding the
 specified \co{pthread_mutex_t}.
-As with \co{lock_reader()}, line~34 casts \co{arg} to a pointer
-to \co{pthread_mutex_t}, lines~36-39 acquires the specified lock,
-and lines~44-47 releases it.
-While holding the lock, lines~40-43 increment the shared variable \co{x},
+As with \co{lock_reader()}, line~\lnref{cast} casts \co{arg} to a pointer
+to \co{pthread_mutex_t},
+lines~\lnref{acq:b}-\lnref{acq:e} acquires the specified lock,
+and lines~\lnref{rel:b}-\lnref{rel:e} releases it.
+While holding the lock, lines~\lnref{loop:b}-\lnref{loop:e}
+increment the shared variable \co{x},
 sleeping for five milliseconds between each increment.
-Finally, lines~44-47 release the lock.
+Finally, lines~\lnref{rel:b}-\lnref{rel:e} release the lock.
+\end{lineref}
 
 \begin{listing}[tbp]
-{ \scriptsize
-\begin{verbbox}
-  1   printf("Creating two threads using same lock:\n");
-  2   if (pthread_create(&tid1, NULL,
-  3                      lock_reader, &lock_a) != 0) {
-  4     perror("pthread_create");
-  5     exit(EXIT_FAILURE);
-  6   }
-  7   if (pthread_create(&tid2, NULL,
-  8                      lock_writer, &lock_a) != 0) {
-  9     perror("pthread_create");
- 10     exit(EXIT_FAILURE);
- 11   }
- 12   if (pthread_join(tid1, &vp) != 0) {
- 13     perror("pthread_join");
- 14     exit(EXIT_FAILURE);
- 15   }
- 16   if (pthread_join(tid2, &vp) != 0) {
- 17     perror("pthread_join");
- 18     exit(EXIT_FAILURE);
- 19   }
-\end{verbbox}
-}
-\centering
-\theverbbox
+\input{CodeSamples/toolsoftrade/lock@same_lock.fcv}
 \caption{Demonstration of Same Exclusive Lock}
 \label{lst:toolsoftrade:Demonstration of Same Exclusive Lock}
 \end{listing}
 
+\begin{lineref}[ln:toolsoftrade:lock:same_lock]
 Listing~\ref{lst:toolsoftrade:Demonstration of Same Exclusive Lock}
 shows a code fragment that runs \co{lock_reader()} and
 \co{lock_writer()} as threads using the same lock, namely, \co{lock_a}.
-Lines~2-6 create a thread running \co{lock_reader()}, and then
-Lines~7-11 create a thread running \co{lock_writer()}.
-Lines~12-19 wait for both threads to complete.
+Lines~\lnref{cr:reader:b}-\lnref{cr:reader:e} create a thread
+running \co{lock_reader()}, and then
+Lines~\lnref{cr:writer:b}-\lnref{cr:writer:e} create a thread
+running \co{lock_writer()}.
+Lines~\lnref{wait:b}-\lnref{wait:e} wait for both threads to complete.
 The output of this code fragment is as follows:
+\end{lineref}
 
 \begin{VerbatimU}
 Creating two threads using same lock:
@@ -672,32 +614,7 @@ by \co{lock_writer()} while holding the lock.
 } \QuickQuizEnd
 
 \begin{listing}[tbp]
-{ \scriptsize
-\begin{verbbox}
-  1   printf("Creating two threads w/different locks:\n");
-  2   x = 0;
-  3   if (pthread_create(&tid1, NULL,
-  4                      lock_reader, &lock_a) != 0) {
-  5     perror("pthread_create");
-  6     exit(EXIT_FAILURE);
-  7   }
-  8   if (pthread_create(&tid2, NULL,
-  9                      lock_writer, &lock_b) != 0) {
- 10     perror("pthread_create");
- 11     exit(EXIT_FAILURE);
- 12   }
- 13   if (pthread_join(tid1, &vp) != 0) {
- 14     perror("pthread_join");
- 15     exit(EXIT_FAILURE);
- 16   }
- 17   if (pthread_join(tid2, &vp) != 0) {
- 18     perror("pthread_join");
- 19     exit(EXIT_FAILURE);
- 20   }
-\end{verbbox}
-}
-\centering
-\theverbbox
+\input{CodeSamples/toolsoftrade/lock@diff_lock.fcv}
 \caption{Demonstration of Different Exclusive Locks}
 \label{lst:toolsoftrade:Demonstration of Different Exclusive Locks}
 \end{listing}
@@ -761,7 +678,7 @@ values of \co{x} stored by \co{lock_writer()}.
 	so why does it need to be initialized in
 	Listing~\ref{lst:toolsoftrade:Demonstration of Different Exclusive Locks}?
 \QuickQuizAnswer{
-	See line~3 of
+	See line~\ref{ln:toolsoftrade:lock:reader_writer:x} of
 	Listing~\ref{lst:toolsoftrade:Demonstration of Exclusive Locks}.
 	Because the code in
 	Listing~\ref{lst:toolsoftrade:Demonstration of Same Exclusive Lock}
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/7] toolsoftrade: Employ new scheme for snippet of rwlockscale.c
  2018-10-26 15:22 [PATCH 0/7] count, toolsoftrade: Employ new code-snippet scheme (cont.) Akira Yokosawa
                   ` (2 preceding siblings ...)
  2018-10-26 15:26 ` [PATCH 3/7] toolsoftrade: Employ new scheme for snippets of lock.c Akira Yokosawa
@ 2018-10-26 15:27 ` Akira Yokosawa
  2018-10-26 15:28 ` [PATCH 5/7] toolsoftrade: Employ new scheme for snippet of compiler barriers Akira Yokosawa
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Akira Yokosawa @ 2018-10-26 15:27 UTC (permalink / raw)
  To: Paul E. McKenney; +Cc: perfbook, Akira Yokosawa

From 5f85ee80de39323a192da10c4a25ae8ec0f4cd2c Mon Sep 17 00:00:00 2001
From: Akira Yokosawa <akiyks@gmail.com>
Date: Sun, 14 Oct 2018 18:00:26 +0900
Subject: [PATCH 4/7] toolsoftrade: Employ new scheme for snippet of rwlockscale.c

Signed-off-by: Akira Yokosawa <akiyks@gmail.com>
---
 CodeSamples/toolsoftrade/rwlockscale.c | 54 ++++++++++----------
 toolsoftrade/toolsoftrade.tex          | 93 +++++++++++-----------------------
 2 files changed, 57 insertions(+), 90 deletions(-)

diff --git a/CodeSamples/toolsoftrade/rwlockscale.c b/CodeSamples/toolsoftrade/rwlockscale.c
index affb5a2..b46837e 100644
--- a/CodeSamples/toolsoftrade/rwlockscale.c
+++ b/CodeSamples/toolsoftrade/rwlockscale.c
@@ -26,50 +26,52 @@
 #include <errno.h>
 #include "../api.h"
 
-pthread_rwlock_t rwl = PTHREAD_RWLOCK_INITIALIZER;
-int holdtime = 0;	/* # loops holding lock. */
-int thinktime = 0;	/* # loops not holding lock. */
-long long *readcounts;
-int nreadersrunning = 0;
+//\begin{snippet}[labelbase=ln:toolsoftrade:rwlockscale:reader,commandchars=\@\^\$]
+pthread_rwlock_t rwl = PTHREAD_RWLOCK_INITIALIZER;	//\lnlbl{rwlock}
+int holdtime = 0;	/* # loops holding lock. */	//\lnlbl{holdtm}
+int thinktime = 0;	/* # loops not holding lock. */	//\lnlbl{thinktm}
+long long *readcounts;					//\lnlbl{rdcnts}
+int nreadersrunning = 0;				//\lnlbl{nrdrun}
 
-#define GOFLAG_INIT 0
+#define GOFLAG_INIT 0					//\lnlbl{goflag:b}
 #define GOFLAG_RUN  1
 #define GOFLAG_STOP 2
-char goflag = GOFLAG_INIT;
+char goflag = GOFLAG_INIT;				//\lnlbl{goflag:e}
 
-void *reader(void *arg)
+void *reader(void *arg)					//\lnlbl{reader:b}
 {
 	int en;
 	int i;
 	long long loopcnt = 0;
 	long me = (long)arg;
 
-	__sync_fetch_and_add(&nreadersrunning, 1);
-	while (READ_ONCE(goflag) == GOFLAG_INIT) {
+	__sync_fetch_and_add(&nreadersrunning, 1);	//\lnlbl{reader:atmc_inc}
+	while (READ_ONCE(goflag) == GOFLAG_INIT) {	//\lnlbl{reader:wait:b}
 		continue;
-	}
-	while (READ_ONCE(goflag) == GOFLAG_RUN) {
-		if ((en = pthread_rwlock_rdlock(&rwl)) != 0) {
+	}						//\lnlbl{reader:wait:e}
+	while (READ_ONCE(goflag) == GOFLAG_RUN) {	//\lnlbl{reader:loop:b}
+		if ((en = pthread_rwlock_rdlock(&rwl)) != 0) {	//\lnlbl{reader:acq:b}
 			fprintf(stderr,
-				"pthread_rwlock_rdlock: %s\n", strerror(en));
+			        "pthread_rwlock_rdlock: %s\n", strerror(en));
 			exit(EXIT_FAILURE);
-		}
-		for (i = 1; i < holdtime; i++) {
+		}						//\lnlbl{reader:acq:e}
+		for (i = 1; i < holdtime; i++) {	//\lnlbl{reader:hold:b}
 			barrier();
-		}
-		if ((en = pthread_rwlock_unlock(&rwl)) != 0) {
+		}					//\lnlbl{reader:hold:e}
+		if ((en = pthread_rwlock_unlock(&rwl)) != 0) {	//\lnlbl{reader:rel:b}
 			fprintf(stderr,
 				"pthread_rwlock_unlock: %s\n", strerror(en));
 			exit(EXIT_FAILURE);
-		}
-		for (i = 1; i < thinktime; i++) {
+		}						//\lnlbl{reader:rel:e}
+		for (i = 1; i < thinktime; i++) {	//\lnlbl{reader:think:b}
 			barrier();
-		}
-		loopcnt++;
-	}
-	readcounts[me] = loopcnt;
-	return NULL;
-}
+		}					//\lnlbl{reader:think:e}
+		loopcnt++;				//\lnlbl{reader:count}
+	}						//\lnlbl{reader:loop:e}
+	readcounts[me] = loopcnt;			//\lnlbl{reader:mov_cnt}
+	return NULL;					//\lnlbl{reader:return}
+}							//\lnlbl{reader:e}
+//\end{snippet}
 
 int main(int argc, char *argv[])
 {
diff --git a/toolsoftrade/toolsoftrade.tex b/toolsoftrade/toolsoftrade.tex
index e699b6e..d808df6 100644
--- a/toolsoftrade/toolsoftrade.tex
+++ b/toolsoftrade/toolsoftrade.tex
@@ -722,87 +722,47 @@ However, in practice, we need to know how much additional scalability is
 provided by reader-writer locks.
 
 \begin{listing}[tbp]
-{ \scriptsize
-\begin{verbbox}
-  1 pthread_rwlock_t rwl = PTHREAD_RWLOCK_INITIALIZER;
-  2 int holdtime = 0;
-  3 int thinktime = 0;
-  4 long long *readcounts;
-  5 int nreadersrunning = 0;
-  6 
-  7 #define GOFLAG_INIT 0
-  8 #define GOFLAG_RUN  1
-  9 #define GOFLAG_STOP 2
- 10 char goflag = GOFLAG_INIT;
- 11 
- 12 void *reader(void *arg)
- 13 {
- 14   int i;
- 15   long long loopcnt = 0;
- 16   long me = (long)arg;
- 17 
- 18   __sync_fetch_and_add(&nreadersrunning, 1);
- 19   while (READ_ONCE(goflag) == GOFLAG_INIT) {
- 20     continue;
- 21   }
- 22   while (READ_ONCE(goflag) == GOFLAG_RUN) {
- 23     if (pthread_rwlock_rdlock(&rwl) != 0) {
- 24       perror("pthread_rwlock_rdlock");
- 25       exit(EXIT_FAILURE);
- 26     }
- 27     for (i = 1; i < holdtime; i++) {
- 28       barrier();
- 29     }
- 30     if (pthread_rwlock_unlock(&rwl) != 0) {
- 31       perror("pthread_rwlock_unlock");
- 32       exit(EXIT_FAILURE);
- 33     }
- 34     for (i = 1; i < thinktime; i++) {
- 35       barrier();
- 36     }
- 37     loopcnt++;
- 38   }
- 39   readcounts[me] = loopcnt;
- 40   return NULL;
- 41 }
-\end{verbbox}
-}
-\centering
-\theverbbox
+\input{CodeSamples/toolsoftrade/rwlockscale@reader.fcv}
 \caption{Measuring Reader-Writer Lock Scalability}
 \label{lst:toolsoftrade:Measuring Reader-Writer Lock Scalability}
 \end{listing}
 
+\begin{lineref}[ln:toolsoftrade:rwlockscale:reader]
 Listing~\ref{lst:toolsoftrade:Measuring Reader-Writer Lock Scalability}
 (\path{rwlockscale.c})
 shows one way of measuring reader-writer lock scalability.
-Line~1 shows the definition and initialization of the reader-writer
-lock, line~2 shows the \co{holdtime} argument controlling the
+Line~\lnref{rwlock} shows the definition and initialization of the reader-writer
+lock, line~\lnref{holdtm} shows the \co{holdtime} argument controlling the
 time each thread holds the reader-writer lock,
-line~3 shows the \co{thinktime} argument controlling the time between
+line~\lnref{thinktm} shows the \co{thinktime} argument controlling the time between
 the release of the reader-writer lock and the next acquisition,
-line~4 defines the \co{readcounts} array into which each reader thread
+line~\lnref{rdcnts} defines the \co{readcounts} array into which each reader thread
 places the number of times it acquired the lock, and
-line~5 defines the \co{nreadersrunning} variable, which
+line~\lnref{nrdrun} defines the \co{nreadersrunning} variable, which
 determines when all reader threads have started running.
 
-Lines~7-10 define \co{goflag}, which synchronizes the start and the
+Lines~\lnref{goflag:b}-\lnref{goflag:e} define \co{goflag},
+which synchronizes the start and the
 end of the test.
 This variable is initially set to \co{GOFLAG_INIT}, then set to
 \co{GOFLAG_RUN} after all the reader threads have started, and finally
 set to \co{GOFLAG_STOP} to terminate the test run.
+\end{lineref}
 
-Lines~12-41 define \co{reader()}, which is the reader thread.
-Line~18 atomically increments the \co{nreadersrunning} variable
+\begin{lineref}[ln:toolsoftrade:rwlockscale:reader:reader]
+Lines~\lnref{b}-\lnref{e} define \co{reader()}, which is the reader thread.
+Line~\lnref{atmc_inc} atomically increments the \co{nreadersrunning} variable
 to indicate that this thread is now running, and
-lines~19-21 wait for the test to start.
+lines~\lnref{wait:b}-\lnref{wait:e} wait for the test to start.
 The \co{READ_ONCE()} primitive forces the compiler to fetch \co{goflag}
 on each pass through the loop---the compiler would otherwise be within its
 rights to assume that the value of \co{goflag} would never change.
+\end{lineref}
 
 \QuickQuiz{}
 	Instead of using \co{READ_ONCE()} everywhere, why not just
-	declare \co{goflag} as \co{volatile} on line~10 of
+	declare \co{goflag} as \co{volatile} on
+        line~\ref{ln:toolsoftrade:rwlockscale:reader:goflag:e} of
 	Listing~\ref{lst:toolsoftrade:Measuring Reader-Writer Lock Scalability}?
 \QuickQuizAnswer{
 	A \co{volatile} declaration is in fact a reasonable alternative in
@@ -867,16 +827,21 @@ rights to assume that the value of \co{goflag} would never change.
 	\co{__thread} variable in the corresponding element.
 } \QuickQuizEnd
 
-The loop spanning lines~22-38 carries out the performance test.
-Lines~23-26 acquire the lock, lines~27-29 hold the lock for the specified
+\begin{lineref}[ln:toolsoftrade:rwlockscale:reader:reader]
+The loop spanning lines~\lnref{loop:b}-\lnref{loop:e} carries out the performance test.
+Lines~\lnref{acq:b}-\lnref{acq:e} acquire the lock,
+lines~\lnref{hold:b}-\lnref{hold:e} hold the lock for the specified
 duration (and the \co{barrier()} directive prevents the compiler from
-optimizing the loop out of existence), lines~30-33 release the lock,
-and lines~34-36 wait for the specified duration before re-acquiring the
+optimizing the loop out of existence),
+lines~\lnref{rel:b}-\lnref{rel:e} release the lock,
+and lines~\lnref{think:b}-\lnref{think:e} wait for the specified
+duration before re-acquiring the
 lock.
-Line~37 counts this lock acquisition.
+Line~\lnref{count} counts this lock acquisition.
 
-Line~39 moves the lock-acquisition count to this thread's element of the
-\co{readcounts[]} array, and line~40 returns, terminating this thread.
+Line~\lnref{mov_cnt} moves the lock-acquisition count to this thread's element of the
+\co{readcounts[]} array, and line~\lnref{return} returns, terminating this thread.
+\end{lineref}
 
 \begin{figure}[tb]
 \centering
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 5/7] toolsoftrade: Employ new scheme for snippet of compiler barriers
  2018-10-26 15:22 [PATCH 0/7] count, toolsoftrade: Employ new code-snippet scheme (cont.) Akira Yokosawa
                   ` (3 preceding siblings ...)
  2018-10-26 15:27 ` [PATCH 4/7] toolsoftrade: Employ new scheme for snippet of rwlockscale.c Akira Yokosawa
@ 2018-10-26 15:28 ` Akira Yokosawa
  2018-10-26 15:29 ` [PATCH 6/7] toolsoftrade: Employ new scheme for snippets of threadcreate.c Akira Yokosawa
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 10+ messages in thread
From: Akira Yokosawa @ 2018-10-26 15:28 UTC (permalink / raw)
  To: Paul E. McKenney; +Cc: perfbook, Akira Yokosawa

From 65dac5efc38d7dbb1710d727bc6b67732ce8968c Mon Sep 17 00:00:00 2001
From: Akira Yokosawa <akiyks@gmail.com>
Date: Sun, 14 Oct 2018 18:11:20 +0900
Subject: [PATCH 5/7] toolsoftrade: Employ new scheme for snippet of compiler barriers

Signed-off-by: Akira Yokosawa <akiyks@gmail.com>
---
 CodeSamples/api-pthreads/api-pthreads.h |  7 +++++--
 toolsoftrade/toolsoftrade.tex           | 12 +-----------
 2 files changed, 6 insertions(+), 13 deletions(-)

diff --git a/CodeSamples/api-pthreads/api-pthreads.h b/CodeSamples/api-pthreads/api-pthreads.h
index 6bde0c9..f5510f0 100644
--- a/CodeSamples/api-pthreads/api-pthreads.h
+++ b/CodeSamples/api-pthreads/api-pthreads.h
@@ -53,7 +53,6 @@
 	const typeof( ((type *)0)->member ) *__mptr = (ptr);	\
 	(type *)( (char *)__mptr - offsetof(type,member) );})
 #endif /* #ifndef offsetof */
-#define barrier() __asm__ __volatile__("": : :"memory")
 
 /*
  * Default machine parameters.
@@ -133,9 +132,13 @@ static __inline__ int spin_is_locked(spinlock_t *sp)
 #define spin_lock_irqsave(l, f) do { f = 1; spin_lock(l); } while (0)
 #define spin_unlock_irqrestore(l, f) do { f = 0; spin_unlock(l); } while (0)
 
+//\begin{snippet}[labelbase=ln:api-pthreads:api-pthreads:compiler_barrier,commandchars=\@\[\],numbers=none]
 #define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
-#define READ_ONCE(x) ({ typeof(x) ___x = ACCESS_ONCE(x); ___x; })
+#define READ_ONCE(x) \
+            ({ typeof(x) ___x = ACCESS_ONCE(x); ___x; })
 #define WRITE_ONCE(x, val) ({ ACCESS_ONCE(x) = (val); })
+#define barrier() __asm__ __volatile__("": : :"memory")
+//\end{snippet}
 #ifndef unlikely
 #define unlikely(x) x
 #endif /* #ifndef unlikely */
diff --git a/toolsoftrade/toolsoftrade.tex b/toolsoftrade/toolsoftrade.tex
index d808df6..f1a96ff 100644
--- a/toolsoftrade/toolsoftrade.tex
+++ b/toolsoftrade/toolsoftrade.tex
@@ -1076,17 +1076,7 @@ and all three are discussed at length in
 Section~\ref{sec:toolsoftrade:Accessing Shared Variables}.
 
 \begin{listing}[tb]
-{ \scriptsize
-\begin{verbbox}
-#define ACCESS_ONCE(x) (*(volatile typeof(x) *)&(x))
-#define READ_ONCE(x) \
-            ({ typeof(x) ___x = ACCESS_ONCE(x); ___x; })
-#define WRITE_ONCE(x, val) ({ ACCESS_ONCE(x) = (val); })
-#define barrier() __asm__ __volatile__("": : :"memory")
-\end{verbbox}
-}
-\centering
-\theverbbox
+\input{CodeSamples/api-pthreads/api-pthreads@compiler_barrier.fcv}
 \caption{Compiler Barrier Primitive (for \GCC)}
 \label{lst:toolsoftrade:Compiler Barrier Primitive (for GCC)}
 \end{listing}
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 6/7] toolsoftrade: Employ new scheme for snippets of threadcreate.c
  2018-10-26 15:22 [PATCH 0/7] count, toolsoftrade: Employ new code-snippet scheme (cont.) Akira Yokosawa
                   ` (4 preceding siblings ...)
  2018-10-26 15:28 ` [PATCH 5/7] toolsoftrade: Employ new scheme for snippet of compiler barriers Akira Yokosawa
@ 2018-10-26 15:29 ` Akira Yokosawa
  2018-10-26 15:30 ` [PATCH 7/7] count: Fix indent in count_lim_atomic.c Akira Yokosawa
  2018-10-26 15:35 ` [PATCH 0/7] count, toolsoftrade: Employ new code-snippet scheme (cont.) Akira Yokosawa
  7 siblings, 0 replies; 10+ messages in thread
From: Akira Yokosawa @ 2018-10-26 15:29 UTC (permalink / raw)
  To: Paul E. McKenney; +Cc: perfbook, Akira Yokosawa

From 334b421f68729c28fac868f5d89af6d4aa6d1090 Mon Sep 17 00:00:00 2001
From: Akira Yokosawa <akiyks@gmail.com>
Date: Sun, 14 Oct 2018 20:47:07 +0900
Subject: [PATCH 6/7] toolsoftrade: Employ new scheme for snippets of threadcreate.c

Also convert snippets of thread API, locking API, and per-thread API.
As the snippet of thread API fits the column width of 2c layout,
use "listing" environment instead of "listing*".

Signed-off-by: Akira Yokosawa <akiyks@gmail.com>
---
 CodeSamples/intro/threadcreate.c | 20 +++++----
 toolsoftrade/toolsoftrade.tex    | 90 ++++++++++------------------------------
 2 files changed, 34 insertions(+), 76 deletions(-)

diff --git a/CodeSamples/intro/threadcreate.c b/CodeSamples/intro/threadcreate.c
index 94cde89..381742a 100644
--- a/CodeSamples/intro/threadcreate.c
+++ b/CodeSamples/intro/threadcreate.c
@@ -20,14 +20,16 @@
 
 #include "../api.h"
 
+//\begin{snippet}[labelbase=ln:intro:threadcreate:thread_test,commandchars=\@\[\]]
 void *thread_test(void *arg)
 {
 	int myarg = (intptr_t)arg;
 
 	printf("child thread %d: smp_thread_id() = %d\n",
 	       myarg, smp_thread_id());
-	return NULL;
+	return NULL;				//\lnlbl{return}
 }
+//\end{snippet}
 
 void usage(char *progname)
 {
@@ -36,29 +38,31 @@ void usage(char *progname)
 	exit(-1);
 }
 
+//\begin{snippet}[labelbase=ln:intro:threadcreate:main,commandchars=\@\^\$]
 int main(int argc, char *argv[])
 {
 	int i;
 	int nkids = 1;
 
-	smp_init();
+	smp_init();					//\lnlbl{smp_init}
 
-	if (argc > 1) {
+	if (argc > 1) {					//\lnlbl{parse:b}
 		nkids = strtoul(argv[1], NULL, 0);
 		if (nkids > NR_THREADS) {
 			fprintf(stderr, "nkids = %d too large, max = %d\n",
 				nkids, NR_THREADS);
 			usage(argv[0]);
 		}
-	}
-	printf("Parent thread spawning %d threads.\n", nkids);
+	}						//\lnlbl{parse:e}
+	printf("Parent thread spawning %d threads.\n", nkids); //\lnlbl{announce}
 
-	for (i = 0; i < nkids; i++)
-		create_thread(thread_test, (void *)(intptr_t)i);
+	for (i = 0; i < nkids; i++)			//\lnlbl{create:b}
+		create_thread(thread_test, (void *)(intptr_t)i); //\lnlbl{create:e}
 
-	wait_all_threads();
+	wait_all_threads();				//\lnlbl{wait}
 
 	printf("All spawned threads completed.\n");
 
 	exit(0);
 }
+//\end{snippet}
diff --git a/toolsoftrade/toolsoftrade.tex b/toolsoftrade/toolsoftrade.tex
index f1a96ff..12dabd0 100644
--- a/toolsoftrade/toolsoftrade.tex
+++ b/toolsoftrade/toolsoftrade.tex
@@ -1247,22 +1247,18 @@ The thread API is shown in
 Listing~\ref{lst:toolsoftrade:Thread API}, and members are described in the
 following sections.
 
-\begin{listing*}[tbp]
-{ \scriptsize
-\begin{verbbox}
+\begin{listing}[tbp]
+\begin{VerbatimL}[numbers=none,xleftmargin=2pt]
 int smp_thread_id(void)
 thread_id_t create_thread(void *(*func)(void *), void *arg)
 for_each_thread(t)
 for_each_running_thread(t)
 void *wait_thread(thread_id_t tid)
 void wait_all_threads(void)
-\end{verbbox}
-}
-\centering
-\theverbbox
+\end{VerbatimL}
 \caption{Thread API}
 \label{lst:toolsoftrade:Thread API}
-\end{listing*}
+\end{listing}
 
 \subsubsection{\tco{create_thread()}}
 
@@ -1327,73 +1323,39 @@ a run, so such synchronization is normally not needed.
 
 \subsubsection{Example Usage}
 
-Listing~\ref{lst:toolsoftrade:Example Child Thread}
+Listing~\ref{lst:toolsoftrade:Example Child Thread} (\path{threadcreate.c})
 shows an example hello-world-like child thread.
 As noted earlier, each thread is allocated its own stack, so
 each thread has its own private \co{arg} argument and \co{myarg} variable.
 Each child simply prints its argument and its \co{smp_thread_id()}
 before exiting.
-Note that the \co{return} statement on line~7 terminates the thread,
+Note that the \co{return} statement on
+line~\ref{ln:intro:threadcreate:thread_test:return} terminates the thread,
 returning a \co{NULL} to whoever invokes \co{wait_thread()} on this
 thread.
 
 \begin{listing}[tbp]
-{ \scriptsize
-\begin{verbbox}
-  1 void *thread_test(void *arg)
-  2 {
-  3   int myarg = (int)arg;
-  4
-  5   printf("child thread %d: smp_thread_id() = %d\n",
-  6          myarg, smp_thread_id());
-  7   return NULL;
-  8 }
-\end{verbbox}
-}
-\centering
-\theverbbox
+\input{CodeSamples/intro/threadcreate@thread_test.fcv}
 \caption{Example Child Thread}
 \label{lst:toolsoftrade:Example Child Thread}
 \end{listing}
 
+\begin{lineref}[ln:intro:threadcreate:main]
 The parent program is shown in
 Listing~\ref{lst:toolsoftrade:Example Parent Thread}.
 It invokes \co{smp_init()} to initialize the threading system on
-line~6,
-parses arguments on lines~7-14, and announces its presence on line~15.
-It creates the specified number of child threads on lines~16-17,
-and waits for them to complete on line~18.
+line~\lnref{smp_init},
+parses arguments on lines~\lnref{parse:b}-\lnref{parse:e},
+and announces its presence on line~\lnref{announce}.
+It creates the specified number of child threads on
+lines~\lnref{create:b}-\lnref{create:e},
+and waits for them to complete on line~\lnref{wait}.
 Note that \co{wait_all_threads()} discards the threads return values,
 as in this case they are all \co{NULL}, which is not very interesting.
+\end{lineref}
 
 \begin{listing}[tbp]
-{ \scriptsize
-\begin{verbbox}
-  1 int main(int argc, char *argv[])
-  2 {
-  3   int i;
-  4   int nkids = 1;
-  5
-  6   smp_init();
-  7   if (argc > 1) {
-  8     nkids = strtoul(argv[1], NULL, 0);
-  9     if (nkids > NR_THREADS) {
- 10       fprintf(stderr, "nkids=%d too big, max=%d\n",
- 11         nkids, NR_THREADS);
- 12       usage(argv[0]);
- 13     }
- 14   }
- 15   printf("Parent spawning %d threads.\n", nkids);
- 16   for (i = 0; i < nkids; i++)
- 17     create_thread(thread_test, (void *)i);
- 18   wait_all_threads();
- 19   printf("All threads completed.\n", nkids);
- 20   return EXIT_SUCCESS;
- 21 }
-\end{verbbox}
-}
-\centering
-\theverbbox
+\input{CodeSamples/intro/threadcreate@main.fcv}
 \caption{Example Parent Thread}
 \label{lst:toolsoftrade:Example Parent Thread}
 \end{listing}
@@ -1417,16 +1379,12 @@ each API element being described in the following sections.
 This book's CodeSamples locking API closely follows that of the Linux kernel.
 
 \begin{listing}[tbp]
-{ \scriptsize
-\begin{verbbox}
+\begin{VerbatimL}[numbers=none]
 void spin_lock_init(spinlock_t *sp);
 void spin_lock(spinlock_t *sp);
 int spin_trylock(spinlock_t *sp);
 void spin_unlock(spinlock_t *sp);
-\end{verbbox}
-}
-\centering
-\theverbbox
+\end{VerbatimL}
 \caption{Locking API}
 \label{lst:toolsoftrade:Locking API}
 \end{listing}
@@ -2271,18 +2229,14 @@ Although this API is, strictly speaking, not necessary\footnote{
 	You could instead use \co{__thread} or \co{_Thread_local}.},
 it can provide a good userspace analogy to Linux kernel code.
 
-\begin{listing}[htbp]
-{ \scriptsize
-\begin{verbbox}
+\begin{listing}[tbp]
+\begin{VerbatimL}[numbers=none]
 DEFINE_PER_THREAD(type, name)
 DECLARE_PER_THREAD(type, name)
 per_thread(name, thread)
 __get_thread_var(name)
 init_per_thread(name, v)
-\end{verbbox}
-}
-\centering
-\theverbbox
+\end{VerbatimL}
 \caption{Per-Thread-Variable API}
 \label{lst:toolsoftrade:Per-Thread-Variable API}
 \end{listing}
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 7/7] count: Fix indent in count_lim_atomic.c
  2018-10-26 15:22 [PATCH 0/7] count, toolsoftrade: Employ new code-snippet scheme (cont.) Akira Yokosawa
                   ` (5 preceding siblings ...)
  2018-10-26 15:29 ` [PATCH 6/7] toolsoftrade: Employ new scheme for snippets of threadcreate.c Akira Yokosawa
@ 2018-10-26 15:30 ` Akira Yokosawa
  2018-10-26 15:35 ` [PATCH 0/7] count, toolsoftrade: Employ new code-snippet scheme (cont.) Akira Yokosawa
  7 siblings, 0 replies; 10+ messages in thread
From: Akira Yokosawa @ 2018-10-26 15:30 UTC (permalink / raw)
  To: Paul E. McKenney; +Cc: perfbook, Akira Yokosawa

From 453bc63fd38da42f52eb88b4fed0a38b0f431cf9 Mon Sep 17 00:00:00 2001
From: Akira Yokosawa <akiyks@gmail.com>
Date: Sat, 20 Oct 2018 07:50:26 +0900
Subject: [PATCH 7/7] count: Fix indent in count_lim_atomic.c

Commit 51e9218ac25e ("count: Employ new scheme for snippet of
count_lim_atomic") changed indent width by accident.  Fix it.

Signed-off-by: Akira Yokosawa <akiyks@gmail.com>
---
 CodeSamples/count/count_lim_atomic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CodeSamples/count/count_lim_atomic.c b/CodeSamples/count/count_lim_atomic.c
index 6190a9f..02f4e6d 100644
--- a/CodeSamples/count/count_lim_atomic.c
+++ b/CodeSamples/count/count_lim_atomic.c
@@ -137,7 +137,7 @@ int sub_count(unsigned long delta)			//\lnlbl{sub:b}
 	do {						//\lnlbl{sub:fast:b}
 		split_counterandmax(&counterandmax, &old, &c, &cm);
 		if (delta > c)
-		  goto slowpath;
+			goto slowpath;
 		new = merge_counterandmax(c - delta, cm);
 	} while (atomic_cmpxchg(&counterandmax,
 	                        old, new) != old);
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 0/7] count, toolsoftrade: Employ new code-snippet scheme (cont.)
  2018-10-26 15:22 [PATCH 0/7] count, toolsoftrade: Employ new code-snippet scheme (cont.) Akira Yokosawa
                   ` (6 preceding siblings ...)
  2018-10-26 15:30 ` [PATCH 7/7] count: Fix indent in count_lim_atomic.c Akira Yokosawa
@ 2018-10-26 15:35 ` Akira Yokosawa
  2018-10-26 20:58   ` Paul E. McKenney
  7 siblings, 1 reply; 10+ messages in thread
From: Akira Yokosawa @ 2018-10-26 15:35 UTC (permalink / raw)
  To: Paul E. McKenney; +Cc: perfbook, Akira Yokosawa

On 2018/10/27 00:22:37 +0900, Akira Yokosawa wrote:
> Hi Paul,
> 
> This is a set of simple conversions of code snippets to the new scheme
> in count and toolsoftrade.  There is no change in the code under CodeSamples,
> but there are a few visual changes in the pdf output which reflect the
> actual code samples.

I forgot to mention that Patch #3 contains minor changes in the code to
reduce width of code snippets.

        Thanks, Akira

> 
> Patch #7 fixes an unintended change in indent width made in the previous
> patch set.
> 
>         Thanks, Akira
> --
> Akira Yokosawa (7):
>   count: Employ new scheme for inline code snippets
>   toolsoftrade: Use 'VerbatimU' for inline snippets
>   toolsoftrade: Employ new scheme for snippets of lock.c
>   toolsoftrade: Employ new scheme for snippet of rwlockscale.c
>   toolsoftrade: Employ new scheme for snippet of compiler barriers
>   toolsoftrade: Employ new scheme for snippets of threadcreate.c
>   count: Fix indent in count_lim_atomic.c
> 
>  CodeSamples/api-pthreads/api-pthreads.h |   7 +-
>  CodeSamples/count/count_lim_atomic.c    |   2 +-
>  CodeSamples/intro/threadcreate.c        |  20 +-
>  CodeSamples/toolsoftrade/lock.c         |  76 +++---
>  CodeSamples/toolsoftrade/rwlockscale.c  |  54 ++--
>  count/count.tex                         |  89 +++---
>  toolsoftrade/toolsoftrade.tex           | 460 ++++++++------------------------
>  7 files changed, 253 insertions(+), 455 deletions(-)
> 


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 0/7] count, toolsoftrade: Employ new code-snippet scheme (cont.)
  2018-10-26 15:35 ` [PATCH 0/7] count, toolsoftrade: Employ new code-snippet scheme (cont.) Akira Yokosawa
@ 2018-10-26 20:58   ` Paul E. McKenney
  0 siblings, 0 replies; 10+ messages in thread
From: Paul E. McKenney @ 2018-10-26 20:58 UTC (permalink / raw)
  To: Akira Yokosawa; +Cc: perfbook

On Sat, Oct 27, 2018 at 12:35:10AM +0900, Akira Yokosawa wrote:
> On 2018/10/27 00:22:37 +0900, Akira Yokosawa wrote:
> > Hi Paul,
> > 
> > This is a set of simple conversions of code snippets to the new scheme
> > in count and toolsoftrade.  There is no change in the code under CodeSamples,
> > but there are a few visual changes in the pdf output which reflect the
> > actual code samples.
> 
> I forgot to mention that Patch #3 contains minor changes in the code to
> reduce width of code snippets.
> 
>         Thanks, Akira
> 
> > 
> > Patch #7 fixes an unintended change in indent width made in the previous
> > patch set.
> > 
> >         Thanks, Akira

I applied and pushed this series, thank you!

							Thanx, Paul

> > --
> > Akira Yokosawa (7):
> >   count: Employ new scheme for inline code snippets
> >   toolsoftrade: Use 'VerbatimU' for inline snippets
> >   toolsoftrade: Employ new scheme for snippets of lock.c
> >   toolsoftrade: Employ new scheme for snippet of rwlockscale.c
> >   toolsoftrade: Employ new scheme for snippet of compiler barriers
> >   toolsoftrade: Employ new scheme for snippets of threadcreate.c
> >   count: Fix indent in count_lim_atomic.c
> > 
> >  CodeSamples/api-pthreads/api-pthreads.h |   7 +-
> >  CodeSamples/count/count_lim_atomic.c    |   2 +-
> >  CodeSamples/intro/threadcreate.c        |  20 +-
> >  CodeSamples/toolsoftrade/lock.c         |  76 +++---
> >  CodeSamples/toolsoftrade/rwlockscale.c  |  54 ++--
> >  count/count.tex                         |  89 +++---
> >  toolsoftrade/toolsoftrade.tex           | 460 ++++++++------------------------
> >  7 files changed, 253 insertions(+), 455 deletions(-)
> > 
> 


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2018-10-27  5:37 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-10-26 15:22 [PATCH 0/7] count, toolsoftrade: Employ new code-snippet scheme (cont.) Akira Yokosawa
2018-10-26 15:24 ` [PATCH 1/7] count: Employ new scheme for inline code snippets Akira Yokosawa
2018-10-26 15:24 ` [PATCH 2/7] toolsoftrade: Use 'VerbatimU' for inline snippets Akira Yokosawa
2018-10-26 15:26 ` [PATCH 3/7] toolsoftrade: Employ new scheme for snippets of lock.c Akira Yokosawa
2018-10-26 15:27 ` [PATCH 4/7] toolsoftrade: Employ new scheme for snippet of rwlockscale.c Akira Yokosawa
2018-10-26 15:28 ` [PATCH 5/7] toolsoftrade: Employ new scheme for snippet of compiler barriers Akira Yokosawa
2018-10-26 15:29 ` [PATCH 6/7] toolsoftrade: Employ new scheme for snippets of threadcreate.c Akira Yokosawa
2018-10-26 15:30 ` [PATCH 7/7] count: Fix indent in count_lim_atomic.c Akira Yokosawa
2018-10-26 15:35 ` [PATCH 0/7] count, toolsoftrade: Employ new code-snippet scheme (cont.) Akira Yokosawa
2018-10-26 20:58   ` Paul E. McKenney

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.