{"id":5467,"date":"2018-06-27T20:21:22","date_gmt":"2018-06-27T20:21:22","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-the-rules-to-lock-free-programming\/"},"modified":"2023-06-26T11:48:52","modified_gmt":"2023-06-26T11:48:52","slug":"c-core-guidelines-the-rules-to-lock-free-programming","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-the-rules-to-lock-free-programming\/","title":{"rendered":"C++ Core Guidelines: The Resolution of the Riddle"},"content":{"rendered":"<p>Today, I will solve the riddle from my <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-concurrency-and-lock-free-programming\">last post<\/a>. Thanks to my readers, the analysis of the ABA problem is quite accurate.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5460\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/06\/park-748339_1280.jpg\" alt=\"park 748339 1280\" width=\"600\" height=\"266\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/06\/park-748339_1280.jpg 1280w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/06\/park-748339_1280-300x133.jpg 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/06\/park-748339_1280-1024x454.jpg 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/06\/park-748339_1280-768x341.jpg 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>Only to remind you. The rule CP., 100 from the C++ core guidelines, is the starting point of the riddle.<\/p>\n<\/p>\n<h2><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rconc-lockfree\">CP.100: Don\u2019t use lock-free programming unless you absolutely have to. <\/a><\/h2>\n<p>The challenge in the rule states that the following code snippet has a bug. The bug should be due to the ABA problem. The post <a href=\"https:\/\/www.modernescpp.com\/index.php\/aba-a-is-not-the-same-as-a\">ABA &#8211; A is not the same as A<\/a> gives a concise introduction to the ABA problem.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #006699; font-weight: bold;\">extern<\/span> atomic<span style=\"color: #555555;\">&lt;<\/span>Link<span style=\"color: #555555;\">*&gt;<\/span> head;        <span style=\"color: #0099ff; font-style: italic;\">\/\/ the shared head of a linked list<\/span>\r\n\r\nLink<span style=\"color: #555555;\">*<\/span> nh <span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">new<\/span> Link(data, nullptr);    <span style=\"color: #0099ff; font-style: italic;\">\/\/ make a link ready for insertion<\/span>\r\nLink<span style=\"color: #555555;\">*<\/span> h <span style=\"color: #555555;\">=<\/span> head.load();                 <span style=\"color: #0099ff; font-style: italic;\">\/\/ read the shared head of the list   <\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">do<\/span> {\r\n    <span style=\"color: #006699; font-weight: bold;\">if<\/span> (h<span style=\"color: #555555;\">-&gt;<\/span>data <span style=\"color: #555555;\">&lt;=<\/span> data) <span style=\"color: #006699; font-weight: bold;\">break<\/span>;        <span style=\"color: #0099ff; font-style: italic;\">\/\/ if so, insert elsewhere           <\/span>\r\n    nh<span style=\"color: #555555;\">-&gt;<\/span>next <span style=\"color: #555555;\">=<\/span> h;                      <span style=\"color: #0099ff; font-style: italic;\">\/\/ next element is the previous head  <\/span>\r\n} <span style=\"color: #006699; font-weight: bold;\">while<\/span> (<span style=\"color: #555555;\">!<\/span>head.compare_exchange_weak(h, nh));    <span style=\"color: #0099ff; font-style: italic;\">\/\/ write nh to head or to h <\/span>\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Thanks a lot to anonymous readers of my German blog; here is a runnable piece of code and a deep analysis of the issue.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #009999;\">#include &lt;atomic&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Link<\/span> {\r\n<span style=\"color: #9999ff;\">public:<\/span>\r\n    Link(<span style=\"color: #007788; font-weight: bold;\">int<\/span> d, Link<span style=\"color: #555555;\">*<\/span> p) <span style=\"color: #555555;\">:<\/span> data(d), next(p) {}\r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span>     data;\r\n    Link<span style=\"color: #555555;\">*<\/span>   next;\r\n};\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">foo<\/span> (<span style=\"color: #007788; font-weight: bold;\">int<\/span> data) {\r\n    <span style=\"color: #006699; font-weight: bold;\">extern<\/span> std<span style=\"color: #555555;\">::<\/span>atomic<span style=\"color: #555555;\">&lt;<\/span>Link<span style=\"color: #555555;\">*&gt;<\/span> head;\r\n\r\n    Link<span style=\"color: #555555;\">*<\/span> nh <span style=\"color: #555555;\">=<\/span> <span style=\"color: #006699; font-weight: bold;\">new<\/span> Link(data, nullptr);            <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n    Link<span style=\"color: #555555;\">*<\/span> h  <span style=\"color: #555555;\">=<\/span> head.load();                        <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n\r\n    <span style=\"color: #006699; font-weight: bold;\">do<\/span> {\r\n        <span style=\"color: #006699; font-weight: bold;\">if<\/span> (h<span style=\"color: #555555;\">-&gt;<\/span>data <span style=\"color: #555555;\">&lt;=<\/span> data) <span style=\"color: #006699; font-weight: bold;\">break<\/span>;                <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\n        nh<span style=\"color: #555555;\">-&gt;<\/span>next <span style=\"color: #555555;\">=<\/span> h;                              <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span>\r\n    } <span style=\"color: #006699; font-weight: bold;\">while<\/span> (<span style=\"color: #555555;\">!<\/span>head.compare_exchange_weak(h, nh));  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (5)<\/span>\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>First of all, what should this piece of code do? It creates a singly linked list of nodes (<span style=\"font-family: courier new, courier;\">Link<\/span>). Each <span style=\"font-family: courier new, courier;\">node<\/span> has a pointer and a data field. The pointer points to the next element (<span style=\"font-family: courier new, courier;\">node<\/span>-&gt;next), and the data field stores the value:<span style=\"font-family: courier new, courier;\"> node-&gt;data. <\/span>Each new node is inserted into the singly linked list in such a way that data is ordered in ascending order.<span style=\"font-family: courier new, courier;\"><br \/><\/span><\/p>\n<p>The following steps are performed to insert a new node into the correct position in the singly linked list.<\/p>\n<ul>\n<li><strong>Line 1<\/strong>: A new node is created. This is fine because the node is locally created in each thread.<\/li>\n<li><strong>Line 2<\/strong>: The pointer to the head is read. The read operation is atomic; therefore,&nbsp; considered in isolation, the operation is also acceptable. What does isolation mean? Line 2 creates with line 5 a kind of transaction. Line 2 stores the initial state of the transaction, and line 5 publishes the transaction if nothing had changed in between.<\/li>\n<li><strong>Line 3<\/strong>: Correspondingly to the previous lines, this line 3 has no issue. Only a value comparison takes place, which may end the function if the data of the head is smaller than the new data.<\/li>\n<li><strong>Line 4<\/strong>: <span style=\"font-family: courier new, courier;\">nh<\/span> is local data; therefore, the assignment of<span style=\"font-family: courier new, courier;\"> nh-&gt;next<\/span> is fine. It may happen head<span style=\"font-family: courier new, courier;\"> h<\/span> was changed in the meantime and, consequently, <span style=\"font-family: courier new, courier;\">nh-&gt;next<\/span> does not refer to the head afterward. This is only an issue if the change is committed in the next line 5.<\/li>\n<li><strong>Line 5<\/strong>: The instruction <span style=\"font-family: courier new, courier;\">head.compare_exchange_weak(h, nh)<\/span> compares <span style=\"font-family: courier new, courier;\">the head<\/span> with the stored <span style=\"font-family: courier new, courier;\">h<\/span> in line 2 and exchanges <span style=\"font-family: courier new, courier;\">h<\/span> and <span style=\"font-family: courier new, courier;\">nh<\/span> in an atomic step as soon as they are the same. If <span style=\"font-family: courier new, courier;\">the head <\/span>is not equal to<span style=\"font-family: courier new, courier;\"> h<\/span>, <span style=\"font-family: courier new, courier;\">h<\/span> is set to <span style=\"font-family: courier new, courier;\">head.<\/span> Line 5 ends the atomic transaction and publishes the updated singly linked list.<\/li>\n<\/ul>\n<p>What is the issue with these few lines of code? The entire transaction is based on the pointer comparison in line 5. The singly linked list can be broken if the pointer comparison can be fooled.<\/p>\n<p>There is a time window between the loading of the head (line 2) and then checking if the current head is the old head (line 5). This means another thread may kick in and change in the meantime <span style=\"font-family: courier new, courier;\">head<\/span>, but the first thread is not aware of it.<\/p>\n<p>Let me present a buggy sequence of events.<\/p>\n<h3>Breaking of the Invariant<\/h3>\n<p>The invariant of the following singly linked list is that data is ordered in ascending order. The blue node is the head of the list.<\/p>\n<p>This is the initial structure of the list. The head has the address <strong><span style=\"font-family: courier new, courier;\">0x0815<\/span><\/strong>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5461\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/06\/ABAThread1.png\" alt=\"ABAThread1\" width=\"450\" height=\"94\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/06\/ABAThread1.png 734w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/06\/ABAThread1-300x63.png 300w\" sizes=\"auto, (max-width: 450px) 100vw, 450px\" \/><\/p>\n<p>&nbsp;<\/p>\n<h4>Thread 1<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5462\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/06\/Head42.png\" alt=\"Head42\" width=\"150\" height=\"93\" style=\"display: block; margin-left: auto; margin-right: auto;\" \/><\/p>\n<ul>\n<li>Wants to add the new node with data 42.<\/li>\n<li>42 &lt; 47; therefore, the new node should become the new head.<\/li>\n<li>Right before the line (5), Thread 2 kicks in.<\/li>\n<\/ul>\n<h4>Thread 2<\/h4>\n<ul>\n<li>Removes the current head 47.<\/li>\n<li>Makes the node with data 60 to the new head.<\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5463\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/06\/ABAThread2_60head.png\" alt=\"ABAThread2 60head\" width=\"300\" height=\"92\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/06\/ABAThread2_60head.png 487w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/06\/ABAThread2_60head-300x92.png 300w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/p>\n<ul>\n<li>Wants to add the new node with data 30.<\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5464\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/06\/Head30.png\" alt=\"Head30\" width=\"150\" height=\"98\" style=\"display: block; margin-left: auto; margin-right: auto;\" \/><\/p>\n<ul>\n<li>Makes 30 the new head with address <span style=\"font-family: courier new, courier;\"><strong>0x0815<\/strong><\/span>; this was the former address of 47 and will often happen because of memory reuse.<\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5465\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/06\/ABAThread2_30.png\" alt=\"ABAThread2 30\" width=\"500\" height=\"99\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/06\/ABAThread2_30.png 750w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/06\/ABAThread2_30-300x60.png 300w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<p>&nbsp;<\/p>\n<h4>&nbsp;Thread 1<\/h4>\n<ul>\n<li>Makes the node with the data 42 to the new head; this is fine because line 5 compares the old with the new node, and they have the same address: <span style=\"font-family: courier new, courier;\"><strong>0x0815.<\/strong><\/span><\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5466\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/06\/ABAThread1_42.png\" alt=\"ABAThread1 42\" width=\"600\" height=\"108\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/06\/ABAThread1_42.png 969w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/06\/ABAThread1_42-300x54.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/06\/ABAThread1_42-768x139.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>&nbsp;Now, the singly linked list is broken because the values of the nodes are not ordered in ascending order.<\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>I&#8217;m nearly done with the rules of concurrency and lock-free programming. The remaining rules are about wrong assumptions about hardware\/compiler combinations and the infamous double-checked locking pattern. Read about it in the next post.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today, I will solve the riddle from my last post. Thanks to my readers, the analysis of the ABA problem is quite accurate.<\/p>\n","protected":false},"author":21,"featured_media":5460,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[372],"tags":[483],"class_list":["post-5467","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-modern-c","tag-lock-free"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5467","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/comments?post=5467"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5467\/revisions"}],"predecessor-version":[{"id":6821,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5467\/revisions\/6821"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5460"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5467"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5467"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5467"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}