{"id":10705,"date":"2025-03-24T11:37:37","date_gmt":"2025-03-24T11:37:37","guid":{"rendered":"https:\/\/www.modernescpp.com\/?p=10705"},"modified":"2025-07-03T14:38:59","modified_gmt":"2025-07-03T14:38:59","slug":"a-lock-free-stack-a-hazard-pointer-implementation-explained-i","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/a-lock-free-stack-a-hazard-pointer-implementation-explained-i\/","title":{"rendered":"A Lock-Free Stack: A Hazard Pointer Implementation Explained I"},"content":{"rendered":"\n<p>In my last post, I presented a hazard pointer implementation: <a href=\"https:\/\/www.modernescpp.com\/index.php\/a-lock-free-stack-a-hazard-pointer-implementation\/\">A Lock-Free Stack: A Hazard Pointer Implementation<\/a>. Today, I will explain the implementation.<\/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:711px;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<p><code>MyNode <\/code>is a class template, parametrized by the type it holds:<code> data. MyNode <\/code>models the concept <code>Node<\/code>.<\/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: #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>\nconcept Node <span style=\"color: #555555\">=<\/span> requires(T a) {\n    {T<span style=\"color: #555555\">::<\/span>data};\n    { <span style=\"color: #555555\">*<\/span>a.next } <span style=\"color: #555555\">-&gt;<\/span> std<span style=\"color: #555555\">::<\/span>same_as<span style=\"color: #555555\">&lt;<\/span>T<span style=\"color: #555555\">&amp;&gt;<\/span>;\n};\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\">struct<\/span> MyNode {\n    T data;\n    MyNode<span style=\"color: #555555\">*<\/span> next;\n    MyNode(T d)<span style=\"color: #555555\">:<\/span> data(d), next(nullptr){ }\n};\n<\/pre><\/div>\n\n\n\n<p>Concepts are compile-time predicates. They put semantic constraints on template parameters. The concept <code>Node <\/code>requires member <code>data<\/code> and a pointer <code>next <\/code>that returns a <code>Node<\/code>. The program <code>lockFreeStackHazardPointers.cpp <\/code>types are essentially parametrized on the <code>data <\/code>member and the concept<code> Node. MyNode<\/code> models the concept <code>Node<\/code>. For example, here is the declaration of the <code>LockFreeStack<\/code>:<\/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: #006699; font-weight: bold\">template<\/span><span style=\"color: #555555\">&lt;<\/span><span style=\"color: #006699; font-weight: bold\">typename<\/span> T, Node MyNode <span style=\"color: #555555\">=<\/span> MyNode<span style=\"color: #555555\">&lt;<\/span>T<span style=\"color: #555555\">&gt;&gt;<\/span>\n\n<span style=\"color: #006699; font-weight: bold\">class<\/span> <span style=\"color: #00AA88; font-weight: bold\">LockFreeStack<\/span>;\n<\/pre><\/div>\n\n\n\n<p>Let me continue my analysis of the program with the lock-free 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%\">template<span style=\"color: #555555\">&lt;<\/span><span style=\"color: #006699; font-weight: bold\">typename<\/span> T, Node MyNode <span style=\"color: #555555\">=<\/span> MyNode<span style=\"color: #555555\">&lt;<\/span>T<span style=\"color: #555555\">&gt;&gt;<\/span>\n<span style=\"color: #006699; font-weight: bold\">class<\/span> <span style=\"color: #00AA88; font-weight: bold\">LockFreeStack<\/span> {\n\n    std<span style=\"color: #555555\">::<\/span>atomic<span style=\"color: #555555\">&lt;<\/span>MyNode<span style=\"color: #555555\">*&gt;<\/span> head;\n    RetireList<span style=\"color: #555555\">&lt;<\/span>T<span style=\"color: #555555\">&gt;<\/span> retireList;\n \n <span style=\"color: #9999FF\">public:<\/span>\n    LockFreeStack() <span style=\"color: #555555\">=<\/span> <span style=\"color: #006699; font-weight: bold\">default<\/span>;\n    LockFreeStack(<span style=\"color: #006699; font-weight: bold\">const<\/span> LockFreeStack<span style=\"color: #555555\">&amp;<\/span>) <span style=\"color: #555555\">=<\/span> <span style=\"color: #006699; font-weight: bold\">delete<\/span>;\n    LockFreeStack<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> LockFreeStack<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        MyNode<span style=\"color: #555555\">*<\/span> <span style=\"color: #006699; font-weight: bold\">const<\/span> newMyNode <span style=\"color: #555555\">=<\/span> <span style=\"color: #006699; font-weight: bold\">new<\/span> MyNode(val);\n        newMyNode<span style=\"color: #555555\">-&gt;<\/span>next <span style=\"color: #555555\">=<\/span> head.load();\n        <span style=\"color: #006699; font-weight: bold\">while<\/span>( <span style=\"color: #555555\">!<\/span>head.compare_exchange_strong(newMyNode<span style=\"color: #555555\">-&gt;<\/span>next, newMyNode) );\n    }\n\n    T <span style=\"color: #CC00FF\">topAndPop<\/span>() {\n        std<span style=\"color: #555555\">::<\/span>atomic<span style=\"color: #555555\">&lt;<\/span>MyNode<span style=\"color: #555555\">*&gt;&amp;<\/span> hazardPointer <span style=\"color: #555555\">=<\/span> getHazardPointer<span style=\"color: #555555\">&lt;<\/span>T<span style=\"color: #555555\">&gt;<\/span>();\n        MyNode<span style=\"color: #555555\">*<\/span> oldHead <span style=\"color: #555555\">=<\/span> head.load();\n        <span style=\"color: #006699; font-weight: bold\">do<\/span> {\n            MyNode<span style=\"color: #555555\">*<\/span> tempMyNode; \n            <span style=\"color: #006699; font-weight: bold\">do<\/span> {\n                tempMyNode <span style=\"color: #555555\">=<\/span> oldHead;\n                hazardPointer.store(oldHead);\n                oldHead <span style=\"color: #555555\">=<\/span> head.load();\n            } <span style=\"color: #006699; font-weight: bold\">while<\/span>( oldHead <span style=\"color: #555555\">!=<\/span> tempMyNode );\n        } <span style=\"color: #006699; font-weight: bold\">while<\/span>( oldHead <span style=\"color: #555555\">&amp;&amp;<\/span> <span style=\"color: #555555\">!<\/span>head.compare_exchange_strong(oldHead, oldHead<span style=\"color: #555555\">-&gt;<\/span>next) ) ;\n        <span style=\"color: #006699; font-weight: bold\">if<\/span> ( <span style=\"color: #555555\">!<\/span>oldHead ) <span style=\"color: #006699; font-weight: bold\">throw<\/span> std<span style=\"color: #555555\">::<\/span>out_of_range(<span style=\"color: #CC3300\">&quot;The stack is empty!&quot;<\/span>);\n        hazardPointer.store(nullptr);\n        <span style=\"color: #006699; font-weight: bold\">auto<\/span> res <span style=\"color: #555555\">=<\/span> oldHead<span style=\"color: #555555\">-&gt;<\/span>data;\n        <span style=\"color: #006699; font-weight: bold\">if<\/span> ( retireList.isInUse(oldHead) ) retireList.addNode(oldHead);\n        <span style=\"color: #006699; font-weight: bold\">else<\/span> <span style=\"color: #006699; font-weight: bold\">delete<\/span> oldHead;\n        retireList.deleteUnusedNodes();\n        <span style=\"color: #006699; font-weight: bold\">return<\/span> res;\n    }\n};\n<\/pre><\/div>\n\n\n\n<p>The <code>push <\/code>call is not critical from a concurrency perspective because <code>head <\/code>is updated in an atomic step. Additionally, the <code>compare_exchange_strong <\/code>call guarantees that <code>head <\/code>is always the current head of the stack.<\/p>\n\n\n\n<p>Due to hazard pointers, the call <code>topAndPop <\/code>becomes more complicated. First, the function <code>getHazardPointer <\/code>references the hazard pointer for the current thread. The call <code>hazardPointer.store(oldHead)<\/code> makes the current thread to the owner of the hazard pointer, and the call<code> hazardPointer.store(nullptr)<\/code>releases its ownership. First, let me analyze the inner and outer do-while loops. The inner do-while loop sets the hazard pointer to the head of the stack. The do-while loop ends when the following holds: <code>oldHead ==<\/code> <code>tempNode<\/code>. Both nodes are equal if <code>oldHead <\/code>is still the current head of the lock-free stack. <code>oldHead <\/code>was set and could not be the current head anymore because another thread may be kicked in and already managed <code>oldHead<\/code>. The outer do-while loop should be familiar from the previous lock-free stack implementations. I iterate in the while loop using <code>compare_exchange_strong <\/code>and set the <code>head <\/code>to <code>oldHead->next.<\/code> In the end, <code>head <\/code>is the head of the stack. Remember, the member function <code>topAndPop <\/code>should return the value of the head and remove it. Before I use <code>oldHead <\/code>I have to check if <code>oldHead <\/code>is not a null pointer. If <code>oldHead <\/code>is a null pointer, I throw an exception. The rest of the <code>topAndPop <\/code>is straightforward. \u00a0The call <code>retireList.isInUse(oldHead)<\/code> checks if <code>oldHead <\/code>is still in use. Depending on this check, <code>oldHead <\/code>is added to the retire list <code>retireList.addNode<\/code> if it is not yet on the list or deleted. The last call <code>retireList.deleteUnusedNodes<\/code> is the most labor-intensive call in the member function <code>topAndPop<\/code>. The member function <code>retireListe.deleteUnusedNodes<\/code> traverses the entire retire list and deletes all nodes that are not used anymore.<\/p>\n\n\n\n<p>For performance reasons, the call<code> retireList.deleteUnusedNodes <\/code>should not be executed in each call of <code>topAndPop<\/code>. An improved strategy is to invoke the member function <code>deleteUnusedNodes<\/code> if the length of the retire list exceeds a specific threshold. For example, when the length of the retire list is twice the length of the stack, at least half of the nodes can be deleted. This threshold value is a trade-off between performance requirements and memory consumption.<\/p>\n\n\n\n<p>Let me continue my explanation with the free function <code>getHazardPointer<\/code>.<\/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: #006699; font-weight: bold\">template<\/span> <span style=\"color: #555555\">&lt;<\/span><span style=\"color: #006699; font-weight: bold\">typename<\/span> T, Node MyNode <span style=\"color: #555555\">=<\/span> MyNode<span style=\"color: #555555\">&lt;<\/span>T<span style=\"color: #555555\">&gt;&gt;<\/span>\nsttd<span style=\"color: #555555\">::<\/span>atomic<span style=\"color: #555555\">&lt;<\/span>MyNode<span style=\"color: #555555\">*&gt;&amp;<\/span> getHazardPointer() {\n    thread_local <span style=\"color: #006699; font-weight: bold\">static<\/span> HazardPointerOwner<span style=\"color: #555555\">&lt;<\/span>T<span style=\"color: #555555\">&gt;<\/span> hazard;\n    <span style=\"color: #006699; font-weight: bold\">return<\/span> hazard.getPointer();\n}\n<\/pre><\/div>\n\n\n\n<p>The function <code>getHazardPointer <\/code>references a hazard pointer using the hazard pointer owner<code> hazard. hazard<\/code> is a thread-local and static variable. Therefore, each thread gets its copy of the hazard pointer owner, and its lifetime is bound to the lifetime of the owning thread. The bound lifetime of the hazard pointer owner is crucial because it guarantees the hazard pointer is cleared when the thread-local hazard pointer owner is destroyed. I write more about this RAII object in my analysis of the class type <code>HazardPointerOwner<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What&#8217;s Next?<\/h2>\n\n\n\n<p>In my next post, I will explain the remaining implementation.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In my last post, I presented a hazard pointer implementation: A Lock-Free Stack: A Hazard Pointer Implementation. Today, I will explain the implementation. MyNode is a class template, parametrized by the type it holds: data. MyNode models the concept Node. template &lt;typename T&gt; concept Node = requires(T a) { {T::data}; { *a.next } -&gt; std::same_as&lt;T&amp;&gt;; [&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-10705","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\/10705","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=10705"}],"version-history":[{"count":5,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/10705\/revisions"}],"predecessor-version":[{"id":10710,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/10705\/revisions\/10710"}],"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=10705"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=10705"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=10705"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}