Skip to content

Commit ee7a4a9

Browse files
committed
Tweak style annotation
Replace \monobox{} with \cc{} to properly apply the style to C code. Dollar sign removed for shell command.
1 parent 8abe58d commit ee7a4a9

File tree

1 file changed

+10
-10
lines changed

1 file changed

+10
-10
lines changed

concurrency-primer.tex

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -902,8 +902,8 @@ \subsection{ABA problem}
902902
A: v = 52
903903
\end{ccode}
904904

905-
In the example provided, the presence of ABA problem results in thread A being unaware that variable \monobox{v} has been altered.
906-
Since the comparison result indicates \monobox{v} unchanged, \monobox{v + 10} is swapped in.
905+
In the example provided, the presence of ABA problem results in thread A being unaware that variable \cc{v} has been altered.
906+
Since the comparison result indicates \cc{v} unchanged, \cc{v + 10} is swapped in.
907907
Here sleeping is only used to ensure the occurrence of ABA problem.
908908
In real world scenario, instead of sleeping, thread A could paused by being context switched for other tasks, including being preempted by higher priority tasks.
909909
This example seems harmless, but things can get nasty when atomic \textsc{RMW} operations are used in more complex data structures.
@@ -924,18 +924,18 @@ \subsection{ABA problem}
924924
Consider the following scenario:
925925
\begin{enumerate}
926926
\item There is only one job left.
927-
\item Thread A loads the pointer to the job by \monobox{atomic\_load()}.
927+
\item Thread A loads the pointer to the job by \cc{atomic_load()}.
928928
\item Thread A is preempted.
929-
\item Thread B claims the job and successfully updates \monobox{thrd\_pool->head->prev}.
929+
\item Thread B claims the job and successfully updates \cc{thrd_pool->head->prev}.
930930
\item Thread B sets thread pool state to idle.
931931
\item Main thread finishes waiting and adds more jobs.
932932
\item Memory allocator reuses the recently freed memory as new jobs addresses.
933933
\item Fortunately, the first added job has the same address as the one thread A held.
934-
\item Thread A is back in running state. The comparison result is equal so it updates \monobox{thrd\_pool->head->prev} with the old \monobox{job->prev}, which is already a dangling pointer.
935-
\item Another thread loads the dangling pointer from \monobox{thrd\_pool->head->prev}.
934+
\item Thread A is back in running state. The comparison result is equal so it updates \cc{thrd_pool->head->prev} with the old \cc{job->prev}, which is already a dangling pointer.
935+
\item Another thread loads the dangling pointer from \cc{thrd_pool->head->prev}.
936936
\end{enumerate}
937937

938-
Notice that even though \monobox{job->prev} is not loaded explicitly before comparison, compiler could place loading instructions before comparison.
938+
Notice that even though \cc{job->prev} is not loaded explicitly before comparison, compiler could place loading instructions before comparison.
939939
At the end, the dangling pointer could either point to garbage or trigger segmentation fault.
940940
It could be even worse if nested ABA problem occurs in thread B.
941941
Also, the possibility to allocate a job with same address could be higher when using memory pool, meaning that more chances to have ABA problem occurred.
@@ -956,15 +956,15 @@ \subsection{ABA problem}
956956
It requires the compare-and-swap instruction to be capable of comparing a wider size at once.
957957
Sometimes, this is referred to as \introduce{double-width compare-and-swap}.
958958
On x86-64 processors, for atomic instructions that load or store more than a CPU word size, it needs additional hardware support.
959-
You can use \monobox{\$ grep cx16 /proc/cpuinfo} to check if the processor supports 16-byte compare-and-swap.
959+
You can use \monobox{grep cx16 /proc/cpuinfo} to check if the processor supports 16-byte compare-and-swap.
960960
For hardware that does not support the desired size, software implementations which may have locks involve are used instead, as mentioned in \secref{atomictype}.
961961
Back to the example, ABA problem in the following code is fixed by using an version number that increments each time a job is added to the empty queue. On x86-64, add a compiler flag \monobox{-mcx16} to enable 16-byte compare-and-swap in \monobox{worker} function.
962962

963963
\inputminted{c}{./examples/rmw_example_aba.c}
964964

965-
Notice that, in the \monobox{struct idle\_job}, a union is used for type punning, which bundles the pointer and version number for compare-and-swap.
965+
Notice that, in the \cc{struct idle_job}, a union is used for type punning, which bundles the pointer and version number for compare-and-swap.
966966
Directly casting a job pointer to a pointer that points to a 16-byte object is undefined behavior (due to having different alignment), thus type punning is used instead.
967-
By using this techniques, \monobox{struct idle\_job} still can be accessed normally in other places, minimizing code modification.
967+
By using this techniques, \cc{struct idle_job} still can be accessed normally in other places, minimizing code modification.
968968
Compiler optimizations are conservative on type punning, but it is acceptable for atomic operations.
969969
See \secref{fusing}.
970970
Another way to prevent ABA problem in the example is using safe memory reclamation mechanisms.

0 commit comments

Comments
 (0)