Re: [PATCH] Convert code snippets to 'listing' env (howto, toolsoftrade, count)

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

 



On Wed, Oct 11, 2017 at 07:40:14AM +0900, Akira Yokosawa wrote:
> >From d3f43d97fdbcbe68b6e5936b8d94c50b78bfeaaf Mon Sep 17 00:00:00 2001
> From: Akira Yokosawa <akiyks@xxxxxxxxx>
> Date: Mon, 10 Oct 2017 22:18:17 +0900
> Subject: [PATCH] Convert code snippets to 'listing' env (howto, toolsoftrade, count)
> 
> Also fix a typo referring table by "Figure" in count.tex.
> 
> Signed-off-by: Akira Yokosawa <akiyks@xxxxxxxxx>
> ---
> Hi Paul,
> 
> Looks like we have some time to do the conversion to "listing" environments
> before the upcoming release.
> 
> This is the 1st round of the conversion.

Looks like a good time, thank you!  Queued and pushed.

							Thanx, Paul

>             Thanks, Akira
> --
>  count/count.tex               | 276 +++++++++++++++++++++---------------------
>  defer/rcuexercises.tex        |   2 +-
>  howto/howto.tex               |  20 +--
>  owned/owned.tex               |  28 ++---
>  together/applyrcu.tex         |  16 +--
>  toolsoftrade/toolsoftrade.tex | 140 ++++++++++-----------
>  6 files changed, 241 insertions(+), 241 deletions(-)
> 
> diff --git a/count/count.tex b/count/count.tex
> index a213558..9638971 100644
> --- a/count/count.tex
> +++ b/count/count.tex
> @@ -165,7 +165,7 @@ are more appropriate for advanced students.
>  \section{Why Isn't Concurrent Counting Trivial?}
>  \label{sec:count:Why Isn't Concurrent Counting Trivial?}
> 
> -\begin{figure}[bp]
> +\begin{listing}[bp]
>  { \scriptsize
>  \begin{verbbox}
>    1 long counter = 0;
> @@ -184,12 +184,12 @@ are more appropriate for advanced students.
>  \centering
>  \theverbbox
>  \caption{Just Count!}
> -\label{fig:count:Just Count!}
> -\end{figure}
> +\label{lst:count:Just Count!}
> +\end{listing}
> 
>  Let's start with something simple, for example, the straightforward
>  use of arithmetic shown in
> -Figure~\ref{fig:count:Just Count!} (\path{count_nonatomic.c}).
> +Listing~\ref{lst:count:Just Count!} (\path{count_nonatomic.c}).
>  Here, we have a counter on line~1, we increment it on line~5, and we
>  read out its value on line~10.
>  What could be simpler?
> @@ -242,7 +242,7 @@ accuracies far greater than 50\,\% are almost always necessary.
>  	Furthermore, proofs can have bugs just as easily as programs can!
>  } \QuickQuizEnd
> 
> -\begin{figure}[tbp]
> +\begin{listing}[tbp]
>  { \scriptsize
>  \begin{verbbox}
>    1 atomic_t counter = ATOMIC_INIT(0);
> @@ -261,8 +261,8 @@ accuracies far greater than 50\,\% are almost always necessary.
>  \centering
>  \theverbbox
>  \caption{Just Count Atomically!}
> -\label{fig:count:Just Count Atomically!}
> -\end{figure}
> +\label{lst:count:Just Count Atomically!}
> +\end{listing}
> 
>  \begin{figure}[tb]
>  \centering
> @@ -273,7 +273,7 @@ accuracies far greater than 50\,\% are almost always necessary.
> 
>  The straightforward way to count accurately is to use atomic operations,
>  as shown in
> -Figure~\ref{fig:count:Just Count Atomically!} (\path{count_atomic.c}).
> +Listing~\ref{lst:count:Just Count Atomically!} (\path{count_atomic.c}).
>  Line~1 defines an atomic variable, line~5 atomically increments it, and
>  line~10 reads it out.
>  Because this is atomic, it keeps perfect count.
> @@ -491,7 +491,7 @@ thread (presumably cache aligned and padded to avoid false sharing).
>  	Section~\ref{sec:count:Per-Thread-Variable-Based Implementation}.
>  } \QuickQuizEnd
> 
> -\begin{figure}[tbp]
> +\begin{listing}[tbp]
>  { \scriptsize
>  \begin{verbbox}
>    1 DEFINE_PER_THREAD(long, counter);
> @@ -515,11 +515,11 @@ thread (presumably cache aligned and padded to avoid false sharing).
>  \centering
>  \theverbbox
>  \caption{Array-Based Per-Thread Statistical Counters}
> -\label{fig:count:Array-Based Per-Thread Statistical Counters}
> -\end{figure}
> +\label{lst:count:Array-Based Per-Thread Statistical Counters}
> +\end{listing}
> 
>  Such an array can be wrapped into per-thread primitives, as shown in
> -Figure~\ref{fig:count:Array-Based Per-Thread Statistical Counters}
> +Listing~\ref{lst:count:Array-Based Per-Thread Statistical Counters}
>  (\path{count_stat.c}).
>  Line~1 defines an array containing a set of per-thread counters of
>  type \co{long} named, creatively enough, \co{counter}.
> @@ -559,7 +559,7 @@ normal loads suffice, and no special atomic instructions are required.
> 
>  \QuickQuiz{}
>  	How does the per-thread \co{counter} variable in
> -	Figure~\ref{fig:count:Array-Based Per-Thread Statistical Counters}
> +	Listing~\ref{lst:count:Array-Based Per-Thread Statistical Counters}
>  	get initialized?
>  \QuickQuizAnswer{
>  	The C standard specifies that the initial value of
> @@ -573,7 +573,7 @@ normal loads suffice, and no special atomic instructions are required.
> 
>  \QuickQuiz{}
>  	How is the code in
> -	Figure~\ref{fig:count:Array-Based Per-Thread Statistical Counters}
> +	Listing~\ref{lst:count:Array-Based Per-Thread Statistical Counters}
>  	supposed to permit more than one counter?
>  \QuickQuizAnswer{
>  	Indeed, this toy example does not support more than one counter.
> @@ -602,7 +602,7 @@ at the beginning of this chapter.
>  	and during that time, the counter could well be changing.
>  	This means that the value returned by
>  	\co{read_count()} in
> -	Figure~\ref{fig:count:Array-Based Per-Thread Statistical Counters}
> +	Listing~\ref{lst:count:Array-Based Per-Thread Statistical Counters}
>  	will not necessarily be exact.
>  	Assume that the counter is being incremented at rate
>  	$r$ counts per unit time, and that \co{read_count()}'s
> @@ -743,7 +743,7 @@ date, however, once updates cease, the global counter will eventually
>  converge on the true value---hence this approach qualifies as
>  eventually consistent.
> 
> -\begin{figure}[tbp]
> +\begin{listing}[tbp]
>  { \scriptsize
>  \begin{verbbox}
>   1 DEFINE_PER_THREAD(unsigned long, counter);
> @@ -802,11 +802,11 @@ eventually consistent.
>  \centering
>  \theverbbox
>  \caption{Array-Based Per-Thread Eventually Consistent Counters}
> -\label{fig:count:Array-Based Per-Thread Eventually Consistent Counters}
> -\end{figure}
> +\label{lst:count:Array-Based Per-Thread Eventually Consistent Counters}
> +\end{listing}
> 
>  The implementation is shown in
> -Figure~\ref{fig:count:Array-Based Per-Thread Eventually Consistent Counters}
> +Listing~\ref{lst:count:Array-Based Per-Thread Eventually Consistent Counters}
>  (\path{count_stat_eventual.c}).
>  Lines~1-2 show the per-thread variable and the global variable that
>  track the counter's value, and line three shows \co{stopflag}
> @@ -814,7 +814,7 @@ which is used to coordinate termination (for the case where we want
>  to terminate the program with an accurate counter value).
>  The \co{inc_count()} function shown on lines~5-9 is similar to its
>  counterpart in
> -Figure~\ref{fig:count:Array-Based Per-Thread Statistical Counters}.
> +Listing~\ref{lst:count:Array-Based Per-Thread Statistical Counters}.
>  The \co{read_count()} function shown on lines~11-14 simply returns the
>  value of the \co{global_count} variable.
> 
> @@ -834,7 +834,7 @@ comes at the cost of the additional thread running \co{eventual()}.
> 
>  \QuickQuiz{}
>  	Why doesn't \co{inc_count()} in
> -	Figure~\ref{fig:count:Array-Based Per-Thread Eventually Consistent Counters}
> +	Listing~\ref{lst:count:Array-Based Per-Thread Eventually Consistent Counters}
>  	need to use atomic instructions?
>  	After all, we now have multiple threads accessing the per-thread
>  	counters!
> @@ -872,7 +872,7 @@ comes at the cost of the additional thread running \co{eventual()}.
> 
>  \QuickQuiz{}
>  	Won't the single global thread in the function \co{eventual()} of
> -	Figure~\ref{fig:count:Array-Based Per-Thread Eventually Consistent Counters}
> +	Listing~\ref{lst:count:Array-Based Per-Thread Eventually Consistent Counters}
>  	be just as severe a bottleneck as a global lock would be?
>  \QuickQuizAnswer{
>  	In this case, no.
> @@ -883,7 +883,7 @@ comes at the cost of the additional thread running \co{eventual()}.
> 
>  \QuickQuiz{}
>  	Won't the estimate returned by \co{read_count()} in
> -	Figure~\ref{fig:count:Array-Based Per-Thread Eventually Consistent Counters}
> +	Listing~\ref{lst:count:Array-Based Per-Thread Eventually Consistent Counters}
>  	become increasingly
>  	inaccurate as the number of threads rises?
>  \QuickQuizAnswer{
> @@ -897,7 +897,7 @@ comes at the cost of the additional thread running \co{eventual()}.
> 
>  \QuickQuiz{}
>  	Given that in the eventually\-/consistent algorithm shown in
> -	Figure~\ref{fig:count:Array-Based Per-Thread Eventually Consistent Counters}
> +	Listing~\ref{lst:count:Array-Based Per-Thread Eventually Consistent Counters}
>  	both reads and updates have extremely low overhead
>  	and are extremely scalable, why would anyone bother with the
>  	implementation described in
> @@ -934,7 +934,7 @@ comes at the cost of the additional thread running \co{eventual()}.
>  \subsection{Per-Thread-Variable-Based Implementation}
>  \label{sec:count:Per-Thread-Variable-Based Implementation}
> 
> -\begin{figure}[tb]
> +\begin{listing}[tb]
>  { \scriptsize
>  \begin{verbbox}
>    1 long __thread counter = 0;
> @@ -984,13 +984,13 @@ comes at the cost of the additional thread running \co{eventual()}.
>  \centering
>  \theverbbox
>  \caption{Per-Thread Statistical Counters}
> -\label{fig:count:Per-Thread Statistical Counters}
> -\end{figure}
> +\label{lst:count:Per-Thread Statistical Counters}
> +\end{listing}
> 
>  Fortunately, \GCC\ provides an \co{__thread} storage class that provides
>  per-thread storage.
>  This can be used as shown in
> -Figure~\ref{fig:count:Per-Thread Statistical Counters} (\path{count_end.c})
> +Listing~\ref{lst:count:Per-Thread Statistical Counters} (\path{count_end.c})
>  to implement
>  a statistical counter that not only scales, but that also incurs little
>  or no performance penalty to incrementers compared to simple non-atomic
> @@ -1058,7 +1058,7 @@ Finally, line~22 returns the sum.
> 
>  \QuickQuiz{}
>  	Doesn't the check for \co{NULL} on line~19 of
> -	Figure~\ref{fig:count:Per-Thread Statistical Counters}
> +	Listing~\ref{lst:count:Per-Thread Statistical Counters}
>  	add extra branch mispredictions?
>  	Why not have a variable set permanently to zero, and point
>  	unused counter-pointers to that variable rather than setting
> @@ -1074,7 +1074,7 @@ Finally, line~22 returns the sum.
>  \QuickQuiz{}
>  	Why on earth do we need something as heavyweight as a \emph{lock}
>  	guarding the summation in the function \co{read_count()} in
> -	Figure~\ref{fig:count:Per-Thread Statistical Counters}?
> +	Listing~\ref{lst:count:Per-Thread Statistical Counters}?
>  \QuickQuizAnswer{
>  	Remember, when a thread exits, its per-thread variables disappear.
>  	Therefore, if we attempt to access a given thread's per-thread
> @@ -1105,7 +1105,7 @@ array to point to its per-thread \co{counter} variable.
>  \QuickQuiz{}
>  	Why on earth do we need to acquire the lock in
>  	\co{count_register_thread()} in
> -	Figure~\ref{fig:count:Per-Thread Statistical Counters}?
> +	Listing~\ref{lst:count:Per-Thread Statistical Counters}?
>  	It is a single properly aligned machine-word store to a location
>  	that no other thread is modifying, so it should be atomic anyway,
>  	right?
> @@ -1150,7 +1150,7 @@ variables vanish when that thread exits.
>  	accessible, even if the corresponding CPU is offline---even
>  	if the corresponding CPU never existed and never will exist.
> 
> -\begin{figure}[tb]
> +\begin{listing}[tb]
>  { \scriptsize
>  \begin{verbbox}
>    1 long __thread counter = 0;
> @@ -1196,12 +1196,12 @@ variables vanish when that thread exits.
>  \centering
>  \theverbbox
>  \caption{Per-Thread Statistical Counters With Lockless Summation}
> -\label{fig:count:Per-Thread Statistical Counters With Lockless Summation}
> -\end{figure}
> +\label{lst:count:Per-Thread Statistical Counters With Lockless Summation}
> +\end{listing}
> 
>  	One workaround is to ensure that each thread continues to exist
>  	until all threads are finished, as shown in
> -	Figure~\ref{fig:count:Per-Thread Statistical Counters With Lockless Summation}
> +	Listing~\ref{lst:count:Per-Thread Statistical Counters With Lockless Summation}
>  	(\path{count_tstat.c}).
>  	Analysis of this code is left as an exercise to the reader,
>  	however, please note that it does not fit well into the
> @@ -1388,7 +1388,7 @@ Section~\ref{sec:SMPdesign:Parallel Fastpath}.
>  \subsection{Simple Limit Counter Implementation}
>  \label{sec:count:Simple Limit Counter Implementation}
> 
> -\begin{figure}[tbp]
> +\begin{listing}[tbp]
>  { \scriptsize
>  \begin{verbbox}
>    1 unsigned long __thread counter = 0;
> @@ -1403,8 +1403,8 @@ Section~\ref{sec:SMPdesign:Parallel Fastpath}.
>  \centering
>  \theverbbox
>  \caption{Simple Limit Counter Variables}
> -\label{fig:count:Simple Limit Counter Variables}
> -\end{figure}
> +\label{lst:count:Simple Limit Counter Variables}
> +\end{listing}
> 
>  \begin{figure}[tb]
>  \centering
> @@ -1413,7 +1413,7 @@ Section~\ref{sec:SMPdesign:Parallel Fastpath}.
>  \label{fig:count:Simple Limit Counter Variable Relationships}
>  \end{figure}
> 
> -Figure~\ref{fig:count:Simple Limit Counter Variables}
> +Listing~\ref{lst:count:Simple Limit Counter Variables}
>  shows both the per-thread and global variables used by this
>  implementation.
>  The per-thread \co{counter} and \co{countermax} variables are the
> @@ -1443,7 +1443,7 @@ spinlock guards all of the global variables, in other words, no thread
>  is permitted to access or modify any of the global variables unless it
>  has acquired \co{gblcnt_mutex}.
> 
> -\begin{figure}[tbp]
> +\begin{listing}[tbp]
>  { \scriptsize
>  \begin{verbbox}
>    1 int add_count(unsigned long delta)
> @@ -1501,17 +1501,17 @@ has acquired \co{gblcnt_mutex}.
>  \centering
>  \theverbbox
>  \caption{Simple Limit Counter Add, Subtract, and Read}
> -\label{fig:count:Simple Limit Counter Add, Subtract, and Read}
> -\end{figure}
> +\label{lst:count:Simple Limit Counter Add, Subtract, and Read}
> +\end{listing}
> 
> -Figure~\ref{fig:count:Simple Limit Counter Add, Subtract, and Read}
> +Listing~\ref{lst:count:Simple Limit Counter Add, Subtract, and Read}
>  shows the \co{add_count()}, \co{sub_count()}, and \co{read_count()}
>  functions (\path{count_lim.c}).
> 
> 
>  \QuickQuiz{}
>  	Why does
> -	Figure~\ref{fig:count:Simple Limit Counter Add, Subtract, and Read}
> +	Listing~\ref{lst:count:Simple Limit Counter Add, Subtract, and Read}
>  	provide \co{add_count()} and \co{sub_count()} instead of the
>  	\co{inc_count()} and \co{dec_count()} interfaces show in
>  	Section~\ref{sec:count:Statistical Counters}?
> @@ -1531,7 +1531,7 @@ references only per-thread variables, and should not incur any cache misses.
> 
>  \QuickQuiz{}
>  	What is with the strange form of the condition on line~3 of
> -	Figure~\ref{fig:count:Simple Limit Counter Add, Subtract, and Read}?
> +	Listing~\ref{lst:count:Simple Limit Counter Add, Subtract, and Read}?
>  	Why not the following more intuitive form of the fastpath?
> 
>  	\vspace{5pt}
> @@ -1552,7 +1552,7 @@ references only per-thread variables, and should not incur any cache misses.
>  	Try the above formulation with \co{counter} equal to 10 and
>  	\co{delta} equal to \co{ULONG_MAX}.
>  	Then try it again with the code shown in
> -	Figure~\ref{fig:count:Simple Limit Counter Add, Subtract, and Read}.
> +	Listing~\ref{lst:count:Simple Limit Counter Add, Subtract, and Read}.
> 
>  	A good understanding of integer overflow will be required for
>  	the rest of this example, so if you have never dealt with
> @@ -1566,7 +1566,7 @@ If the test on line~3 fails, we must access global variables, and thus
>  must acquire \co{gblcnt_mutex} on line~7, which we release on line~11
>  in the failure case or on line~16 in the success case.
>  Line~8 invokes \co{globalize_count()}, shown in
> -Figure~\ref{fig:count:Simple Limit Counter Utility Functions},
> +Listing~\ref{lst:count:Simple Limit Counter Utility Functions},
>  which clears the thread-local variables, adjusting the global variables
>  as needed, thus simplifying global processing.
>  (But don't take \emph{my} word for it, try coding it yourself!)
> @@ -1581,7 +1581,7 @@ returns indicating failure.
>  Otherwise, we take the slowpath.
>  Line~14 adds \co{delta} to \co{globalcount}, and then
>  line~15 invokes \co{balance_count()} (shown in
> -Figure~\ref{fig:count:Simple Limit Counter Utility Functions})
> +Listing~\ref{lst:count:Simple Limit Counter Utility Functions})
>  in order to update both the global and the per-thread variables.
>  This call to \co{balance_count()}
>  will usually set this thread's \co{countermax} to re-enable the fastpath.
> @@ -1592,7 +1592,7 @@ line~17 returns indicating success.
>  \QuickQuiz{}
>  	Why does \co{globalize_count()} zero the per-thread variables,
>  	only to later call \co{balance_count()} to refill them in
> -	Figure~\ref{fig:count:Simple Limit Counter Add, Subtract, and Read}?
> +	Listing~\ref{lst:count:Simple Limit Counter Add, Subtract, and Read}?
>  	Why not just leave the per-thread variables non-zero?
>  \QuickQuizAnswer{
>  	That is in fact what an earlier version of this code did.
> @@ -1616,7 +1616,7 @@ Because the slowpath must access global state, line~26
>  acquires \co{gblcnt_mutex}, which is released either by line~29
>  (in case of failure) or by line~34 (in case of success).
>  Line~27 invokes \co{globalize_count()}, shown in
> -Figure~\ref{fig:count:Simple Limit Counter Utility Functions},
> +Listing~\ref{lst:count:Simple Limit Counter Utility Functions},
>  which again clears the thread-local variables, adjusting the global variables
>  as needed.
>  Line~28 checks to see if the counter can accommodate subtracting
> @@ -1626,7 +1626,7 @@ Line~28 checks to see if the counter can accommodate subtracting
>  \QuickQuiz{}
>  	Given that \co{globalreserve} counted against us in \co{add_count()},
>  	why doesn't it count for us in \co{sub_count()} in
> -	Figure~\ref{fig:count:Simple Limit Counter Add, Subtract, and Read}?
> +	Listing~\ref{lst:count:Simple Limit Counter Add, Subtract, and Read}?
>  \QuickQuizAnswer{
>  	The \co{globalreserve} variable tracks the sum of all threads'
>  	\co{countermax} variables.
> @@ -1641,7 +1641,7 @@ Line~28 checks to see if the counter can accommodate subtracting
> 
>  \QuickQuiz{}
>  	Suppose that one thread invokes \co{add_count()} shown in
> -	Figure~\ref{fig:count:Simple Limit Counter Add, Subtract, and Read},
> +	Listing~\ref{lst:count:Simple Limit Counter Add, Subtract, and Read},
>  	and then another thread invokes \co{sub_count()}.
>  	Won't \co{sub_count()} return failure even though the value of
>  	the counter is non-zero?
> @@ -1658,14 +1658,14 @@ If, on the other hand, line~28 finds that the counter \emph{can}
>  accommodate subtracting \co{delta}, we complete the slowpath.
>  Line~32 does the subtraction and then
>  line~33 invokes \co{balance_count()} (shown in
> -Figure~\ref{fig:count:Simple Limit Counter Utility Functions})
> +Listing~\ref{lst:count:Simple Limit Counter Utility Functions})
>  in order to update both global and per-thread variables
>  (hopefully re-enabling the fastpath).
>  Then line~34 releases \co{gblcnt_mutex}, and line~35 returns success.
> 
>  \QuickQuiz{}
>  	Why have both \co{add_count()} and \co{sub_count()} in
> -	Figure~\ref{fig:count:Simple Limit Counter Add, Subtract, and Read}?
> +	Listing~\ref{lst:count:Simple Limit Counter Add, Subtract, and Read}?
>  	Why not simply pass a negative number to \co{add_count()}?
>  \QuickQuizAnswer{
>  	Given that \co{add_count()} takes an \co{unsigned} \co{long}
> @@ -1686,7 +1686,7 @@ Line~44 initializes local variable \co{sum} to the value of
>  per-thread \co{counter} variables.
>  Line~49 then returns the sum.
> 
> -\begin{figure}[tbp]
> +\begin{listing}[tbp]
>  { \scriptsize
>  \begin{verbbox}
>    1 static void globalize_count(void)
> @@ -1732,13 +1732,13 @@ Line~49 then returns the sum.
>  \centering
>  \theverbbox
>  \caption{Simple Limit Counter Utility Functions}
> -\label{fig:count:Simple Limit Counter Utility Functions}
> -\end{figure}
> +\label{lst:count:Simple Limit Counter Utility Functions}
> +\end{listing}
> 
> -Figure~\ref{fig:count:Simple Limit Counter Utility Functions}
> +Listing~\ref{lst:count:Simple Limit Counter Utility Functions}
>  shows a number of utility functions used by the \co{add_count()},
>  \co{sub_count()}, and \co{read_count()} primitives shown in
> -Figure~\ref{fig:count:Simple Limit Counter Add, Subtract, and Read}.
> +Listing~\ref{lst:count:Simple Limit Counter Add, Subtract, and Read}.
> 
>  Lines~1-7 show \co{globalize_count()}, which zeros the current thread's
>  per-thread counters, adjusting the global variables appropriately.
> @@ -1782,7 +1782,7 @@ Finally, in either case, line~18 makes the corresponding adjustment to
> 
>  \QuickQuiz{}
>  	Why set \co{counter} to \co{countermax / 2} in line~15 of
> -	Figure~\ref{fig:count:Simple Limit Counter Utility Functions}?
> +	Listing~\ref{lst:count:Simple Limit Counter Utility Functions}?
>  	Wouldn't it be simpler to just take \co{countermax} counts?
>  \QuickQuizAnswer{
>  	First, it really is reserving \co{countermax} counts
> @@ -1902,7 +1902,7 @@ This task is undertaken in the next section.
>  \subsection{Approximate Limit Counter Implementation}
>  \label{sec:count:Approximate Limit Counter Implementation}
> 
> -\begin{figure}[tbp]
> +\begin{listing}[tbp]
>  { \scriptsize
>  \begin{verbbox}
>    1 unsigned long __thread counter = 0;
> @@ -1918,10 +1918,10 @@ This task is undertaken in the next section.
>  \centering
>  \theverbbox
>  \caption{Approximate Limit Counter Variables}
> -\label{fig:count:Approximate Limit Counter Variables}
> -\end{figure}
> +\label{lst:count:Approximate Limit Counter Variables}
> +\end{listing}
> 
> -\begin{figure}[tbp]
> +\begin{listing}[tbp]
>  { \scriptsize
>  \begin{verbbox}
>    1 static void balance_count(void)
> @@ -1942,25 +1942,25 @@ This task is undertaken in the next section.
>  \centering
>  \theverbbox
>  \caption{Approximate Limit Counter Balancing}
> -\label{fig:count:Approximate Limit Counter Balancing}
> -\end{figure}
> +\label{lst:count:Approximate Limit Counter Balancing}
> +\end{listing}
> 
>  Because this implementation (\path{count_lim_app.c}) is quite similar to
>  that in the previous section
> -(Figures~\ref{fig:count:Simple Limit Counter Variables},
> -\ref{fig:count:Simple Limit Counter Add, Subtract, and Read}, and
> -\ref{fig:count:Simple Limit Counter Utility Functions}),
> +(Listings~\ref{lst:count:Simple Limit Counter Variables},
> +\ref{lst:count:Simple Limit Counter Add, Subtract, and Read}, and
> +\ref{lst:count:Simple Limit Counter Utility Functions}),
>  only the changes are shown here.
> -Figure~\ref{fig:count:Approximate Limit Counter Variables}
> +Listing~\ref{lst:count:Approximate Limit Counter Variables}
>  is identical to
> -Figure~\ref{fig:count:Simple Limit Counter Variables},
> +Listing~\ref{lst:count:Simple Limit Counter Variables},
>  with the addition of \co{MAX_COUNTERMAX}, which sets the maximum
>  permissible value of the per-thread \co{countermax} variable.
> 
>  Similarly,
> -Figure~\ref{fig:count:Approximate Limit Counter Balancing}
> +Listing~\ref{lst:count:Approximate Limit Counter Balancing}
>  is identical to the \co{balance_count()} function in
> -Figure~\ref{fig:count:Simple Limit Counter Utility Functions},
> +Listing~\ref{lst:count:Simple Limit Counter Utility Functions},
>  with the addition of lines~6 and 7, which enforce the
>  \co{MAX_COUNTERMAX} limit on the per-thread \co{countermax} variable.
> 
> @@ -2038,7 +2038,7 @@ represent \co{counter} and the low-order 16 bits to represent
>  	the reader.
>  } \QuickQuizEnd
> 
> -\begin{figure}[tbp]
> +\begin{listing}[tbp]
>  { \scriptsize
>  \begin{verbbox}
>    1 atomic_t __thread ctrandmax = ATOMIC_INIT(0);
> @@ -2079,12 +2079,12 @@ represent \co{counter} and the low-order 16 bits to represent
>  \centering
>  \theverbbox
>  \caption{Atomic Limit Counter Variables and Access Functions}
> -\label{fig:count:Atomic Limit Counter Variables and Access Functions}
> -\end{figure}
> +\label{lst:count:Atomic Limit Counter Variables and Access Functions}
> +\end{listing}
> 
>  The variables and access functions for a simple atomic limit counter
>  are shown in
> -Figure~\ref{fig:count:Atomic Limit Counter Variables and Access Functions}
> +Listing~\ref{lst:count:Atomic Limit Counter Variables and Access Functions}
>  (\path{count_lim_atomic.c}).
>  The \co{counter} and \co{countermax} variables in earlier algorithms
>  are combined into the single variable \co{ctrandmax} shown on
> @@ -2096,7 +2096,7 @@ representation of \co{int}.
>  Lines~2-6 show the definitions for \co{globalcountmax}, \co{globalcount},
>  \co{globalreserve}, \co{counterp}, and \co{gblcnt_mutex}, all of which
>  take on roles similar to their counterparts in
> -Figure~\ref{fig:count:Approximate Limit Counter Variables}.
> +Listing~\ref{lst:count:Approximate Limit Counter Variables}.
>  Line~7 defines \co{CM_BITS}, which gives the number of bits in each half
>  of \co{ctrandmax}, and line~8 defines \co{MAX_COUNTERMAX}, which
>  gives the maximum value that may be held in either half of
> @@ -2104,7 +2104,7 @@ gives the maximum value that may be held in either half of
> 
>  \QuickQuiz{}
>  	In what way does line~7 of
> -	Figure~\ref{fig:count:Atomic Limit Counter Variables and Access Functions}
> +	Listing~\ref{lst:count:Atomic Limit Counter Variables and Access Functions}
>  	violate the C standard?
>  \QuickQuizAnswer{
>  	It assumes eight bits per byte.
> @@ -2134,7 +2134,7 @@ it on line~24.
>  \QuickQuiz{}
>  	Given that there is only one \co{ctrandmax} variable,
>  	why bother passing in a pointer to it on line~18 of
> -	Figure~\ref{fig:count:Atomic Limit Counter Variables and Access Functions}?
> +	Listing~\ref{lst:count:Atomic Limit Counter Variables and Access Functions}?
>  \QuickQuizAnswer{
>  	There is only one \co{ctrandmax} variable \emph{per thread}.
>  	Later, we will see code that needs to pass other threads'
> @@ -2149,7 +2149,7 @@ the result.
> 
>  \QuickQuiz{}
>  	Why does \co{merge_ctrandmax()} in
> -	Figure~\ref{fig:count:Atomic Limit Counter Variables and Access Functions}
> +	Listing~\ref{lst:count:Atomic Limit Counter Variables and Access Functions}
>  	return an \co{int} rather than storing directly into an
>  	\co{atomic_t}?
>  \QuickQuizAnswer{
> @@ -2157,7 +2157,7 @@ the result.
>  	to the \co{atomic_cmpxchg()} primitive.
>  } \QuickQuizEnd
> 
> -\begin{figure}[tbp]
> +\begin{listing}[tbp]
>  { \scriptsize
>  \begin{verbbox}
>    1 int add_count(unsigned long delta)
> @@ -2228,10 +2228,10 @@ the result.
>  \centering
>  \theverbbox
>  \caption{Atomic Limit Counter Add and Subtract}
> -\label{fig:count:Atomic Limit Counter Add and Subtract}
> -\end{figure}
> +\label{lst:count:Atomic Limit Counter Add and Subtract}
> +\end{listing}
> 
> -Figure~\ref{fig:count:Atomic Limit Counter Add and Subtract}
> +Listing~\ref{lst:count:Atomic Limit Counter Add and Subtract}
>  shows the \co{add_count()} and \co{sub_count()} functions.
> 
>  Lines~1-32 show \co{add_count()}, whose fastpath spans lines~8-15,
> @@ -2256,7 +2256,7 @@ execution continues in the loop at line~9.
>  \QuickQuiz{}
>  	Yecch!
>  	Why the ugly \co{goto} on line~11 of
> -	Figure~\ref{fig:count:Atomic Limit Counter Add and Subtract}?
> +	Listing~\ref{lst:count:Atomic Limit Counter Add and Subtract}?
>  	Haven't you heard of the \co{break} statement???
>  \QuickQuizAnswer{
>  	Replacing the \co{goto} with a \co{break} would require keeping
> @@ -2271,20 +2271,20 @@ execution continues in the loop at line~9.
> 
>  \QuickQuiz{}
>  	Why would the \co{atomic_cmpxchg()} primitive at lines~13-14 of
> -	Figure~\ref{fig:count:Atomic Limit Counter Add and Subtract}
> +	Listing~\ref{lst:count:Atomic Limit Counter Add and Subtract}
>  	ever fail?
>  	After all, we picked up its old value on line~9 and have not
>  	changed it!
>  \QuickQuizAnswer{
>  	Later, we will see how the \co{flush_local_count()} function in
> -	Figure~\ref{fig:count:Atomic Limit Counter Utility Functions 1}
> +	Listing~\ref{lst:count:Atomic Limit Counter Utility Functions 1}
>  	might update this thread's \co{ctrandmax} variable concurrently
>  	with the execution of the fastpath on lines~8-14 of
> -	Figure~\ref{fig:count:Atomic Limit Counter Add and Subtract}.
> +	Listing~\ref{lst:count:Atomic Limit Counter Add and Subtract}.
>  } \QuickQuizEnd
> 
>  Lines~16-31 of
> -Figure~\ref{fig:count:Atomic Limit Counter Add and Subtract}
> +Listing~\ref{lst:count:Atomic Limit Counter Add and Subtract}
>  show \co{add_count()}'s slowpath, which is protected by \co{gblcnt_mutex},
>  which is acquired on line~17 and released on lines~24 and 30.
>  Line~18 invokes \co{globalize_count()}, which moves this thread's
> @@ -2304,14 +2304,14 @@ spreads counts to the local state if appropriate, line~30 releases
>  returns success.
> 
>  Lines~34-63 of
> -Figure~\ref{fig:count:Atomic Limit Counter Add and Subtract}
> +Listing~\ref{lst:count:Atomic Limit Counter Add and Subtract}
>  show \co{sub_count()}, which is structured similarly to
>  \co{add_count()}, having a fastpath on lines~41-48 and a slowpath on
>  lines~49-62.
>  A line-by-line analysis of this function is left as an exercise to
>  the reader.
> 
> -\begin{figure}[tbp]
> +\begin{listing}[tbp]
>  { \scriptsize
>  \begin{verbbox}
>    1 unsigned long read_count(void)
> @@ -2337,10 +2337,10 @@ the reader.
>  \centering
>  \theverbbox
>  \caption{Atomic Limit Counter Read}
> -\label{fig:count:Atomic Limit Counter Read}
> -\end{figure}
> +\label{lst:count:Atomic Limit Counter Read}
> +\end{listing}
> 
> -Figure~\ref{fig:count:Atomic Limit Counter Read} shows \co{read_count()}.
> +Listing~\ref{lst:count:Atomic Limit Counter Read} shows \co{read_count()}.
>  Line~9 acquires \co{gblcnt_mutex} and line~16 releases it.
>  Line~10 initializes local variable \co{sum} to the value of
>  \co{globalcount}, and the loop spanning lines~11-15 adds the
> @@ -2348,7 +2348,7 @@ per-thread counters to this sum, isolating each per-thread counter
>  using \co{split_ctrandmax} on line~13.
>  Finally, line~17 returns the sum.
> 
> -\begin{figure}[tbp]
> +\begin{listing}[tbp]
>  { \scriptsize
>  \begin{verbbox}
>    1 static void globalize_count(void)
> @@ -2388,10 +2388,10 @@ Finally, line~17 returns the sum.
>  \centering
>  \theverbbox
>  \caption{Atomic Limit Counter Utility Functions 1}
> -\label{fig:count:Atomic Limit Counter Utility Functions 1}
> -\end{figure}
> +\label{lst:count:Atomic Limit Counter Utility Functions 1}
> +\end{listing}
> 
> -\begin{figure}[tb]
> +\begin{listing}[tb]
>  { \scriptsize
>  \begin{verbbox}
>    1 static void balance_count(void)
> @@ -2440,11 +2440,11 @@ Finally, line~17 returns the sum.
>  \centering
>  \theverbbox
>  \caption{Atomic Limit Counter Utility Functions 2}
> -\label{fig:count:Atomic Limit Counter Utility Functions 2}
> -\end{figure}
> +\label{lst:count:Atomic Limit Counter Utility Functions 2}
> +\end{listing}
> 
> -Figures~\ref{fig:count:Atomic Limit Counter Utility Functions 1}
> -and~\ref{fig:count:Atomic Limit Counter Utility Functions 2}
> +Listings~\ref{lst:count:Atomic Limit Counter Utility Functions 1}
> +and~\ref{lst:count:Atomic Limit Counter Utility Functions 2}
>  shows the utility functions
>  \co{globalize_count()},
>  \co{flush_local_count()},
> @@ -2452,7 +2452,7 @@ shows the utility functions
>  \co{count_register_thread()}, and
>  \co{count_unregister_thread()}.
>  The code for \co{globalize_count()} is shown on lines~1-12,
> -of Figure~\ref{fig:count:Atomic Limit Counter Utility Functions 1} and
> +of Listing~\ref{lst:count:Atomic Limit Counter Utility Functions 1} and
>  is similar to that of previous algorithms, with the addition of
>  line~7, which is now required to split out \co{counter} and
>  \co{countermax} from \co{ctrandmax}.
> @@ -2477,7 +2477,7 @@ line~30 subtracts this thread's \co{countermax} from \co{globalreserve}.
>  	What stops a thread from simply refilling its
>  	\co{ctrandmax} variable immediately after
>  	\co{flush_local_count()} on line~14 of
> -	Figure~\ref{fig:count:Atomic Limit Counter Utility Functions 1}
> +	Listing~\ref{lst:count:Atomic Limit Counter Utility Functions 1}
>  	empties it?
>  \QuickQuizAnswer{
>  	This other thread cannot refill its \co{ctrandmax}
> @@ -2494,7 +2494,7 @@ line~30 subtracts this thread's \co{countermax} from \co{globalreserve}.
>  	\co{add_count()} or \co{sub_count()} from interfering with
>  	the \co{ctrandmax} variable while
>  	\co{flush_local_count()} is accessing it on line~27 of
> -	Figure~\ref{fig:count:Atomic Limit Counter Utility Functions 1}
> +	Listing~\ref{lst:count:Atomic Limit Counter Utility Functions 1}
>  	empties it?
>  \QuickQuizAnswer{
>  	Nothing.
> @@ -2520,7 +2520,7 @@ line~30 subtracts this thread's \co{countermax} from \co{globalreserve}.
>  } \QuickQuizEnd
> 
>  Lines~1-22 on
> -Figure~\ref{fig:count:Atomic Limit Counter Utility Functions 2}
> +Listing~\ref{lst:count:Atomic Limit Counter Utility Functions 2}
>  show the code for \co{balance_count()}, which refills
>  the calling thread's local \co{ctrandmax} variable.
>  This function is quite similar to that of the preceding algorithms,
> @@ -2534,7 +2534,7 @@ line~33.
>  	Given that the \co{atomic_set()} primitive does a simple
>  	store to the specified \co{atomic_t}, how can line~21 of
>  	\co{balance_count()} in
> -	Figure~\ref{fig:count:Atomic Limit Counter Utility Functions 2}
> +	Listing~\ref{lst:count:Atomic Limit Counter Utility Functions 2}
>  	work correctly in face of concurrent \co{flush_local_count()}
>  	updates to this variable?
>  \QuickQuizAnswer{
> @@ -2668,7 +2668,7 @@ The slowpath then sets that thread's \co{theft} state to IDLE.
>  \subsection{Signal-Theft Limit Counter Implementation}
>  \label{sec:count:Signal-Theft Limit Counter Implementation}
> 
> -\begin{figure}[tbp]
> +\begin{listing}[tbp]
>  { \scriptsize
>  \begin{verbbox}
>    1 #define THEFT_IDLE  0
> @@ -2693,10 +2693,10 @@ The slowpath then sets that thread's \co{theft} state to IDLE.
>  \centering
>  \theverbbox
>  \caption{Signal-Theft Limit Counter Data}
> -\label{fig:count:Signal-Theft Limit Counter Data}
> -\end{figure}
> +\label{lst:count:Signal-Theft Limit Counter Data}
> +\end{listing}
> 
> -Figure~\ref{fig:count:Signal-Theft Limit Counter Data}
> +Listing~\ref{lst:count:Signal-Theft Limit Counter Data}
>  (\path{count_lim_sig.c})
>  shows the data structures used by the signal-theft based counter
>  implementation.
> @@ -2706,7 +2706,7 @@ Lines~8-17 are similar to earlier implementations, with the addition of
>  lines~14 and 15 to allow remote access to a thread's \co{countermax}
>  and \co{theft} variables, respectively.
> 
> -\begin{figure}[tbp]
> +\begin{listing}[tbp]
>  { \scriptsize
>  \begin{verbbox}
>    1 static void globalize_count(void)
> @@ -2777,10 +2777,10 @@ and \co{theft} variables, respectively.
>  \centering
>  \theverbbox
>  \caption{Signal-Theft Limit Counter Value-Migration Functions}
> -\label{fig:count:Signal-Theft Limit Counter Value-Migration Functions}
> -\end{figure}
> +\label{lst:count:Signal-Theft Limit Counter Value-Migration Functions}
> +\end{listing}
> 
> -Figure~\ref{fig:count:Signal-Theft Limit Counter Value-Migration Functions}
> +Listing~\ref{lst:count:Signal-Theft Limit Counter Value-Migration Functions}
>  shows the functions responsible for migrating counts between per-thread
>  variables and the global variables.
>  Lines~1-7 shows \co{globalize_count()}, which is identical to earlier
> @@ -2796,7 +2796,7 @@ this thread's fastpaths are not running, line~16 sets the \co{theft}
>  state to READY.
> 
>  \QuickQuiz{}
> -	In Figure~\ref{fig:count:Signal-Theft Limit Counter Value-Migration Functions}
> +	In Listing~\ref{lst:count:Signal-Theft Limit Counter Value-Migration Functions}
>  	function \co{flush_local_count_sig()}, why are there
>  	\co{ACCESS_ONCE()} wrappers around the uses of the
>  	\co{theft} per-thread variable?
> @@ -2835,7 +2835,7 @@ Otherwise, line~32 sets the thread's \co{theft} state to REQ and
>  line~33 sends the thread a signal.
> 
>  \QuickQuiz{}
> -	In Figure~\ref{fig:count:Signal-Theft Limit Counter Value-Migration Functions},
> +	In Listing~\ref{lst:count:Signal-Theft Limit Counter Value-Migration Functions},
>  	why is it safe for line~28 to directly access the other thread's
>  	\co{countermax} variable?
>  \QuickQuizAnswer{
> @@ -2849,7 +2849,7 @@ line~33 sends the thread a signal.
>  } \QuickQuizEnd
> 
>  \QuickQuiz{}
> -	In Figure~\ref{fig:count:Signal-Theft Limit Counter Value-Migration Functions},
> +	In Listing~\ref{lst:count:Signal-Theft Limit Counter Value-Migration Functions},
>  	why doesn't line~33 check for the current thread sending itself
>  	a signal?
>  \QuickQuizAnswer{
> @@ -2861,7 +2861,7 @@ line~33 sends the thread a signal.
> 
>  \QuickQuiz{}
>  	The code in
> -	Figure~\ref{fig:count:Signal-Theft Limit Counter Value-Migration Functions},
> +	Listing~\ref{lst:count:Signal-Theft Limit Counter Value-Migration Functions},
>  	works with \GCC\ and POSIX.
>  	What would be required to make it also conform to the ISO C standard?
>  \QuickQuizAnswer{
> @@ -2882,7 +2882,7 @@ READY, so lines~43-46 do the thieving.
>  Line~47 then sets the thread's \co{theft} state back to IDLE.
> 
>  \QuickQuiz{}
> -	In Figure~\ref{fig:count:Signal-Theft Limit Counter Value-Migration Functions}, why does line~41 resend the signal?
> +	In Listing~\ref{lst:count:Signal-Theft Limit Counter Value-Migration Functions}, why does line~41 resend the signal?
>  \QuickQuizAnswer{
>  	Because many operating systems over several decades have
>  	had the property of losing the occasional signal.
> @@ -2897,7 +2897,7 @@ Line~47 then sets the thread's \co{theft} state back to IDLE.
>  Lines~51-63 show \co{balance_count()}, which is similar to that of
>  earlier examples.
> 
> -\begin{figure}[tbp]
> +\begin{listing}[tbp]
>  { \scriptsize
>  \begin{verbbox}
>    1 int add_count(unsigned long delta)
> @@ -2941,10 +2941,10 @@ earlier examples.
>  \centering
>  \theverbbox
>  \caption{Signal-Theft Limit Counter Add Function}
> -\label{fig:count:Signal-Theft Limit Counter Add Function}
> -\end{figure}
> +\label{lst:count:Signal-Theft Limit Counter Add Function}
> +\end{listing}
> 
> -\begin{figure}[tb]
> +\begin{listing}[tb]
>  { \scriptsize
>  \begin{verbbox}
>   38 int sub_count(unsigned long delta)
> @@ -2986,10 +2986,10 @@ earlier examples.
>  \centering
>  \theverbbox
>  \caption{Signal-Theft Limit Counter Subtract Function}
> -\label{fig:count:Signal-Theft Limit Counter Subtract Function}
> -\end{figure}
> +\label{lst:count:Signal-Theft Limit Counter Subtract Function}
> +\end{listing}
> 
> -Figure~\ref{fig:count:Signal-Theft Limit Counter Add Function}
> +Listing~\ref{lst:count:Signal-Theft Limit Counter Add Function}
>  shows the \co{add_count()} function.
>  The fastpath spans lines~5-20, and the slowpath lines~21-35.
>  Line~5 sets the per-thread \co{counting} variable to 1 so that
> @@ -3014,7 +3014,7 @@ READY also sees the effects of line~9.
>  If the fastpath addition at line~9 was executed, then line~20 returns
>  success.
> 
> -\begin{figure}[tbp]
> +\begin{listing}[tbp]
>  { \scriptsize
>  \begin{verbbox}
>    1 unsigned long read_count(void)
> @@ -3035,21 +3035,21 @@ success.
>  \centering
>  \theverbbox
>  \caption{Signal-Theft Limit Counter Read Function}
> -\label{fig:count:Signal-Theft Limit Counter Read Function}
> -\end{figure}
> +\label{lst:count:Signal-Theft Limit Counter Read Function}
> +\end{listing}
> 
>  Otherwise, we fall through to the slowpath starting at line~21.
>  The structure of the slowpath is similar to those of earlier examples,
>  so its analysis is left as an exercise to the reader.
>  Similarly, the structure of \co{sub_count()} on
> -Figure~\ref{fig:count:Signal-Theft Limit Counter Subtract Function}
> +Listing~\ref{lst:count:Signal-Theft Limit Counter Subtract Function}
>  is the same
>  as that of \co{add_count()}, so the analysis of \co{sub_count()} is also
>  left as an exercise for the reader, as is the analysis of
>  \co{read_count()} in
> -Figure~\ref{fig:count:Signal-Theft Limit Counter Read Function}.
> +Listing~\ref{lst:count:Signal-Theft Limit Counter Read Function}.
> 
> -\begin{figure}[tbp]
> +\begin{listing}[tbp]
>  { \scriptsize
>  \begin{verbbox}
>    1 void count_init(void)
> @@ -3092,11 +3092,11 @@ Figure~\ref{fig:count:Signal-Theft Limit Counter Read Function}.
>  \centering
>  \theverbbox
>  \caption{Signal-Theft Limit Counter Initialization Functions}
> -\label{fig:count:Signal-Theft Limit Counter Initialization Functions}
> -\end{figure}
> +\label{lst:count:Signal-Theft Limit Counter Initialization Functions}
> +\end{listing}
> 
>  Lines~1-12 of
> -Figure~\ref{fig:count:Signal-Theft Limit Counter Initialization Functions}
> +Listing~\ref{lst:count:Signal-Theft Limit Counter Initialization Functions}
>  show \co{count_init()}, which set up \co{flush_local_count_sig()}
>  as the signal handler for \co{SIGUSR1},
>  enabling the \co{pthread_kill()} calls in \co{flush_local_count()}
> @@ -3414,7 +3414,7 @@ courtesy of eventual consistency.
>  \label{tab:count:Limit Counter Performance on Power-6}
>  \end{table*}
> 
> -Figure~\ref{tab:count:Limit Counter Performance on Power-6}
> +Table~\ref{tab:count:Limit Counter Performance on Power-6}
>  shows the performance of the parallel limit-counting algorithms.
>  Exact enforcement of the limits incurs a substantial performance
>  penalty, although on this 4.7\,GHz \Power{6} system that penalty can be reduced
> diff --git a/defer/rcuexercises.tex b/defer/rcuexercises.tex
> index 1d9e138..21d9683 100644
> --- a/defer/rcuexercises.tex
> +++ b/defer/rcuexercises.tex
> @@ -14,7 +14,7 @@ suffice for most of these exercises.
> 
>  \QuickQuiz{}
>  	The statistical-counter implementation shown in
> -	Figure~\ref{fig:count:Per-Thread Statistical Counters}
> +	Listing~\ref{lst:count:Per-Thread Statistical Counters}
>  	(\path{count_end.c})
>  	used a global lock to guard the summation in \co{read_count()},
>  	which resulted in poor performance and negative scalability.
> diff --git a/howto/howto.tex b/howto/howto.tex
> index 90abb14..1a0b75c 100644
> --- a/howto/howto.tex
> +++ b/howto/howto.tex
> @@ -361,7 +361,7 @@ Other types of systems have well-known ways of locating files by filename.
>  \section{Whose Book Is This?}
>  \label{sec:howto:Whose Book Is This?}
> 
> -\begin{figure*}[tbp]
> +\begin{listing*}[tbp]
>  {
>  \scriptsize
>  \begin{verbbox}
> @@ -376,10 +376,10 @@ Other types of systems have well-known ways of locating files by filename.
>  }
>  \hspace*{1in}\OneColumnHSpace{-0.5in}\theverbbox
>  \caption{Creating an Up-To-Date PDF}
> -\label{fig:howto:Creating a Up-To-Date PDF}
> -\end{figure*}
> +\label{lst:howto:Creating a Up-To-Date PDF}
> +\end{listing*}
> 
> -\begin{figure*}[tbp]
> +\begin{listing*}[tbp]
>  {
>  \scriptsize
>  \begin{verbbox}
> @@ -393,8 +393,8 @@ Other types of systems have well-known ways of locating files by filename.
>  }
>  \hspace*{1in}\OneColumnHSpace{-0.5in}\theverbbox
>  \caption{Generating an Updated PDF}
> -\label{fig:howto:Generating an Updated PDF}
> -\end{figure*}
> +\label{lst:howto:Generating an Updated PDF}
> +\end{listing*}
> 
>  As the cover says, the editor is one Paul E.~McKenney.
>  However, the editor does accept contributions via the
> @@ -416,18 +416,18 @@ in the file \path{FAQ-BUILD.txt} in the \LaTeX{} source to the book.
> 
>  To create and display a current \LaTeX{} source tree of this book,
>  use the list of Linux commands shown in
> -Figure~\ref{fig:howto:Creating a Up-To-Date PDF}.
> +Listing~\ref{lst:howto:Creating a Up-To-Date PDF}.
>  In some environments, the \co{evince} command that displays \path{perfbook.pdf}
>  may need to be replaced, for example, with \co{acroread}.
>  The \co{git clone} command need only be used the first time you
>  create a PDF, subsequently, you can run the commands shown in
> -Figure~\ref{fig:howto:Generating an Updated PDF} to pull in any updates
> +Listing~\ref{lst:howto:Generating an Updated PDF} to pull in any updates
>  and generate an updated PDF.
>  The commands in
> -Figure~\ref{fig:howto:Generating an Updated PDF}
> +Listing~\ref{lst:howto:Generating an Updated PDF}
>  must be run within the \path{perfbook} directory created by the commands
>  shown in
> -Figure~\ref{fig:howto:Creating a Up-To-Date PDF}.
> +Listing~\ref{lst:howto:Creating a Up-To-Date PDF}.
> 
>  PDFs of this book are sporadically posted at
>  \url{http://kernel.org/pub/linux/kernel/people/paulmck/perfbook/perfbook.html}
> diff --git a/owned/owned.tex b/owned/owned.tex
> index f74b5d6..d584e82 100644
> --- a/owned/owned.tex
> +++ b/owned/owned.tex
> @@ -132,8 +132,8 @@ is obviously quite attractive.
>  } \QuickQuizEnd
> 
>  This same pattern can be written in C as well as in \co{sh}, as illustrated by
> -Figures~\ref{fig:toolsoftrade:Using the fork() Primitive}
> -and~\ref{fig:toolsoftrade:Using the wait() Primitive}.
> +Listings~\ref{lst:toolsoftrade:Using the fork() Primitive}
> +and~\ref{lst:toolsoftrade:Using the wait() Primitive}.
> 
>  The next section discusses use of data ownership in shared-memory
>  parallel programs.
> @@ -150,8 +150,8 @@ of ownership and access rights.
> 
>  For example, consider the per-thread statistical counter implementation
>  shown in
> -Figure~\ref{fig:count:Per-Thread Statistical Counters} on
> -page~\pageref{fig:count:Per-Thread Statistical Counters}.
> +Listing~\ref{lst:count:Per-Thread Statistical Counters} on
> +page~\pageref{lst:count:Per-Thread Statistical Counters}.
>  Here, \co{inc_count()} updates only the corresponding thread's
>  instance of \co{counter},
>  while \co{read_count()} accesses, but does not modify, all
> @@ -195,9 +195,9 @@ beginning on
>  page~\pageref{sec:count:Signal-Theft Limit Counter Design},
>  in particular the \co{flush_local_count_sig()} and
>  \co{flush_local_count()} functions in
> -Figure~\ref{fig:count:Signal-Theft Limit Counter Value-Migration Functions}
> +Listing~\ref{lst:count:Signal-Theft Limit Counter Value-Migration Functions}
>  on
> -page~\pageref{fig:count:Signal-Theft Limit Counter Value-Migration Functions}.
> +page~\pageref{lst:count:Signal-Theft Limit Counter Value-Migration Functions}.
> 
>  The \co{flush_local_count_sig()} function is a signal handler that
>  acts as the shipped function.
> @@ -207,12 +207,12 @@ the shipped function executes.
>  This shipped function has the not-unusual added complication of
>  needing to interact with any concurrently executing \co{add_count()}
>  or \co{sub_count()} functions (see
> -Figure~\ref{fig:count:Signal-Theft Limit Counter Add Function}
> +Listing~\ref{lst:count:Signal-Theft Limit Counter Add Function}
>  on
> -page~\pageref{fig:count:Signal-Theft Limit Counter Add Function} and
> -Figure~\ref{fig:count:Signal-Theft Limit Counter Subtract Function}
> +page~\pageref{lst:count:Signal-Theft Limit Counter Add Function} and
> +Listing~\ref{lst:count:Signal-Theft Limit Counter Subtract Function}
>  on
> -page~\pageref{fig:count:Signal-Theft Limit Counter Subtract Function}).
> +page~\pageref{lst:count:Signal-Theft Limit Counter Subtract Function}).
> 
>  \QuickQuiz{}
>  	What mechanisms other than POSIX signals may be used for function
> @@ -246,7 +246,7 @@ The eventually consistent counter implementation described in
>  Section~\ref{sec:count:Eventually Consistent Implementation} provides an example.
>  This implementation has a designated thread that runs the
>  \co{eventual()} function shown on lines~15-32 of
> -Figure~\ref{fig:count:Array-Based Per-Thread Eventually Consistent Counters}.
> +Listing~\ref{lst:count:Array-Based Per-Thread Eventually Consistent Counters}.
>  This \co{eventual()} thread periodically pulls the per-thread counts
>  into the global counter, so that accesses to the global counter will,
>  as the name says, eventually converge on the actual value.
> @@ -254,7 +254,7 @@ as the name says, eventually converge on the actual value.
>  \QuickQuiz{}
>  	But none of the data in the \co{eventual()} function shown on
>  	lines~15-32 of
> -	Figure~\ref{fig:count:Array-Based Per-Thread Eventually Consistent Counters}
> +	Listing~\ref{lst:count:Array-Based Per-Thread Eventually Consistent Counters}
>  	is actually owned by the \co{eventual()} thread!
>  	In just what way is this data ownership???
>  \QuickQuizAnswer{
> @@ -298,8 +298,8 @@ a considerable reduction in the spread of certain types of disease.
> 
>  In other cases, privatization imposes costs.
>  For example, consider the simple limit counter shown in
> -Figure~\ref{fig:count:Simple Limit Counter Add, Subtract, and Read} on
> -page~\pageref{fig:count:Simple Limit Counter Add, Subtract, and Read}.
> +Listing~\ref{lst:count:Simple Limit Counter Add, Subtract, and Read} on
> +page~\pageref{lst:count:Simple Limit Counter Add, Subtract, and Read}.
>  This is an example of an algorithm where threads can read each others'
>  data, but are only permitted to update their own data.
>  A quick review of the algorithm shows that the only cross-thread
> diff --git a/together/applyrcu.tex b/together/applyrcu.tex
> index e3d6f0d..d477ab5 100644
> --- a/together/applyrcu.tex
> +++ b/together/applyrcu.tex
> @@ -21,8 +21,8 @@ Unfortunately, threads needing to read out the value via \co{read_count()}
>  were required to acquire a global
>  lock, and thus incurred high overhead and suffered poor scalability.
>  The code for the lock-based implementation is shown in
> -Figure~\ref{fig:count:Per-Thread Statistical Counters} on
> -Page~\pageref{fig:count:Per-Thread Statistical Counters}.
> +Listing~\ref{lst:count:Per-Thread Statistical Counters} on
> +Page~\pageref{lst:count:Per-Thread Statistical Counters}.
> 
>  \QuickQuiz{}
>  	Why on earth did we need that global lock in the first place?
> @@ -56,8 +56,8 @@ execution.
>  	Just what is the accuracy of \co{read_count()}, anyway?
>  \QuickQuizAnswer{
>  	Refer to
> -	Figure~\ref{fig:count:Per-Thread Statistical Counters} on
> -	Page~\pageref{fig:count:Per-Thread Statistical Counters}.
> +	Listing~\ref{lst:count:Per-Thread Statistical Counters} on
> +	Page~\pageref{lst:count:Per-Thread Statistical Counters}.
>  	Clearly, if there are no concurrent invocations of \co{inc_count()},
>  	\co{read_count()} will return an exact result.
>  	However, if there \emph{are} concurrent invocations of
> @@ -205,7 +205,7 @@ the current \co{countarray} structure, and
>  the \co{final_mutex} spinlock.
> 
>  Lines~10-13 show \co{inc_count()}, which is unchanged from
> -Figure~\ref{fig:count:Per-Thread Statistical Counters}.
> +Listing~\ref{lst:count:Per-Thread Statistical Counters}.
> 
>  Lines~15-29 show \co{read_count()}, which has changed significantly.
>  Lines~21 and~27 substitute \co{rcu_read_lock()} and
> @@ -280,13 +280,13 @@ Line~69 can then safely free the old \co{countarray} structure.
>  	Wow!
>  	Figure~\ref{fig:together:RCU and Per-Thread Statistical Counters}
>  	contains 69 lines of code, compared to only 42 in
> -	Figure~\ref{fig:count:Per-Thread Statistical Counters}.
> +	Listing~\ref{lst:count:Per-Thread Statistical Counters}.
>  	Is this extra complexity really worth it?
>  \QuickQuizAnswer{
>  	This of course needs to be decided on a case-by-case basis.
>  	If you need an implementation of \co{read_count()} that
>  	scales linearly, then the lock-based implementation shown in
> -	Figure~\ref{fig:count:Per-Thread Statistical Counters}
> +	Listing~\ref{lst:count:Per-Thread Statistical Counters}
>  	simply will not work for you.
>  	On the other hand, if calls to \co{count_read()} are sufficiently
>  	rare, then the lock-based version is simpler and might thus be
> @@ -300,7 +300,7 @@ Line~69 can then safely free the old \co{countarray} structure.
>  	and the use of RCU unnecessary.
>  	This would in turn enable an implementation that
>  	was even simpler than the one shown in
> -	Figure~\ref{fig:count:Per-Thread Statistical Counters}, but
> +	Listing~\ref{lst:count:Per-Thread Statistical Counters}, but
>  	with all the scalability and performance benefits of the
>  	implementation shown in
>  	Figure~\ref{fig:together:RCU and Per-Thread Statistical Counters}!
> diff --git a/toolsoftrade/toolsoftrade.tex b/toolsoftrade/toolsoftrade.tex
> index bd43879..b18d3d0 100644
> --- a/toolsoftrade/toolsoftrade.tex
> +++ b/toolsoftrade/toolsoftrade.tex
> @@ -189,7 +189,7 @@ These concerns can of course add substantial complexity to the code.
>  For more information, see any of a number of textbooks on the
>  subject~\cite{WRichardStevens1992,StewartWeiss2013UNIX}.
> 
> -\begin{figure}[tbp]
> +\begin{listing}[tbp]
>  { \scriptsize
>  \begin{verbbox}
>    1 pid = fork();
> @@ -207,14 +207,14 @@ subject~\cite{WRichardStevens1992,StewartWeiss2013UNIX}.
>  \centering
>  \theverbbox
>  \caption{Using the \tco{fork()} Primitive}
> -\label{fig:toolsoftrade:Using the fork() Primitive}
> -\end{figure}
> +\label{lst:toolsoftrade:Using the fork() Primitive}
> +\end{listing}
> 
>  If \co{fork()} succeeds, it returns twice, once for the parent
>  and again for the child.
>  The value returned from \co{fork()} allows the caller to tell
>  the difference, as shown in
> -Figure~\ref{fig:toolsoftrade:Using the fork() Primitive}
> +Listing~\ref{lst:toolsoftrade:Using the fork() Primitive}
>  (\path{forkjoin.c}).
>  Line~1 executes the \co{fork()} primitive, and saves its return value
>  in local variable \co{pid}.
> @@ -228,7 +228,7 @@ Otherwise, the \co{fork()} has executed successfully, and the parent
>  therefore executes line~9 with the variable \co{pid} containing the
>  process ID of the child.
> 
> -\begin{figure}[tbp]
> +\begin{listing}[tbp]
>  { \scriptsize
>  \begin{verbbox}
>    1 void waitall(void)
> @@ -251,8 +251,8 @@ process ID of the child.
>  \centering
>  \theverbbox
>  \caption{Using the \tco{wait()} Primitive}
> -\label{fig:toolsoftrade:Using the wait() Primitive}
> -\end{figure}
> +\label{lst:toolsoftrade:Using the wait() Primitive}
> +\end{listing}
> 
>  The parent process may use the \co{wait()} primitive to wait for its children
>  to complete.
> @@ -261,7 +261,7 @@ counterpart, as each invocation of \co{wait()} waits for but one child
>  process.
>  It is therefore customary to wrap \co{wait()} into a function similar
>  to the \co{waitall()} function shown in
> -Figure~\ref{fig:toolsoftrade:Using the wait() Primitive}
> +Listing~\ref{lst:toolsoftrade:Using the wait() Primitive}
>  (\path{api-pthread.h}),
>  with this \co{waitall()} function having semantics similar to the
>  shell-script \co{wait} command.
> @@ -283,14 +283,14 @@ Otherwise, lines~11 and 12 print an error and exit.
>  	child individually.
>  	In addition, some parallel applications need to detect the
>  	reason that the child died.
> -	As we saw in Figure~\ref{fig:toolsoftrade:Using the wait() Primitive},
> +	As we saw in Listing~\ref{lst:toolsoftrade:Using the wait() Primitive},
>  	it is not hard to build a \co{waitall()} function out of
>  	the \co{wait()} function, but it would be impossible to
>  	do the reverse.
>  	Once the information about a specific child is lost, it is lost.
>  } \QuickQuizEnd
> 
> -\begin{figure}[tbp]
> +\begin{listing}[tbp]
>  { \scriptsize
>  \begin{verbbox}
>    1 int x = 0;
> @@ -313,13 +313,13 @@ Otherwise, lines~11 and 12 print an error and exit.
>  \centering
>  \theverbbox
>  \caption{Processes Created Via \tco{fork()} Do Not Share Memory}
> -\label{fig:toolsoftrade:Processes Created Via fork() Do Not Share Memory}
> -\end{figure}
> +\label{lst:toolsoftrade:Processes Created Via fork() Do Not Share Memory}
> +\end{listing}
> 
>  It is critically important to note that the parent and child do \emph{not}
>  share memory.
>  This is illustrated by the program shown in
> -Figure~\ref{fig:toolsoftrade:Processes Created Via fork() Do Not Share Memory}
> +Listing~\ref{lst:toolsoftrade:Processes Created Via fork() Do Not Share Memory}
>  (\path{forkjoinvar.c}),
>  in which the child sets a global variable \co{x} to 1 on line~6,
>  prints a message on line~7, and exits on line~8.
> @@ -353,7 +353,7 @@ Parent process sees x=0
>  	source code of the Linux-kernel implementations themselves.
> 
>  	It is important to note that the parent process in
> -	Figure~\ref{fig:toolsoftrade:Processes Created Via fork() Do Not Share Memory}
> +	Listing~\ref{lst:toolsoftrade:Processes Created Via fork() Do Not Share Memory}
>  	waits until after the child terminates to do its \co{printf()}.
>  	Using \co{printf()}'s buffered I/O concurrently to the same file
>  	from multiple processes is non-trivial, and is best avoided.
> @@ -376,7 +376,7 @@ than fork-join parallelism.
>  To create a thread within an existing process, invoke the
>  \co{pthread_create()} primitive, for example, as shown on lines~15
>  and~16 of
> -Figure~\ref{fig:toolsoftrade:Threads Created Via pthread-create() Share Memory}
> +Listing~\ref{lst:toolsoftrade:Threads Created Via pthread-create() Share Memory}
>  (\path{pcreate.c}).
>  The first argument is a pointer to a \co{pthread_t} in which to store the
>  ID of the thread to be created, the second \co{NULL} argument is a pointer
> @@ -385,7 +385,7 @@ to an optional \co{pthread_attr_t}, the third argument is the function
>  that is to be invoked by the new thread, and the last \co{NULL} argument
>  is the argument that will be passed to \co{mythread}.
> 
> -\begin{figure}[tbp]
> +\begin{listing}[tbp]
>  { \scriptsize
>  \begin{verbbox}
>    1 int x = 0;
> @@ -419,15 +419,15 @@ is the argument that will be passed to \co{mythread}.
>  \centering
>  \theverbbox
>  \caption{Threads Created Via \tco{pthread_create()} Share Memory}
> -\label{fig:toolsoftrade:Threads Created Via pthread-create() Share Memory}
> -\end{figure}
> +\label{lst:toolsoftrade:Threads Created Via pthread-create() Share Memory}
> +\end{listing}
> 
>  In this example, \co{mythread()} simply returns, but it could instead
>  call \co{pthread_exit()}.
> 
>  \QuickQuiz{}
>  	If the \co{mythread()} function in
> -	Figure~\ref{fig:toolsoftrade:Threads Created Via pthread-create() Share Memory}
> +	Listing~\ref{lst:toolsoftrade:Threads Created Via pthread-create() Share Memory}
>  	can simply return, why bother with \co{pthread_exit()}?
>  \QuickQuizAnswer{
>  	In this simple example, there is no reason whatsoever.
> @@ -450,7 +450,7 @@ or the value returned by the thread's top-level function, depending on
>  how the thread in question exits.
> 
>  The program shown in
> -Figure~\ref{fig:toolsoftrade:Threads Created Via pthread-create() Share Memory}
> +Listing~\ref{lst:toolsoftrade:Threads Created Via pthread-create() Share Memory}
>  produces output as follows, demonstrating that memory is in fact
>  shared between the two threads:
> 
> @@ -541,7 +541,7 @@ lock~\cite{Hoare74}.
>  	to the reader.
>  } \QuickQuizEnd
> 
> -\begin{figure}[tbp]
> +\begin{listing}[tbp]
>  { \scriptsize
>  \begin{verbbox}
>    1 pthread_mutex_t lock_a = PTHREAD_MUTEX_INITIALIZER;
> @@ -598,11 +598,11 @@ lock~\cite{Hoare74}.
>  \centering
>  \theverbbox
>  \caption{Demonstration of Exclusive Locks}
> -\label{fig:toolsoftrade:Demonstration of Exclusive Locks}
> -\end{figure}
> +\label{lst:toolsoftrade:Demonstration of Exclusive Locks}
> +\end{listing}
> 
>  This exclusive-locking property is demonstrated using the code shown in
> -Figure~\ref{fig:toolsoftrade:Demonstration of Exclusive Locks}
> +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}.
> @@ -618,7 +618,7 @@ primitives.
>  \QuickQuiz{}
>  	Why not simply make the argument to \co{lock_reader()}
>  	on line~5 of
> -	Figure~\ref{fig:toolsoftrade:Demonstration of Exclusive Locks}
> +	Listing~\ref{lst:toolsoftrade:Demonstration of Exclusive Locks}
>  	be a pointer to a \co{pthread_mutex_t}?
>  \QuickQuizAnswer{
>  	Because we will need to pass \co{lock_reader()} to
> @@ -653,7 +653,7 @@ required by \co{pthread_create()}.
>  } \QuickQuizEnd
> 
>  Lines~31-49 of
> -Figure~\ref{fig:toolsoftrade:Demonstration of Exclusive Locks}
> +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}.
> @@ -664,7 +664,7 @@ While holding the lock, lines~40-43 increment the shared variable \co{x},
>  sleeping for five milliseconds between each increment.
>  Finally, lines~44-47 release the lock.
> 
> -\begin{figure}[tbp]
> +\begin{listing}[tbp]
>  { \scriptsize
>  \begin{verbbox}
>    1   printf("Creating two threads using same lock:\n");
> @@ -691,10 +691,10 @@ Finally, lines~44-47 release the lock.
>  \centering
>  \theverbbox
>  \caption{Demonstration of Same Exclusive Lock}
> -\label{fig:toolsoftrade:Demonstration of Same Exclusive Lock}
> -\end{figure}
> +\label{lst:toolsoftrade:Demonstration of Same Exclusive Lock}
> +\end{listing}
> 
> -Figure~\ref{fig:toolsoftrade:Demonstration of Same Exclusive 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
> @@ -719,7 +719,7 @@ by \co{lock_writer()} while holding the lock.
>  \QuickQuiz{}
>  	Is ``x = 0'' the only possible output from the code fragment
>  	shown in
> -	Figure~\ref{fig:toolsoftrade:Demonstration of Same Exclusive Lock}?
> +	Listing~\ref{lst:toolsoftrade:Demonstration of Same Exclusive Lock}?
>  	If so, why?
>  	If not, what other output could appear, and why?
>  \QuickQuizAnswer{
> @@ -735,7 +735,7 @@ by \co{lock_writer()} while holding the lock.
>  	However, there are no guarantees, especially on a busy system.
>  } \QuickQuizEnd
> 
> -\begin{figure}[tbp]
> +\begin{listing}[tbp]
>  { \scriptsize
>  \begin{verbbox}
>    1   printf("Creating two threads w/different locks:\n");
> @@ -763,10 +763,10 @@ by \co{lock_writer()} while holding the lock.
>  \centering
>  \theverbbox
>  \caption{Demonstration of Different Exclusive Locks}
> -\label{fig:toolsoftrade:Demonstration of Different Exclusive Locks}
> -\end{figure}
> +\label{lst:toolsoftrade:Demonstration of Different Exclusive Locks}
> +\end{listing}
> 
> -Figure~\ref{fig:toolsoftrade:Demonstration of Different Exclusive Locks}
> +Listing~\ref{lst:toolsoftrade:Demonstration of Different Exclusive Locks}
>  shows a similar code fragment, but this time using different locks:
>  \co{lock_a} for \co{lock_reader()} and \co{lock_b} for
>  \co{lock_writer()}.
> @@ -811,7 +811,7 @@ values of \co{x} stored by \co{lock_writer()}.
> 
>  \QuickQuiz{}
>  	In the code shown in
> -	Figure~\ref{fig:toolsoftrade:Demonstration of Different Exclusive Locks},
> +	Listing~\ref{lst:toolsoftrade:Demonstration of Different Exclusive Locks},
>  	is \co{lock_reader()} guaranteed to see all the values produced
>  	by \co{lock_writer()}?
>  	Why or why not?
> @@ -825,19 +825,19 @@ values of \co{x} stored by \co{lock_writer()}.
> 
>  \QuickQuiz{}
>  	Wait a minute here!!!
> -	Figure~\ref{fig:toolsoftrade:Demonstration of Same Exclusive Lock}
> +	Listing~\ref{lst:toolsoftrade:Demonstration of Same Exclusive Lock}
>  	didn't initialize shared variable \co{x},
>  	so why does it need to be initialized in
> -	Figure~\ref{fig:toolsoftrade:Demonstration of Different Exclusive Locks}?
> +	Listing~\ref{lst:toolsoftrade:Demonstration of Different Exclusive Locks}?
>  \QuickQuizAnswer{
>  	See line~3 of
> -	Figure~\ref{fig:toolsoftrade:Demonstration of Exclusive Locks}.
> +	Listing~\ref{lst:toolsoftrade:Demonstration of Exclusive Locks}.
>  	Because the code in
> -	Figure~\ref{fig:toolsoftrade:Demonstration of Same Exclusive Lock}
> +	Listing~\ref{lst:toolsoftrade:Demonstration of Same Exclusive Lock}
>  	ran first, it could rely on the compile-time initialization of
>  	\co{x}.
>  	The code in
> -	Figure~\ref{fig:toolsoftrade:Demonstration of Different Exclusive Locks}
> +	Listing~\ref{lst:toolsoftrade:Demonstration of Different Exclusive Locks}
>  	ran next, so it had to re-initialize \co{x}.
>  } \QuickQuizEnd
> 
> @@ -873,7 +873,7 @@ an arbitrarily large number of readers to concurrently hold the lock.
>  However, in practice, we need to know how much additional scalability is
>  provided by reader-writer locks.
> 
> -\begin{figure}[tbp]
> +\begin{listing}[tbp]
>  { \scriptsize
>  \begin{verbbox}
>    1 pthread_rwlock_t rwl = PTHREAD_RWLOCK_INITIALIZER;
> @@ -922,10 +922,10 @@ provided by reader-writer locks.
>  \centering
>  \theverbbox
>  \caption{Measuring Reader-Writer Lock Scalability}
> -\label{fig:toolsoftrade:Measuring Reader-Writer Lock Scalability}
> -\end{figure}
> +\label{lst:toolsoftrade:Measuring Reader-Writer Lock Scalability}
> +\end{listing}
> 
> -Figure~\ref{fig:toolsoftrade:Measuring Reader-Writer Lock Scalability}
> +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
> @@ -955,7 +955,7 @@ rights to assume that the value of \co{goflag} would never change.
>  \QuickQuiz{}
>  	Instead of using \co{READ_ONCE()} everywhere, why not just
>  	declare \co{goflag} as \co{volatile} on line~10 of
> -	Figure~\ref{fig:toolsoftrade:Measuring Reader-Writer Lock Scalability}?
> +	Listing~\ref{lst:toolsoftrade:Measuring Reader-Writer Lock Scalability}?
>  \QuickQuizAnswer{
>  	A \co{volatile} declaration is in fact a reasonable alternative in
>  	this particular case.
> @@ -977,7 +977,7 @@ rights to assume that the value of \co{goflag} would never change.
>  	Don't we also need memory barriers to make sure
>  	that the change in \co{goflag}'s value propagates to the
>  	CPU in a timely fashion in
> -	Figure~\ref{fig:toolsoftrade:Measuring Reader-Writer Lock Scalability}?
> +	Listing~\ref{lst:toolsoftrade:Measuring Reader-Writer Lock Scalability}?
>  \QuickQuizAnswer{
>  	No, memory barriers are not needed and won't help here.
>  	Memory barriers only enforce ordering among multiple memory
> @@ -1167,7 +1167,7 @@ to protect the tiniest of critical sections.
>  One such way are atomic operations.
>  We have seen one atomic operations already, in the form of the
>  \co{__sync_fetch_and_add()} primitive on line~18 of
> -Figure~\ref{fig:toolsoftrade:Measuring Reader-Writer Lock Scalability}.
> +Listing~\ref{lst:toolsoftrade:Measuring Reader-Writer Lock Scalability}.
>  This primitive atomically adds the value of its second argument to
>  the value referenced by its first argument, returning the old value
>  (which was ignored in this case).
> @@ -1243,11 +1243,11 @@ In some cases, it is sufficient to constrain the compiler's ability
>  to reorder operations, while allowing the CPU free rein, in which
>  case the \co{barrier()} primitive may be used, as it in fact was
>  on line~28 of
> -Figure~\ref{fig:toolsoftrade:Measuring Reader-Writer Lock Scalability}.
> +Listing~\ref{lst:toolsoftrade:Measuring Reader-Writer Lock Scalability}.
>  In some cases, it is only necessary to ensure that the compiler
>  avoids optimizing away a given memory read, in which case the
>  \co{READ_ONCE()} primitive may be used, as it was on line~17 of
> -Figure~\ref{fig:toolsoftrade:Demonstration of Exclusive Locks}.
> +Listing~\ref{lst:toolsoftrade:Demonstration of Exclusive Locks}.
>  Similarly, the \co{WRITE_ONCE()} primitive may be used to prevent the
>  compiler from optimizing away a given memory write.
>  These last three primitives are not provided directly by \GCC,
> @@ -1416,10 +1416,10 @@ Threads share everything except for per-thread local state,\footnote{
>  which includes program counter and stack.
> 
>  The thread API is shown in
> -Figure~\ref{fig:toolsoftrade:Thread API}, and members are described in the
> +Listing~\ref{lst:toolsoftrade:Thread API}, and members are described in the
>  following sections.
> 
> -\begin{figure*}[tbp]
> +\begin{listing*}[tbp]
>  { \scriptsize
>  \begin{verbbox}
>  int smp_thread_id(void)
> @@ -1433,8 +1433,8 @@ void wait_all_threads(void)
>  \centering
>  \theverbbox
>  \caption{Thread API}
> -\label{fig:toolsoftrade:Thread API}
> -\end{figure*}
> +\label{lst:toolsoftrade:Thread API}
> +\end{listing*}
> 
>  \subsubsection{\tco{create_thread()}}
> 
> @@ -1499,7 +1499,7 @@ a run, so such synchronization is normally not needed.
> 
>  \subsubsection{Example Usage}
> 
> -Figure~\ref{fig:toolsoftrade:Example Child Thread}
> +Listing~\ref{lst:toolsoftrade:Example Child Thread}
>  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.
> @@ -1509,7 +1509,7 @@ Note that the \co{return} statement on line~7 terminates the thread,
>  returning a \co{NULL} to whoever invokes \co{wait_thread()} on this
>  thread.
> 
> -\begin{figure}[tbp]
> +\begin{listing}[tbp]
>  { \scriptsize
>  \begin{verbbox}
>    1 void *thread_test(void *arg)
> @@ -1525,11 +1525,11 @@ thread.
>  \centering
>  \theverbbox
>  \caption{Example Child Thread}
> -\label{fig:toolsoftrade:Example Child Thread}
> -\end{figure}
> +\label{lst:toolsoftrade:Example Child Thread}
> +\end{listing}
> 
>  The parent program is shown in
> -Figure~\ref{fig:toolsoftrade:Example Parent Thread}.
> +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.
> @@ -1538,7 +1538,7 @@ and waits for them to complete on line~18.
>  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.
> 
> -\begin{figure}[tbp]
> +\begin{listing}[tbp]
>  { \scriptsize
>  \begin{verbbox}
>    1 int main(int argc, char *argv[])
> @@ -1567,8 +1567,8 @@ as in this case they are all \co{NULL}, which is not very interesting.
>  \centering
>  \theverbbox
>  \caption{Example Parent Thread}
> -\label{fig:toolsoftrade:Example Parent Thread}
> -\end{figure}
> +\label{lst:toolsoftrade:Example Parent Thread}
> +\end{listing}
> 
>  \QuickQuiz{}
>  	What happened to the Linux-kernel equivalents to \co{fork()}
> @@ -1584,11 +1584,11 @@ as in this case they are all \co{NULL}, which is not very interesting.
>  \label{sec:toolsoftrade:Locking}
> 
>  A good starting subset of the Linux kernel's locking API is shown in
> -Figure~\ref{fig:toolsoftrade:Locking API},
> +Listing~\ref{lst:toolsoftrade:Locking API},
>  each API element being described in the following sections.
>  This book's CodeSamples locking API closely follows that of the Linux kernel.
> 
> -\begin{figure}[tbp]
> +\begin{listing}[tbp]
>  { \scriptsize
>  \begin{verbbox}
>  void spin_lock_init(spinlock_t *sp);
> @@ -1600,8 +1600,8 @@ void spin_unlock(spinlock_t *sp);
>  \centering
>  \theverbbox
>  \caption{Locking API}
> -\label{fig:toolsoftrade:Locking API}
> -\end{figure}
> +\label{lst:toolsoftrade:Locking API}
> +\end{listing}
> 
>  \subsubsection{\tco{spin_lock_init()}}
> 
> @@ -1721,7 +1721,7 @@ given per-CPU variable, \co{per_cpu()} to access a specified CPU's
>  instance of a given per-CPU variable, along with many other special-purpose
>  per-CPU operations.
> 
> -Figure~\ref{fig:toolsoftrade:Per-Thread-Variable API}
> +Listing~\ref{lst:toolsoftrade:Per-Thread-Variable API}
>  shows this book's per-thread-variable API, which is patterned
>  after the Linux kernel's per-CPU-variable API.
>  This API provides the per-thread equivalent of global variables.
> @@ -1729,7 +1729,7 @@ 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{figure}[htbp]
> +\begin{listing}[htbp]
>  { \scriptsize
>  \begin{verbbox}
>  DEFINE_PER_THREAD(type, name)
> @@ -1742,8 +1742,8 @@ init_per_thread(name, v)
>  \centering
>  \theverbbox
>  \caption{Per-Thread-Variable API}
> -\label{fig:toolsoftrade:Per-Thread-Variable API}
> -\end{figure}
> +\label{lst:toolsoftrade:Per-Thread-Variable API}
> +\end{listing}
> 
>  \QuickQuiz{}
>  	How could you work around the lack of a per-thread-variable
> -- 
> 2.7.4
> 

--
To unsubscribe from this list: send the line "unsubscribe perfbook" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[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