From d697d6b6b40359faadffb10fd219c8882dbcd09a Mon Sep 17 00:00:00 2001 From: Jens Maurer Date: Tue, 10 Sep 2019 21:44:53 +0200 Subject: [PATCH] [basic.atomics] Use math mode for memory model placeholders. --- source/atomics.tex | 132 ++++++++++++------------- source/basic.tex | 233 ++++++++++++++++++++++----------------------- 2 files changed, 181 insertions(+), 184 deletions(-) diff --git a/source/atomics.tex b/source/atomics.tex index 4160680e9d..37a396a0af 100644 --- a/source/atomics.tex +++ b/source/atomics.tex @@ -419,78 +419,78 @@ \end{note} \pnum -An atomic operation \placeholder{A} that performs a release operation on an atomic -object \placeholder{M} synchronizes with an atomic operation \placeholder{B} that performs -an acquire operation on \placeholder{M} and takes its value from any side effect in the -release sequence headed by \placeholder{A}. +An atomic operation $A$ that performs a release operation on an atomic +object $M$ synchronizes with an atomic operation $B$ that performs +an acquire operation on $M$ and takes its value from any side effect in the +release sequence headed by $A$. \pnum -An atomic operation \placeholder{A} on some atomic object \placeholder{M} is +An atomic operation $A$ on some atomic object $M$ is \defn{coherence-ordered before} -another atomic operation \placeholder{B} on \placeholder{M} if +another atomic operation $B$ on $M$ if \begin{itemize} -\item \placeholder{A} is a modification, and -\placeholder{B} reads the value stored by \placeholder{A}, or -\item \placeholder{A} precedes \placeholder{B} -in the modification order of \placeholder{M}, or -\item \placeholder{A} and \placeholder{B} are not +\item $A$ is a modification, and +$B$ reads the value stored by $A$, or +\item $A$ precedes $B$ +in the modification order of $M$, or +\item $A$ and $B$ are not the same atomic read-modify-write operation, and -there exists an atomic modification \placeholder{X} of \placeholder{M} -such that \placeholder{A} reads the value stored by \placeholder{X} and -\placeholder{X} precedes \placeholder{B} -in the modification order of \placeholder{M}, or -\item there exists an atomic modification \placeholder{X} of \placeholder{M} -such that \placeholder{A} is coherence-ordered before \placeholder{X} and -\placeholder{X} is coherence-ordered before \placeholder{B}. +there exists an atomic modification $X$ of $M$ +such that $A$ reads the value stored by $X$ and +$X$ precedes $B$ +in the modification order of $M$, or +\item there exists an atomic modification $X$ of $M$ +such that $A$ is coherence-ordered before $X$ and +$X$ is coherence-ordered before $B$. \end{itemize} \pnum -There is a single total order \placeholder{S} +There is a single total order $S$ on all \tcode{memory_order::seq_cst} operations, including fences, that satisfies the following constraints. -First, if \placeholder{A} and \placeholder{B} are +First, if $A$ and $B$ are \tcode{memory_order::seq_cst} operations and -\placeholder{A} strongly happens before \placeholder{B}, -then \placeholder{A} precedes \placeholder{B} in \placeholder{S}. -Second, for every pair of atomic operations \placeholder{A} and -\placeholder{B} on an object \placeholder{M}, -where \placeholder{A} is coherence-ordered before \placeholder{B}, -the following four conditions are required to be satisfied by \placeholder{S}: +$A$ strongly happens before $B$, +then $A$ precedes $B$ in $S$. +Second, for every pair of atomic operations $A$ and +$B$ on an object $M$, +where $A$ is coherence-ordered before $B$, +the following four conditions are required to be satisfied by $S$: \begin{itemize} -\item if \placeholder{A} and \placeholder{B} are both +\item if $A$ and $B$ are both \tcode{memory_order::seq_cst} operations, -then \placeholder{A} precedes \placeholder{B} in \placeholder{S}; and -\item if \placeholder{A} is a \tcode{memory_order::seq_cst} operation and -\placeholder{B} happens before -a \tcode{memory_order::seq_cst} fence \placeholder{Y}, -then \placeholder{A} precedes \placeholder{Y} in \placeholder{S}; and -\item if a \tcode{memory_order::seq_cst} fence \placeholder{X} -happens before \placeholder{A} and -\placeholder{B} is a \tcode{memory_order::seq_cst} operation, -then \placeholder{X} precedes \placeholder{B} in \placeholder{S}; and -\item if a \tcode{memory_order::seq_cst} fence \placeholder{X} -happens before \placeholder{A} and -\placeholder{B} happens before -a \tcode{memory_order::seq_cst} fence \placeholder{Y}, -then \placeholder{X} precedes \placeholder{Y} in \placeholder{S}. +then $A$ precedes $B$ in $S$; and +\item if $A$ is a \tcode{memory_order::seq_cst} operation and +$B$ happens before +a \tcode{memory_order::seq_cst} fence $Y$, +then $A$ precedes $Y$ in $S$; and +\item if a \tcode{memory_order::seq_cst} fence $X$ +happens before $A$ and +$B$ is a \tcode{memory_order::seq_cst} operation, +then $X$ precedes $B$ in $S$; and +\item if a \tcode{memory_order::seq_cst} fence $X$ +happens before $A$ and +$B$ happens before +a \tcode{memory_order::seq_cst} fence $Y$, +then $X$ precedes $Y$ in $S$. \end{itemize} \pnum \begin{note} -This definition ensures that \placeholder{S} is consistent with -the modification order of any atomic object \placeholder{M}. +This definition ensures that $S$ is consistent with +the modification order of any atomic object $M$. It also ensures that -a \tcode{memory_order::seq_cst} load \placeholder{A} of \placeholder{M} -gets its value either from the last modification of \placeholder{M} -that precedes \placeholder{A} in \placeholder{S} or -from some non-\tcode{memory_order::seq_cst} modification of \placeholder{M} -that does not happen before any modification of \placeholder{M} -that precedes \placeholder{A} in \placeholder{S}. +a \tcode{memory_order::seq_cst} load $A$ of $M$ +gets its value either from the last modification of $M$ +that precedes $A$ in $S$ or +from some non-\tcode{memory_order::seq_cst} modification of $M$ +that does not happen before any modification of $M$ +that precedes $A$ in $S$. \end{note} \pnum \begin{note} -We do not require that \placeholder{S} be consistent with +We do not require that $S$ be consistent with ``happens before''\iref{intro.races}. This allows more efficient implementation of \tcode{memory_order::acquire} and \tcode{memory_order::release} @@ -3522,27 +3522,27 @@ fence}. \pnum -A release fence \placeholder{A} synchronizes with an acquire fence \placeholder{B} if there exist -atomic operations \placeholder{X} and \placeholder{Y}, both operating on some atomic object -\placeholder{M}, such that \placeholder{A} is sequenced before \placeholder{X}, \placeholder{X} modifies -\placeholder{M}, \placeholder{Y} is sequenced before \placeholder{B}, and \placeholder{Y} reads the value -written by \placeholder{X} or a value written by any side effect in the hypothetical release -sequence \placeholder{X} would head if it were a release operation. +A release fence $A$ synchronizes with an acquire fence $B$ if there exist +atomic operations $X$ and $Y$, both operating on some atomic object +$M$, such that $A$ is sequenced before $X$, $X$ modifies +$M$, $Y$ is sequenced before $B$, and $Y$ reads the value +written by $X$ or a value written by any side effect in the hypothetical release +sequence $X$ would head if it were a release operation. \pnum -A release fence \placeholder{A} synchronizes with an atomic operation \placeholder{B} that -performs an acquire operation on an atomic object \placeholder{M} if there exists an atomic -operation \placeholder{X} such that \placeholder{A} is sequenced before \placeholder{X}, \placeholder{X} -modifies \placeholder{M}, and \placeholder{B} reads the value written by \placeholder{X} or a value -written by any side effect in the hypothetical release sequence \placeholder{X} would head if +A release fence $A$ synchronizes with an atomic operation $B$ that +performs an acquire operation on an atomic object $M$ if there exists an atomic +operation $X$ such that $A$ is sequenced before $X$, $X$ +modifies $M$, and $B$ reads the value written by $X$ or a value +written by any side effect in the hypothetical release sequence $X$ would head if it were a release operation. \pnum -An atomic operation \placeholder{A} that is a release operation on an atomic object -\placeholder{M} synchronizes with an acquire fence \placeholder{B} if there exists some atomic -operation \placeholder{X} on \placeholder{M} such that \placeholder{X} is sequenced before \placeholder{B} -and reads the value written by \placeholder{A} or a value written by any side effect in the -release sequence headed by \placeholder{A}. +An atomic operation $A$ that is a release operation on an atomic object +$M$ synchronizes with an acquire fence $B$ if there exists some atomic +operation $X$ on $M$ such that $X$ is sequenced before $B$ +and reads the value written by $A$ or a value written by any side effect in the +release sequence headed by $A$. \indexlibraryglobal{atomic_thread_fence}% \begin{itemdecl} diff --git a/source/basic.tex b/source/basic.tex index 83660fbf7f..a06c1d79e3 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -5557,8 +5557,8 @@ \rSec3[intro.races]{Data races} \pnum -The value of an object visible to a thread \placeholder{T} at a particular point is the -initial value of the object, a value assigned to the object by \placeholder{T}, or a +The value of an object visible to a thread $T$ at a particular point is the +initial value of the object, a value assigned to the object by $T$, or a value assigned to the object by another thread, according to the rules below. \begin{note} In some cases, there may instead be undefined behavior. Much of this @@ -5589,17 +5589,17 @@ perform an acquire operation on the locations comprising the mutex. Correspondingly, a call that releases the same mutex will perform a release operation on those same locations. Informally, performing a release operation on -\placeholder{A} forces prior +$A$ forces prior \indextext{side effects}% side effects on other memory locations to become visible to other threads that later perform a consume or an acquire operation on -\placeholder{A}. ``Relaxed'' atomic operations are not synchronization operations even +$A$. ``Relaxed'' atomic operations are not synchronization operations even though, like synchronization operations, they cannot contribute to data races. \end{note} \pnum -All modifications to a particular atomic object \placeholder{M} occur in some -particular total order, called the \defn{modification order} of \placeholder{M}. +All modifications to a particular atomic object $M$ occur in some +particular total order, called the \defn{modification order} of $M$. \begin{note} There is a separate order for each atomic object. There is no requirement that these can be combined into a single @@ -5609,11 +5609,11 @@ \pnum A \defn{release sequence} headed -by a release operation \placeholder{A} on an atomic object \placeholder{M} +by a release operation $A$ on an atomic object $M$ is a maximal contiguous sub-sequence of \indextext{side effects}% -side effects in the modification order of \placeholder{M}, -where the first operation is \placeholder{A}, and +side effects in the modification order of $M$, +where the first operation is $A$, and every subsequent operation is an atomic read-modify-write operation. \pnum @@ -5634,30 +5634,30 @@ \end{note} \pnum -An evaluation \placeholder{A} \defn{carries a dependency} to an evaluation \placeholder{B} if +An evaluation $A$ \defn{carries a dependency} to an evaluation $B$ if \begin{itemize} \item -the value of \placeholder{A} is used as an operand of \placeholder{B}, unless: +the value of $A$ is used as an operand of $B$, unless: \begin{itemize} \item -\placeholder{B} is an invocation of any specialization of +$B$ is an invocation of any specialization of \tcode{std::kill_dependency}\iref{atomics.order}, or \item -\placeholder{A} is the left operand of a built-in logical \logop{AND} (\tcode{\&\&}, +$A$ is the left operand of a built-in logical \logop{AND} (\tcode{\&\&}, see~\ref{expr.log.and}) or logical \logop{OR} (\tcode{||}, see~\ref{expr.log.or}) operator, or \item -\placeholder{A} is the left operand of a conditional (\tcode{?:}, see~\ref{expr.cond}) +$A$ is the left operand of a conditional (\tcode{?:}, see~\ref{expr.cond}) operator, or \item -\placeholder{A} is the left operand of the built-in comma (\tcode{,}) +$A$ is the left operand of the built-in comma (\tcode{,}) operator\iref{expr.comma}; \end{itemize} or \item -\placeholder{A} writes a scalar object or bit-field \placeholder{M}, \placeholder{B} reads the value -written by \placeholder{A} from \placeholder{M}, and \placeholder{A} is sequenced before \placeholder{B}, or +$A$ writes a scalar object or bit-field $M$, $B$ reads the value +written by $A$ from $M$, and $A$ is sequenced before $B$, or \item -for some evaluation \placeholder{X}, \placeholder{A} carries a dependency to \placeholder{X}, and -\placeholder{X} carries a dependency to \placeholder{B}. +for some evaluation $X$, $A$ carries a dependency to $X$, and +$X$ carries a dependency to $B$. \end{itemize} \begin{note} ``Carries a dependency to'' is a subset of ``is sequenced before'', @@ -5665,17 +5665,17 @@ \end{note} \pnum -An evaluation \placeholder{A} is \defn{dependency-ordered before} an evaluation -\placeholder{B} if +An evaluation $A$ is \defn{dependency-ordered before} an evaluation +$B$ if \begin{itemize} \item -\placeholder{A} performs a release operation on an atomic object \placeholder{M}, and, in -another thread, \placeholder{B} performs a consume operation on \placeholder{M} and reads -the value written by \placeholder{A}, or +$A$ performs a release operation on an atomic object $M$, and, in +another thread, $B$ performs a consume operation on $M$ and reads +the value written by $A$, or \item -for some evaluation \placeholder{X}, \placeholder{A} is dependency-ordered before \placeholder{X} and -\placeholder{X} carries a dependency to \placeholder{B}. +for some evaluation $X$, $A$ is dependency-ordered before $X$ and +$X$ carries a dependency to $B$. \end{itemize} \begin{note} @@ -5684,25 +5684,25 @@ \end{note} \pnum -An evaluation \placeholder{A} \defn{inter-thread happens before} an evaluation \placeholder{B} +An evaluation $A$ \defn{inter-thread happens before} an evaluation $B$ if \begin{itemize} \item - \placeholder{A} synchronizes with \placeholder{B}, or + $A$ synchronizes with $B$, or \item - \placeholder{A} is dependency-ordered before \placeholder{B}, or + $A$ is dependency-ordered before $B$, or \item - for some evaluation \placeholder{X} + for some evaluation $X$ \begin{itemize} \item - \placeholder{A} synchronizes with \placeholder{X} and \placeholder{X} - is sequenced before \placeholder{B}, or + $A$ synchronizes with $X$ and $X$ + is sequenced before $B$, or \item - \placeholder{A} is sequenced before \placeholder{X} and \placeholder{X} - inter-thread happens before \placeholder{B}, or + $A$ is sequenced before $X$ and $X$ + inter-thread happens before $B$, or \item - \placeholder{A} inter-thread happens before \placeholder{X} and \placeholder{X} - inter-thread happens before \placeholder{B}. + $A$ inter-thread happens before $X$ and $X$ + inter-thread happens before $B$. \end{itemize} \end{itemize} \begin{note} @@ -5724,11 +5724,11 @@ \end{note} \pnum -An evaluation \placeholder{A} \defn{happens before} an evaluation \placeholder{B} -(or, equivalently, \placeholder{B} \defn{happens after} \placeholder{A}) if: +An evaluation $A$ \defn{happens before} an evaluation $B$ +(or, equivalently, $B$ \defn{happens after} $A$) if: \begin{itemize} -\item \placeholder{A} is sequenced before \placeholder{B}, or -\item \placeholder{A} inter-thread happens before \placeholder{B}. +\item $A$ is sequenced before $B$, or +\item $A$ inter-thread happens before $B$. \end{itemize} The implementation shall ensure that no program execution demonstrates a cycle in the ``happens before'' relation. @@ -5738,13 +5738,13 @@ \end{note} \pnum -An evaluation \placeholder{A} \defn{simply happens before} an evaluation \placeholder{B} +An evaluation $A$ \defn{simply happens before} an evaluation $B$ if either \begin{itemize} -\item \placeholder{A} is sequenced before \placeholder{B}, or -\item \placeholder{A} synchronizes with \placeholder{B}, or -\item \placeholder{A} simply happens before \placeholder{X} and -\placeholder{X} simply happens before \placeholder{B}. +\item $A$ is sequenced before $B$, or +\item $A$ synchronizes with $B$, or +\item $A$ simply happens before $X$ and +$X$ simply happens before $B$. \end{itemize} \begin{note} In the absence of consume operations, @@ -5752,44 +5752,43 @@ \end{note} \pnum -An evaluation \placeholder{A} \defn{strongly happens before} -an evaluation \placeholder{D} if, either +An evaluation $A$ \defn{strongly happens before} +an evaluation $D$ if, either \begin{itemize} -\item \placeholder{A} is sequenced before \placeholder{D}, or -\item \placeholder{A} synchronizes with \placeholder{D}, and -both \placeholder{A} and \placeholder{D} are +\item $A$ is sequenced before $D$, or +\item $A$ synchronizes with $D$, and +both $A$ and $D$ are sequentially consistent atomic operations\iref{atomics.order}, or -\item there are evaluations \placeholder{B} and \placeholder{C} -such that \placeholder{A} is sequenced before \placeholder{B}, -\placeholder{B} simply happens before \placeholder{C}, and -\placeholder{C} is sequenced before \placeholder{D}, or -\item there is an evaluation \placeholder{B} such that -\placeholder{A} strongly happens before \placeholder{B}, and -\placeholder{B} strongly happens before \placeholder{D}. +\item there are evaluations $B$ and $C$ +such that $A$ is sequenced before $B$, +$B$ simply happens before $C$, and +$C$ is sequenced before $D$, or +\item there is an evaluation $B$ such that +$A$ strongly happens before $B$, and +$B$ strongly happens before $D$. \end{itemize} \begin{note} -Informally, if \placeholder{A} strongly happens before \placeholder{B}, -then \placeholder{A} appears to be evaluated before \placeholder{B} +Informally, if $A$ strongly happens before $B$, +then $A$ appears to be evaluated before $B$ in all contexts. Strongly happens before excludes consume operations. \end{note} \pnum -A \defnadj{visible}{side effect} \placeholder{A} on a scalar object or bit-field \placeholder{M} -with respect to a value computation \placeholder{B} of \placeholder{M} satisfies the +A \defnadj{visible}{side effect} $A$ on a scalar object or bit-field $M$ +with respect to a value computation $B$ of $M$ satisfies the conditions: \begin{itemize} -\item \placeholder{A} happens before \placeholder{B} and +\item $A$ happens before $B$ and \item there is no other \indextext{side effects}% -side effect \placeholder{X} to \placeholder{M} such that \placeholder{A} -happens before \placeholder{X} and \placeholder{X} happens before \placeholder{B}. +side effect $X$ to $M$ such that $A$ +happens before $X$ and $X$ happens before $B$. \end{itemize} -The value of a non-atomic scalar object or bit-field \placeholder{M}, as determined by -evaluation \placeholder{B}, shall be the value stored by the +The value of a non-atomic scalar object or bit-field $M$, as determined by +evaluation $B$, shall be the value stored by the \indextext{side effects!visible}% -visible side effect -\placeholder{A}. +visible side effect $A$. \begin{note} If there is ambiguity about which side effect to a non-atomic object or bit-field is visible, then the behavior is either @@ -5805,10 +5804,10 @@ \pnum The value of an -atomic object \placeholder{M}, as determined by evaluation \placeholder{B}, shall be the value +atomic object $M$, as determined by evaluation $B$, shall be the value stored by some -side effect \placeholder{A} that modifies \placeholder{M}, where \placeholder{B} does not happen -before \placeholder{A}. +side effect $A$ that modifies $M$, where $B$ does not happen +before $A$. \begin{note} The set of such side effects is also restricted by the rest of the rules described here, and in particular, by the coherence requirements below. @@ -5816,25 +5815,24 @@ \pnum \indextext{coherence!write-write}% -If an operation \placeholder{A} that modifies an atomic object \placeholder{M} happens before -an operation \placeholder{B} that modifies \placeholder{M}, then \placeholder{A} shall be earlier -than \placeholder{B} in the modification order of \placeholder{M}. +If an operation $A$ that modifies an atomic object $M$ happens before +an operation $B$ that modifies $M$, then $A$ shall be earlier +than $B$ in the modification order of $M$. \begin{note} -This requirement -is known as write-write coherence. +This requirement is known as write-write coherence. \end{note} \pnum \indextext{coherence!read-read}% If a \indextext{value computation}% -value computation \placeholder{A} of an atomic object \placeholder{M} happens before a -value computation \placeholder{B} of \placeholder{M}, and \placeholder{A} takes its value from a side -effect \placeholder{X} on \placeholder{M}, then the value computed by \placeholder{B} shall either be -the value stored by \placeholder{X} or the value stored by a +value computation $A$ of an atomic object $M$ happens before a +value computation $B$ of $M$, and $A$ takes its value from a side +effect $X$ on $M$, then the value computed by $B$ shall either be +the value stored by $X$ or the value stored by a \indextext{side effects}% -side effect \placeholder{Y} on -\placeholder{M}, where \placeholder{Y} follows \placeholder{X} in the modification order of \placeholder{M}. +side effect $Y$ on $M$, +where $Y$ follows $X$ in the modification order of $M$. \begin{note} This requirement is known as read-read coherence. \end{note} @@ -5843,10 +5841,10 @@ \indextext{coherence!read-write}% If a \indextext{value computation}% -value computation \placeholder{A} of an atomic object \placeholder{M} happens before an -operation \placeholder{B} that modifies \placeholder{M}, then \placeholder{A} shall take its value from a side -effect \placeholder{X} on \placeholder{M}, where \placeholder{X} precedes \placeholder{B} in the -modification order of \placeholder{M}. +value computation $A$ of an atomic object $M$ happens before an +operation $B$ that modifies $M$, then $A$ shall take its value from a side +effect $X$ on $M$, where $X$ precedes $B$ in the +modification order of $M$. \begin{note} This requirement is known as read-write coherence. @@ -5856,15 +5854,13 @@ \indextext{coherence!write-read}% If a \indextext{side effects}% -side effect \placeholder{X} on an atomic object \placeholder{M} happens before a value -computation \placeholder{B} of \placeholder{M}, then the evaluation \placeholder{B} shall take its -value from \placeholder{X} or from a +side effect $X$ on an atomic object $M$ happens before a value +computation $B$ of $M$, then the evaluation $B$ shall take its +value from $X$ or from a \indextext{side effects}% -side effect \placeholder{Y} that follows \placeholder{X} in the -modification order of \placeholder{M}. +side effect $Y$ that follows $X$ in the modification order of $M$. \begin{note} -This requirement is known as -write-read coherence. +This requirement is known as write-read coherence. \end{note} \pnum @@ -5921,12 +5917,12 @@ result in a data race if both occur in the same thread, even if one or more occurs in a signal handler. For each signal handler invocation, evaluations performed by the thread invoking a signal handler can be divided into two -groups \placeholder{A} and \placeholder{B}, such that no evaluations in -\placeholder{B} happen before evaluations in \placeholder{A}, and the +groups $A$ and $B$, such that no evaluations in +$B$ happen before evaluations in $A$, and the evaluations of such \tcode{volatile std::sig_atomic_t} objects take values as though -all evaluations in \placeholder{A} happened before the execution of the signal +all evaluations in $A$ happened before the execution of the signal handler and the execution of the signal handler happened before all evaluations -in \placeholder{B}. +in $B$. \pnum \begin{note} @@ -6109,39 +6105,40 @@ \pnum \indextext{forward progress guarantees!delegation of}% -When a thread of execution \placeholder{P} is specified to \defnx{block with forward -progress guarantee delegation}{block (execution)!with forward -progress guarantee delegation} on the completion of a set \placeholder{S} of threads -of execution, then throughout the whole time of \placeholder{P} being blocked on -\placeholder{S}, the implementation shall ensure that the forward progress guarantees -provided by at least one thread of execution in \placeholder{S} is at least as strong -as \placeholder{P}'s forward progress guarantees. -\begin{note} -It is unspecified which thread or threads of execution in \placeholder{S} are chosen +When a thread of execution $P$ is specified to +\defnx{block with forward progress guarantee delegation} +{block (execution)!with forward progress guarantee delegation} +on the completion of a set $S$ of threads of execution, +then throughout the whole time of $P$ being blocked on $S$, +the implementation shall ensure that the forward progress guarantees +provided by at least one thread of execution in $S$ +is at least as strong as $P$'s forward progress guarantees. +\begin{note} +It is unspecified which thread or threads of execution in $S$ are chosen and for which number of execution steps. The strengthening is not permanent and not necessarily in place for the rest of the lifetime of the affected thread of -execution. As long as \placeholder{P} is blocked, the implementation has to eventually -select and potentially strengthen a thread of execution in \placeholder{S}. +execution. As long as $P$ is blocked, the implementation has to eventually +select and potentially strengthen a thread of execution in $S$. \end{note} -Once a thread of execution in \placeholder{S} terminates, it is removed from \placeholder{S}. -Once \placeholder{S} is empty, \placeholder{P} is unblocked. +Once a thread of execution in $S$ terminates, it is removed from $S$. +Once $S$ is empty, $P$ is unblocked. \pnum \begin{note} -A thread of execution \placeholder{B} thus can temporarily provide an effectively +A thread of execution $B$ thus can temporarily provide an effectively stronger forward progress guarantee for a certain amount of time, due to a -second thread of execution \placeholder{A} being blocked on it with forward -progress guarantee delegation. In turn, if \placeholder{B} then blocks with -forward progress guarantee delegation on \placeholder{C}, this may also temporarily -provide a stronger forward progress guarantee to \placeholder{C}. +second thread of execution $A$ being blocked on it with forward +progress guarantee delegation. In turn, if $B$ then blocks with +forward progress guarantee delegation on $C$, this may also temporarily +provide a stronger forward progress guarantee to $C$. \end{note} \pnum \begin{note} -If all threads of execution in \placeholder{S} finish executing (e.g., they terminate -and do not use blocking synchronization incorrectly), then \placeholder{P}'s execution +If all threads of execution in $S$ finish executing (e.g., they terminate +and do not use blocking synchronization incorrectly), then $P$'s execution of the operation that blocks with forward progress guarantee delegation will not -result in \placeholder{P}'s progress guarantee being effectively weakened. +result in $P$'s progress guarantee being effectively weakened. \end{note} \pnum