You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: concurrency-primer.tex
+10-10Lines changed: 10 additions & 10 deletions
Original file line number
Diff line number
Diff line change
@@ -902,8 +902,8 @@ \subsection{ABA problem}
902
902
A: v = 52
903
903
\end{ccode}
904
904
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.
907
907
Here sleeping is only used to ensure the occurrence of ABA problem.
908
908
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.
909
909
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}
924
924
Consider the following scenario:
925
925
\begin{enumerate}
926
926
\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()}.
928
928
\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}.
930
930
\item Thread B sets thread pool state to idle.
931
931
\item Main thread finishes waiting and adds more jobs.
932
932
\item Memory allocator reuses the recently freed memory as new jobs addresses.
933
933
\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}.
936
936
\end{enumerate}
937
937
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.
939
939
At the end, the dangling pointer could either point to garbage or trigger segmentation fault.
940
940
It could be even worse if nested ABA problem occurs in thread B.
941
941
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}
956
956
It requires the compare-and-swap instruction to be capable of comparing a wider size at once.
957
957
Sometimes, this is referred to as \introduce{double-width compare-and-swap}.
958
958
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.
960
960
For hardware that does not support the desired size, software implementations which may have locks involve are used instead, as mentioned in \secref{atomictype}.
961
961
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.
962
962
963
963
\inputminted{c}{./examples/rmw_example_aba.c}
964
964
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.
966
966
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.
968
968
Compiler optimizations are conservative on type punning, but it is acceptable for atomic operations.
969
969
See \secref{fusing}.
970
970
Another way to prevent ABA problem in the example is using safe memory reclamation mechanisms.
0 commit comments