[PATCH 4/7] toolsoftrade: Employ new scheme for snippet of rwlockscale.c

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

 



>From 5f85ee80de39323a192da10c4a25ae8ec0f4cd2c Mon Sep 17 00:00:00 2001
From: Akira Yokosawa <akiyks@xxxxxxxxx>
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@xxxxxxxxx>
---
 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@xxxxxxxxxx}
 \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





[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