{"id":10715,"date":"2025-04-07T11:11:06","date_gmt":"2025-04-07T11:11:06","guid":{"rendered":"https:\/\/www.modernescpp.com\/?p=10715"},"modified":"2025-07-03T14:40:14","modified_gmt":"2025-07-03T14:40:14","slug":"a-lock-free-stack-a-hazard-pointer-implementation-explained-ii","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/a-lock-free-stack-a-hazard-pointer-implementation-explained-ii\/","title":{"rendered":"A Lock-Free Stack: A Hazard Pointer Implementation Explained II"},"content":{"rendered":"\n<p>In my last post, I started to explain a hazard pointer implementation: <a href=\"https:\/\/www.modernescpp.com\/index.php\/a-lock-free-stack-a-hazard-pointer-implementation-explained-i\/\">A Lock-Free Stack: A Hazard Pointer Implementation Explained I<\/a>. Today, I will continue to 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<h2 class=\"wp-block-heading\">The Retire List<\/h2>\n\n\n\n<p>The retire list has the public member functions <code>isInUse<\/code>, <code>addNode<\/code>, and <code>deleteUnusedNodes<\/code>. Additionally, it has the inner class <code>RetireNode<\/code>, an atomic member of it, and the private member function <code>addToRetiredNodes<\/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<span style=\"color: #006699; font-weight: bold\">class<\/span> <span style=\"color: #00AA88; font-weight: bold\">RetireList<\/span> {\n\n    <span style=\"color: #006699; font-weight: bold\">struct<\/span> RetiredNode {\n        MyNode<span style=\"color: #555555\">*<\/span> node;\n        RetiredNode<span style=\"color: #555555\">*<\/span> next;\n        RetiredNode(MyNode<span style=\"color: #555555\">*<\/span> p) <span style=\"color: #555555\">:<\/span> node(p), next(nullptr) { }\n        <span style=\"color: #555555\">~<\/span>RetiredNode() {\n            <span style=\"color: #006699; font-weight: bold\">delete<\/span> node;\n        }\n    };\n\n    std<span style=\"color: #555555\">::<\/span>atomic<span style=\"color: #555555\">&lt;<\/span>RetiredNode<span style=\"color: #555555\">*&gt;<\/span> RetiredNodes;\n\n    <span style=\"color: #007788; font-weight: bold\">void<\/span> <span style=\"color: #CC00FF\">addToRetiredNodes<\/span>(RetiredNode<span style=\"color: #555555\">*<\/span> retiredNode) {\n        retiredNode<span style=\"color: #555555\">-&gt;<\/span>next <span style=\"color: #555555\">=<\/span> RetiredNodes.load();\n        <span style=\"color: #006699; font-weight: bold\">while<\/span> (<span style=\"color: #555555\">!<\/span>RetiredNodes.compare_exchange_strong(retiredNode<span style=\"color: #555555\">-&gt;<\/span>next, retiredNode));\n    }\n\n <span style=\"color: #9999FF\">public:<\/span>\n\n    <span style=\"color: #007788; font-weight: bold\">bool<\/span> <span style=\"color: #CC00FF\">isInUse<\/span>(MyNode<span style=\"color: #555555\">*<\/span> node) {\n        <span style=\"color: #006699; font-weight: bold\">for<\/span> (std<span style=\"color: #555555\">::<\/span><span style=\"color: #007788; font-weight: bold\">size_t<\/span> i <span style=\"color: #555555\">=<\/span> <span style=\"color: #FF6600\">0<\/span>; i <span style=\"color: #555555\">&lt;<\/span> MaxHazardPointers; <span style=\"color: #555555\">++<\/span>i) {\n            <span style=\"color: #006699; font-weight: bold\">if<\/span> (HazardPointers<span style=\"color: #555555\">&lt;<\/span>T<span style=\"color: #555555\">&gt;<\/span>[i].pointer.load() <span style=\"color: #555555\">==<\/span> node) <span style=\"color: #006699; font-weight: bold\">return<\/span> <span style=\"color: #336666\">true<\/span>;\n        }\n        <span style=\"color: #006699; font-weight: bold\">return<\/span> <span style=\"color: #336666\">false<\/span>;\n    }\n\n    <span style=\"color: #007788; font-weight: bold\">void<\/span> <span style=\"color: #CC00FF\">addNode<\/span>(MyNode<span style=\"color: #555555\">*<\/span> node) {\n        addToRetiredNodes(<span style=\"color: #006699; font-weight: bold\">new<\/span> RetiredNode(node));\n    }\n\n    <span style=\"color: #007788; font-weight: bold\">void<\/span> <span style=\"color: #CC00FF\">deleteUnusedNodes<\/span>() {\n        RetiredNode<span style=\"color: #555555\">*<\/span> current <span style=\"color: #555555\">=<\/span> RetiredNodes.exchange(nullptr);\n        <span style=\"color: #006699; font-weight: bold\">while<\/span> (current) {\n            RetiredNode<span style=\"color: #555555\">*<\/span> <span style=\"color: #006699; font-weight: bold\">const<\/span> next <span style=\"color: #555555\">=<\/span> current<span style=\"color: #555555\">-&gt;<\/span>next;\n            <span style=\"color: #006699; font-weight: bold\">if<\/span> (<span style=\"color: #555555\">!<\/span>isInUse(current<span style=\"color: #555555\">-&gt;<\/span>node)) <span style=\"color: #006699; font-weight: bold\">delete<\/span> current;\n            <span style=\"color: #006699; font-weight: bold\">else<\/span> addToRetiredNodes(current);\n            current <span style=\"color: #555555\">=<\/span> next;\n        }\n    }\n};\n<\/pre><\/div>\n\n\n\n<p>Let&#8217;s start with the interface of the type <code>RetireList<\/code>.<\/p>\n\n\n\n<p>The member function <code>isInUse<\/code> checks if <code>node <\/code>is in use. It does its job by traversing the <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/language\/variable_template\">variable template<\/a> <code>HazardPointers <\/code>that is parameterized on the type of data the node holds. <code>HazardPointers <\/code>is a C-array of <code>HazardPointer <\/code>of length 50. A <code>HazardPointer <\/code>consists of an atomic thread <code>id <\/code>and an atomic <code>pointer <\/code>to a node.<\/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%\">constexpr std<span style=\"color: #555555\">::<\/span><span style=\"color: #007788; font-weight: bold\">size_t<\/span> MaxHazardPointers <span style=\"color: #555555\">=<\/span> <span style=\"color: #FF6600\">50<\/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, 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\">struct<\/span> HazardPointer {\n    std<span style=\"color: #555555\">::<\/span>atomic<span style=\"color: #555555\">&lt;<\/span>std<span style=\"color: #555555\">::<\/span><span style=\"color: #006699; font-weight: bold\">thread<\/span><span style=\"color: #555555\">::<\/span>id<span style=\"color: #555555\">&gt;<\/span> id;\n    std<span style=\"color: #555555\">::<\/span>atomic<span style=\"color: #555555\">&lt;<\/span>MyNode<span style=\"color: #555555\">*&gt;<\/span> pointer;\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>\nHazardPointer<span style=\"color: #555555\">&lt;<\/span>T<span style=\"color: #555555\">&gt;<\/span> HazardPointers[MaxHazardPointers];\n<\/pre><\/div>\n\n\n\n<p>Using an STL container such as <code>std::set <\/code>as <code>HazardPointers <\/code>is much more convenient. <code>std::set <\/code>is already ordered and guarantees constant access time on average but has a big issue: it&#8217;s not thread-safe.<\/p>\n\n\n\n<p>The member function <code>addNode <\/code>takes a node, invokes the private member function <code>addToRetiredNodes<\/code>, and puts the node into an <code>RetiredNode. RetiredNode <\/code> is an RAII object and guarantees that the wrapped node is destroyed, releasing its memory. All retired nodes build a singly-linked list.<\/p>\n\n\n\n<p>The member function <code>deleteUnusedNodes <\/code>traverses the singly-linked list of retired nodes by applying the following pattern:<\/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: #007788; font-weight: bold\">void<\/span> <span style=\"color: #CC00FF\">deleteUnusedNodes<\/span>() {\n        RetiredNode<span style=\"color: #555555\">*<\/span> current <span style=\"color: #555555\">=<\/span> RetiredNodes.exchange(nullptr);\n        <span style=\"color: #006699; font-weight: bold\">while<\/span> (current) {\n            RetiredNode<span style=\"color: #555555\">*<\/span> <span style=\"color: #006699; font-weight: bold\">const<\/span> next <span style=\"color: #555555\">=<\/span> current<span style=\"color: #555555\">-&gt;<\/span>next;\n            <span style=\"color: #006699; font-weight: bold\">if<\/span> (<span style=\"color: #555555\">!<\/span>isInUse(current<span style=\"color: #555555\">-&gt;<\/span>node)) <span style=\"color: #006699; font-weight: bold\">delete<\/span> current;\n            <span style=\"color: #006699; font-weight: bold\">else<\/span> addToRetiredNodes(current);\n            current <span style=\"color: #555555\">=<\/span> next;\n        }\n    }\n<\/pre><\/div>\n\n\n\n<p>It checks the current node, points the next node to <code>current-&gt;next<\/code> and updates the current node with the next node. Finally, the current node is destroyed if not used anymore or added to the retired nodes. The private member function <code>addToRetireNodes <\/code>adds the retired nodes to the singly-linked list. To perform its job, it loads the <code>RetiredNodes <\/code>and makes the new node <code>retiredNode <\/code>to the new head of the singly-linked list. Before <code>retiredNode <\/code>becoming the new head of the singly-linked list, I have to ensure that it is still the head of the singly-linked list because another thread could kick in and change the head of the singly-linked list in the meantime. Thanks to the while-loop, <code>retiredNode <\/code>becomes only the new head if <code>retiredNode-&gt;next = RetiredNodes.load()<\/code> holds. If not,<code> retiredNode-&gt;next<\/code> is updated to <code>RetiredNodes.load().<\/code><\/p>\n\n\n\n<p>There is only one piece of the puzzle left:<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Hazard Pointer Owner <\/h2>\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<span style=\"color: #006699; font-weight: bold\">class<\/span> <span style=\"color: #00AA88; font-weight: bold\">HazardPointerOwner<\/span> {\n\n    HazardPointer<span style=\"color: #555555\">&lt;<\/span>T<span style=\"color: #555555\">&gt;*<\/span> hazardPointer;\n\n <span style=\"color: #9999FF\">public:<\/span>\n    HazardPointerOwner(HazardPointerOwner <span style=\"color: #006699; font-weight: bold\">const<\/span> <span style=\"color: #555555\">&amp;<\/span>) <span style=\"color: #555555\">=<\/span> <span style=\"color: #006699; font-weight: bold\">delete<\/span>;\n    HazardPointerOwner <span style=\"color: #006699; font-weight: bold\">operator<\/span><span style=\"color: #555555\">=<\/span>(HazardPointerOwner <span style=\"color: #006699; font-weight: bold\">const<\/span> <span style=\"color: #555555\">&amp;<\/span>) <span style=\"color: #555555\">=<\/span> <span style=\"color: #006699; font-weight: bold\">delete<\/span>;\n\n    HazardPointerOwner() <span style=\"color: #555555\">:<\/span> hazardPointer(nullptr) {\n        <span style=\"color: #006699; font-weight: bold\">for<\/span> (std<span style=\"color: #555555\">::<\/span><span style=\"color: #007788; font-weight: bold\">size_t<\/span> i <span style=\"color: #555555\">=<\/span> <span style=\"color: #FF6600\">0<\/span>; i <span style=\"color: #555555\">&lt;<\/span> MaxHazardPointers; <span style=\"color: #555555\">++<\/span>i) {\n            std<span style=\"color: #555555\">::<\/span><span style=\"color: #006699; font-weight: bold\">thread<\/span><span style=\"color: #555555\">::<\/span>id old_id;\n            <span style=\"color: #006699; font-weight: bold\">if<\/span> (HazardPointers<span style=\"color: #555555\">&lt;<\/span>T<span style=\"color: #555555\">&gt;<\/span>[i].id.compare_exchange_strong(\n                                        old_id, std<span style=\"color: #555555\">::<\/span>this_thread<span style=\"color: #555555\">::<\/span>get_id())) {\n                hazardPointer <span style=\"color: #555555\">=<\/span> <span style=\"color: #555555\">&amp;<\/span>HazardPointers<span style=\"color: #555555\">&lt;<\/span>T<span style=\"color: #555555\">&gt;<\/span>[i];\n                <span style=\"color: #006699; font-weight: bold\">break<\/span>;\n            }\n        }\n        <span style=\"color: #006699; font-weight: bold\">if<\/span> (<span style=\"color: #555555\">!<\/span>hazardPointer) {\n            <span style=\"color: #006699; font-weight: bold\">throw<\/span> std<span style=\"color: #555555\">::<\/span>out_of_range(<span style=\"color: #CC3300\">&quot;No hazard pointers available!&quot;<\/span>);\n        }\n    }\n\n    std<span style=\"color: #555555\">::<\/span>atomic<span style=\"color: #555555\">&lt;<\/span>MyNode<span style=\"color: #555555\">*&gt;&amp;<\/span> getPointer() {\n        <span style=\"color: #006699; font-weight: bold\">return<\/span> hazardPointer<span style=\"color: #555555\">-&gt;<\/span>pointer;\n    }\n\n    <span style=\"color: #555555\">~<\/span>HazardPointerOwner() {\n        hazardPointer<span style=\"color: #555555\">-&gt;<\/span>pointer.store(nullptr);\n        hazardPointer<span style=\"color: #555555\">-&gt;<\/span>id.store(std<span style=\"color: #555555\">::<\/span><span style=\"color: #006699; font-weight: bold\">thread<\/span><span style=\"color: #555555\">::<\/span>id());\n    }\n};\n<\/pre><\/div>\n\n\n\n<p> <code>HazardPointerOwner <\/code>holds a <code>hazardPointer<\/code>. This <code>hazardPointer <\/code>is set in the constructor by traversing all <code>HazardPointers<\/code>. The <code>compare_exchange_strong <\/code>call checks in an atomic step if the currently traversed hazard pointer is not set and sets its id to the id of the now executed thread (<code>std::this_thread::get_id()<\/code>). In the success case, <code>hazardPointer <\/code>becomes the new hazard pointer returned to the client invoking the member function <code>getPointer<\/code>. When all of the hazard pointers of <code>HazardPointers <\/code>are used, the constructor throws a <code>std::out_of_range <\/code>exception. Finally, <code>HazardPointerOwner<\/code>&#8216;s destructor sets the <code>hazardPointer <\/code>to its default state.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What&#8217;s Next?<\/h2>\n\n\n\n<p>In C++26, we will get hazard pointers. I will write about them in my next post.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In my last post, I started to explain a hazard pointer implementation: A Lock-Free Stack: A Hazard Pointer Implementation Explained I. Today, I will continue to explain the implementation. The Retire List The retire list has the public member functions isInUse, addNode, and deleteUnusedNodes. Additionally, it has the inner class RetireNode, an atomic member of [&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-10715","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\/10715","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=10715"}],"version-history":[{"count":3,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/10715\/revisions"}],"predecessor-version":[{"id":10719,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/10715\/revisions\/10719"}],"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=10715"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=10715"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=10715"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}