{"id":10598,"date":"2025-02-03T10:37:44","date_gmt":"2025-02-03T10:37:44","guid":{"rendered":"https:\/\/www.modernescpp.com\/?p=10598"},"modified":"2025-07-03T14:32:11","modified_gmt":"2025-07-03T14:32:11","slug":"a-lock-free-stack-a-simplified-implementation","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/a-lock-free-stack-a-simplified-implementation\/","title":{"rendered":"A Lock-Free Stack: A Simplified Implementation"},"content":{"rendered":"\n<p>Today, I continue my mini story about lock-free data structures. <\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"711\" height=\"491\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/01\/Time26Concurrency.png\" alt=\"\" class=\"wp-image-10580\" style=\"width:734px;height:auto\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/01\/Time26Concurrency.png 711w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/01\/Time26Concurrency-300x207.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/01\/Time26Concurrency-705x487.png 705w\" sizes=\"auto, (max-width: 711px) 100vw, 711px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"> General Considerations<\/h2>\n\n\n\n<p>From the outside, the caller\u2019s responsibility (application) is to protect the data. From inside, the data structure is responsible for protecting itself. A data structure that protects itself so a data race cannot appear is called thread-safe.<\/p>\n\n\n\n<p><br>First, what general considerations must you keep in mind when designing a concurrent data structure?<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Locking Strategy<\/strong>: Should the data structure support coarse-grained or fine-grained locking or be lock-free? Coarse-grained locking might be easier to implement but introduces contention. A fine-grained implementation or a lock-free one is much more challenging. First of all, what do I mean by coarse-grained locking? Coarse-grained locking means that only one thread uses the data structure at one point in time.<\/li>\n\n\n\n<li><strong>The Granularity of the Interface<\/strong>: The bigger the thread-safe data structure\u2019s interface, the more difficult it becomes to reason about its concurrent usage.<\/li>\n\n\n\n<li><strong>Typical Usage Pattern<\/strong>: When readers mainly use your data structure, you should not optimize it for writers.<\/li>\n\n\n\n<li><strong>Avoidance of Loopholes:<\/strong> Don\u2019t pass the internals of your data structure to clients.<\/li>\n\n\n\n<li><strong>Contention<\/strong>: Do concurrent client requests seldom or often use your data structure?<\/li>\n\n\n\n<li><strong>Scalability<\/strong>: How is your data structure\u2019s performance characteristic when the number of<br>concurrent clients increases, or the data structure is bounded?<\/li>\n\n\n\n<li><strong>Invariants<\/strong>: Which invariant must hold for your data structure when used?<\/li>\n\n\n\n<li><strong>Exceptions<\/strong>: What should happen if an exception occurs?<\/li>\n<\/ul>\n\n\n\n<p>Of course, these considerations are dependent on each other. For example, using a coarse-grained locking strategy may increase the contention on the data structure and break scalability.<\/p>\n\n\n\n<p>First of all, what is a stack?<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">A Stack<\/h2>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"785\" height=\"225\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/01\/stack.png\" alt=\"\" class=\"wp-image-10600\" style=\"width:500px\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/01\/stack.png 785w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/01\/stack-300x86.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/01\/stack-768x220.png 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/01\/stack-705x202.png 705w\" sizes=\"auto, (max-width: 785px) 100vw, 785px\" \/><\/figure>\n\n\n\n<p>And<code> std::stack<\/code> follows the LIFO principle (Last In &#8211; First Out). A stack <code>sta<\/code>, which needs the header <code>&lt;stack><\/code>, has three member functions.<br>With<code> sta.push(e)<\/code>,  you can insert a new element e at the top of the stack, remove it from the top with sta.pop() , and reference it with <code>sta.top()<\/code>. The stack supports the comparison operators and knows its size.<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #f0f3f3; overflow:auto;width:auto;gray;border-width:.1em .1em .1em .8em\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #009999\">#include &lt;stack&gt;<\/span>\n...\nstd<span style=\"color: #555555\">::<\/span>stack<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span><span style=\"color: #555555\">&gt;<\/span> myStack;\n\nstd<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> myStack.empty() <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>; <span style=\"color: #0099FF; font-style: italic\">\/\/ true<\/span>\nstd<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> myStack.size() <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>; <span style=\"color: #0099FF; font-style: italic\">\/\/ 0<\/span>\n\nmyStack.push(<span style=\"color: #FF6600\">1<\/span>);\nmyStack.push(<span style=\"color: #FF6600\">2<\/span>);\nmyStack.push(<span style=\"color: #FF6600\">3<\/span>);\n\nstd<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> myStack.top() <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>; <span style=\"color: #0099FF; font-style: italic\">\/\/ 3<\/span>\n<span style=\"color: #006699; font-weight: bold\">while<\/span> (<span style=\"color: #555555\">!<\/span>myStack.empty()){\n    std<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> myStack.top() <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&quot; &quot;<\/span>;\n    myStack.pop();\n} <span style=\"color: #0099FF; font-style: italic\">\/\/ 3 2 1<\/span>\n\nstd<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> myStack.empty() <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>; <span style=\"color: #0099FF; font-style: italic\">\/\/ true<\/span>\nstd<span style=\"color: #555555\">::<\/span>cout <span style=\"color: #555555\">&lt;&lt;<\/span> myStack.size() <span style=\"color: #555555\">&lt;&lt;<\/span> <span style=\"color: #CC3300\">&#39;\\n&#39;<\/span>; <span style=\"color: #0099FF; font-style: italic\">\/\/ 0<\/span>\n<\/pre><\/div>\n\n\n\n<p>Now, let me start with the implementation of a lock-free stack.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">A Simplified Implementation<\/h2>\n\n\n\n<p>In my simplified implementation, I start with the <code>push <\/code>member function. First, let me visualize how a new node is added to a singly-linked list. head is the pointer to the first node in the singly-linked list.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"828\" height=\"265\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/01\/SinglyLinkedList.png\" alt=\"\" class=\"wp-image-10607\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/01\/SinglyLinkedList.png 828w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/01\/SinglyLinkedList-300x96.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/01\/SinglyLinkedList-768x246.png 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/01\/SinglyLinkedList-705x226.png 705w\" sizes=\"auto, (max-width: 828px) 100vw, 828px\" \/><\/figure>\n\n\n\n<p><br><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"1023\" height=\"251\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/01\/SinglyLinkedListInsert.png\" alt=\"\" class=\"wp-image-10608\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/01\/SinglyLinkedListInsert.png 1023w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/01\/SinglyLinkedListInsert-300x74.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/01\/SinglyLinkedListInsert-768x188.png 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/01\/SinglyLinkedListInsert-705x173.png 705w\" sizes=\"auto, (max-width: 1023px) 100vw, 1023px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1030\" height=\"236\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/01\/SinglyLinkedListNewHead-1030x236.png\" alt=\"\" class=\"wp-image-10609\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/01\/SinglyLinkedListNewHead-1030x236.png 1030w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/01\/SinglyLinkedListNewHead-300x69.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/01\/SinglyLinkedListNewHead-768x176.png 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/01\/SinglyLinkedListNewHead-705x161.png 705w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/01\/SinglyLinkedListNewHead.png 1036w\" sizes=\"auto, (max-width: 1030px) 100vw, 1030px\" \/><\/figure>\n\n\n\n<p>Each node in the singly-linked list has two attributes. Its value<code> T<\/code> and the<code> next. next<\/code> points to the next element in the singly-linked list. Only the node points to the <code>nullptr<\/code>. Adding a new node to the data is straightforward. Create a new node and let <code>next <\/code>pointer point to the previous head. So far, the new node is not accessible. Finally, the new node becomes the new head, completing the push operation.<\/p>\n\n\n\n<p><br>The following example shows the lock-free implementation of a concurrent stack.<\/p>\n\n\n\n<!-- HTML generated using hilite.me --><div style=\"background: #f0f3f3; overflow:auto;width:auto;gray;border-width:.1em .1em .1em .8em\"><pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #0099FF; font-style: italic\">\/\/ lockFreeStackPush.cpp<\/span>\n\n<span style=\"color: #009999\">#include &lt;atomic&gt;<\/span>\n<span style=\"color: #009999\">#include &lt;iostream&gt;<\/span>\n\n<span style=\"color: #006699; font-weight: bold\">template<\/span><span style=\"color: #555555\">&lt;<\/span><span style=\"color: #006699; font-weight: bold\">typename<\/span> T<span style=\"color: #555555\">&gt;<\/span>\n<span style=\"color: #006699; font-weight: bold\">class<\/span> <span style=\"color: #00AA88; font-weight: bold\">LockFreeStackPush<\/span> {\n <span style=\"color: #9999FF\">private:<\/span>\n    <span style=\"color: #006699; font-weight: bold\">struct<\/span> Node {\n        T data;\n        Node<span style=\"color: #555555\">*<\/span> next;\n        Node(T d)<span style=\"color: #555555\">:<\/span> data(d), next(nullptr) {}\n    };\n    std<span style=\"color: #555555\">::<\/span>atomic<span style=\"color: #555555\">&lt;<\/span>Node<span style=\"color: #555555\">*&gt;<\/span> head;\n <span style=\"color: #9999FF\">public:<\/span>\n    LockFreeStackPush() <span style=\"color: #555555\">=<\/span> <span style=\"color: #006699; font-weight: bold\">default<\/span>;\n    LockFreeStackPush(<span style=\"color: #006699; font-weight: bold\">const<\/span> LockFreeStackPush<span style=\"color: #555555\">&amp;<\/span>) <span style=\"color: #555555\">=<\/span> <span style=\"color: #006699; font-weight: bold\">delete<\/span>;\n    LockFreeStackPush<span style=\"color: #555555\">&amp;<\/span> <span style=\"color: #006699; font-weight: bold\">operator<\/span><span style=\"color: #555555\">=<\/span> (<span style=\"color: #006699; font-weight: bold\">const<\/span> LockFreeStackPush<span style=\"color: #555555\">&amp;<\/span>) <span style=\"color: #555555\">=<\/span> <span style=\"color: #006699; font-weight: bold\">delete<\/span>;\n   \n    <span style=\"color: #007788; font-weight: bold\">void<\/span> <span style=\"color: #CC00FF\">push<\/span>(T val) {\n        Node<span style=\"color: #555555\">*<\/span> <span style=\"color: #006699; font-weight: bold\">const<\/span> newNode <span style=\"color: #555555\">=<\/span> <span style=\"color: #006699; font-weight: bold\">new<\/span> Node(val);                            <span style=\"color: #0099FF; font-style: italic\">\/\/ 1<\/span>\n        newNode<span style=\"color: #555555\">-&gt;<\/span>next <span style=\"color: #555555\">=<\/span> head.load();                                    <span style=\"color: #0099FF; font-style: italic\">\/\/ 2<\/span>\n        <span style=\"color: #006699; font-weight: bold\">while<\/span>( <span style=\"color: #555555\">!<\/span>head.compare_exchange_strong(newNode<span style=\"color: #555555\">-&gt;<\/span>next, newNode) ); <span style=\"color: #0099FF; font-style: italic\">\/\/ 3<\/span>\n    }\n};\n   \n<span style=\"color: #007788; font-weight: bold\">int<\/span> <span style=\"color: #CC00FF\">main<\/span>(){\n\n    LockFreeStackPush<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">int<\/span><span style=\"color: #555555\">&gt;<\/span> lockFreeStack;\n    lockFreeStack.push(<span style=\"color: #FF6600\">5<\/span>);\n    \n    LockFreeStackPush<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #007788; font-weight: bold\">double<\/span><span style=\"color: #555555\">&gt;<\/span> lockFreeStack2;\n    lockFreeStack2.push(<span style=\"color: #FF6600\">5.5<\/span>);\n    \n    LockFreeStackPush<span style=\"color: #555555\">&lt;<\/span>std<span style=\"color: #555555\">::<\/span>string<span style=\"color: #555555\">&gt;<\/span> lockFreeStack3;\n    lockFreeStack3.push(<span style=\"color: #CC3300\">&quot;hello&quot;<\/span>);\n\n}\n<\/pre><\/div>\n\n\n\n<p>Let me analyze the crucial member function <code>push<\/code>. It creates the new node (line 1), adjusts<br>its next pointer to the old head, and makes the new node in a so-called CAS operation the new head (line 3). A CAS operation provides, in an atomic step, a compare and swap operation.<\/p>\n\n\n\n<p>The call <code>newNode->next = head.load() <\/code>loads the old value of head. If the loaded value <code>newNode->next<\/code> is still the same such as head in line 3, the head is updated to the <code>newNode<\/code>,  and the call <code>head.compare_exchange_strong <\/code>returns <code>true<\/code>. If not, the call returns <code>false<\/code>, and the while loop is executed until the call returns <code>true<\/code>. <code>head.compare_exchange_strong<\/code> returns <code>false <\/code>if another thread has meanwhile added a new node to the stack.<\/p>\n\n\n\n<p><br>Lines 2 and 3 build a kind of atomic transaction. First, you make a snapshot of the data structure (line 2), then try to publish the transaction (line 3). If the snapshot is no longer valid, you roll back and try it again.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What&#8217;s Next?<\/h2>\n\n\n\n<p>Todays simplified stack implementation serves me as a baseline for upcoming stacks.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Today, I continue my mini story about lock-free data structures. General Considerations From the outside, the caller\u2019s responsibility (application) is to protect the data. From inside, the data structure is responsible for protecting itself. A data structure that protects itself so a data race cannot appear is called thread-safe. First, what general considerations must you [&hellip;]<\/p>\n","protected":false},"author":21,"featured_media":10580,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[559],"tags":[563],"class_list":["post-10598","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-c26-blog","tag-hazard-pointers"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/10598","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=10598"}],"version-history":[{"count":11,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/10598\/revisions"}],"predecessor-version":[{"id":10613,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/10598\/revisions\/10613"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/10580"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=10598"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=10598"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=10598"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}