{"id":10735,"date":"2025-05-05T11:12:54","date_gmt":"2025-05-05T11:12:54","guid":{"rendered":"https:\/\/www.modernescpp.com\/?p=10735"},"modified":"2025-07-03T14:41:03","modified_gmt":"2025-07-03T14:41:03","slug":"hazard-pointers-in-c26","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/hazard-pointers-in-c26\/","title":{"rendered":"Hazard Pointers in C++26"},"content":{"rendered":"\n<p>Hazard pointers provide garbage collection in C++ and solve the ABA problem. <\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><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\" 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>First of all. What is a hazard pointer? Proposal <a href=\"https:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2023\/p2530r3.pdf\">P2530R3 <\/a>gives a nice explanation:<\/p>\n\n\n\n<p><em>A hazard pointer is a single-writer multi-reader pointer that can be owned by at most one thread at any time. Only the owner of the hazard pointer can set its value, while any number of threads may read its value. A thread that is about to access dynamic objects acquires ownership of hazard pointer(s) to protect such objects from being reclaimed. The owner thread sets the value of a hazard pointer to point to an object in order to indicate to concurrent threads \u2014 that may remove such object \u2014 that the object is not yet safe to reclaim.<br>Hazard pointers are owned and written by threads that act as accessors\/protectors (i.e., protect removable objects from unsafe reclamation in order to access such objects) and are read by threads that act as removers\/reclaimers (i.e., may remove and try to reclaim objects). Removers retire removed objects to the hazard pointer library (i.e., pass the responsibility for reclaiming the objects to the library code rather than normally by user code). The set of protector and remover threads may overlap.<\/em><\/p>\n\n\n\n<p>To make it short, <strong>Hazard Pointers guarantee that the referenced objects are deleted if they are no longer needed.<\/strong><\/p>\n\n\n\n<p>Hazard pointers perform and interact with protection and deferred reclamation.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Protection <\/h3>\n\n\n\n<p>They guarantee that objects are only destroyed if they are no longer needed.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Deferred Reclamation<\/h3>\n\n\n\n<p>Collect the retired objects and extract their values into a set. Read the values of all hazard pointers and compare them with the addresses of the extracted values in the set. If a value from the set is not found in all values of the hazard pointers, it can be destroyed. If found, it will go back in the set of retired objects. <\/p>\n\n\n\n<p>So, what are the advantages of hazard pointers? My answer consists of two points: correctness and performance.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Advantage<\/h2>\n\n\n\n<p>I would like to start with correctness.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Correctness<\/h3>\n\n\n\n<p>The advantage of hazard pointers can be illustrated with a simple example.<\/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%\">Node<span style=\"color: #555555\">*<\/span> currentNode <span style=\"color: #555555\">=<\/span> <span style=\"color: #006699; font-weight: bold\">this<\/span><span style=\"color: #555555\">-&gt;<\/span>head;\nNode<span style=\"color: #555555\">*<\/span> nextNode <span style=\"color: #555555\">=<\/span> currentNode<span style=\"color: #555555\">-&gt;<\/span>next;\n<\/pre><\/div>\n\n\n\n<p>The critical question regarding this small code snippet is: how can we guarantee that <code>currentNode <\/code>is still valid? While one thread is executing this code, another thread may already be executing <code>currentNode<\/code>.<br><br>Atomic <a href=\"https:\/\/en.wikipedia.org\/wiki\/Compare-and-swap\" data-type=\"link\" data-id=\"https:\/\/en.wikipedia.org\/wiki\/Compare-and-swap\">compare-and-swap <\/a>(CAS) operations exacerbate this problem. In C++, the <code>compare_exchange_strong<\/code> operation is typically used for this purpose. However, CAS operations suffer from the ABA problem. I discuss the ABA problem in more detail in my article <a href=\"https:\/\/www.modernescpp.com\/index.php\/deferred-reclamation-in-c26-read-copy-update-and-hazard-pointers\/\" data-type=\"link\" data-id=\"https:\/\/www.modernescpp.com\/index.php\/deferred-reclamation-in-c26-read-copy-update-and-hazard-pointers\/\">Deferred Reclamation in C++26: Read-Copy Update and Hazard Pointers<\/a>. The solution to the problem is relatively obvious: automatic garbage collection. This is exactly what hazard pointers offer.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Performance<\/h3>\n\n\n\n<p><br>With C++14, reader-writer locks were introduced. With these special locks, reading threads are treated differently than writing threads. This means that any number of reading threads can be executed simultaneously, but only one writing thread. As a result, reader-writer locks promise a performance improvement over exclusive locks. More details on reader-writer locks can be found in my earlier article <a href=\"https:\/\/www.modernescpp.com\/index.php\/reader-writer-locks\/\" data-type=\"link\" data-id=\"https:\/\/www.modernescpp.com\/index.php\/reader-writer-locks\/\">Reader-Writer Locks<\/a>.<\/p>\n\n\n\n<p><br>Proposal <a href=\"https:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2023\/p2530r3.pdf\">P2530R3<\/a> provides a nice example of a data structure that is predominantly read. A classic reader-writer lock and hazard pointer are used.<br><br><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1030\" height=\"764\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/04\/grafik-1030x764.png\" alt=\"\" class=\"wp-image-10745\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/04\/grafik-1030x764.png 1030w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/04\/grafik-300x222.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/04\/grafik-768x570.png 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/04\/grafik-705x523.png 705w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2025\/04\/grafik.png 1223w\" sizes=\"auto, (max-width: 1030px) 100vw, 1030px\" \/><\/figure>\n\n\n\n<p><br><br><em>Typical latency of hazard_pointer construction\/destruction in the Folly implementation on contemporary commodity server is approximately 4 ns. Using a pre-constructed hazard_pointer typically takes under one nanosecond to stop for protection.<\/em><\/p>\n\n\n\n<p>Facebook&#8217;s open library <a href=\"https:\/\/github.com\/facebook\/folly\/blob\/main\/folly\/synchronization\/Hazptr.h\" data-type=\"link\" data-id=\"https:\/\/github.com\/facebook\/folly\/blob\/main\/folly\/synchronization\/Hazptr.h\">Folly<\/a> provides the reference implementation of hazard pointers.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Interface<\/h2>\n\n\n\n<p><br><br>Hazard Pointers consisting of the two classes <code>hazard_pointer_obj_base<\/code> and <code>hazard_pointer <\/code>and the two functions <code>make_hazard_pointer<\/code> and <code>swap<\/code>.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>hazard_pointer_obj_base<\/code> is the base class of the protected class, and provides the function <code>retire<\/code>.<\/li>\n\n\n\n<li><code>hazard_pointer<\/code> provides the functions <code>empty, protect, try_protect, reset_protection,<\/code>and <code>swap.<\/code><\/li>\n\n\n\n<li><code>make_hazard_pointer<\/code> creates a hazard pointer.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">What&#8217;s next?<\/h2>\n\n\n\n<p>RCU stands for Read Copy Update, a synchronization technique for almost read-only data structures created by Paul McKenney and used in the Linux kernel since 2002. RCU is currently mentioned in connection with hazard pointers.<\/p>\n\n\n\n<p><br><br><br><br><br><br><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hazard pointers provide garbage collection in C++ and solve the ABA problem. First of all. What is a hazard pointer? Proposal P2530R3 gives a nice explanation: A hazard pointer is a single-writer multi-reader pointer that can be owned by at most one thread at any time. Only the owner of the hazard pointer can set [&hellip;]<\/p>\n","protected":false},"author":21,"featured_media":10449,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[559],"tags":[563],"class_list":["post-10735","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\/10735","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=10735"}],"version-history":[{"count":7,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/10735\/revisions"}],"predecessor-version":[{"id":10747,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/10735\/revisions\/10747"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/10449"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=10735"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=10735"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=10735"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}