[PATCH v2 0/3] libstdc++: Implement std::hazard_pointer (P2530R3)

Paul Xi Cao <[email protected]>
Newsgroups gmane.comp.gcc.patches,gmane.comp.gcc.libstdc++.devel
Message-ID <[email protected]>
This is v2 of the std::hazard_pointer series, addressing Thomas
Rodgers' review of v1:

  https://gcc.gnu.org/pipermail/libstdc++/2026-July/067282.html

The public API is unchanged from v1; everything below is internal.
Point-by-point answers, the measurements, and two questions for the
maintainers are in my reply on that thread.

  R1  reclaim-side ordering     fixed  seq_cst fence in _M_synchronize,
                                       between collect and scan
  R2  retire() allocates        fixed  intrusive retire link in the
                                       object -- this freezes the
                                       layout of a type users derive
                                       from, see below
  R3  slot acquire/release      fixed  lock-free claim and release;
                                       3.8x at 16 threads, 1.13x at
                                       one, and one case slower
                                       than v1
  R4  concurrent.cc could not   fixed  rewritten and validated by
      fail                             negative control
  R5  version.h not regenerated fixed  self-found; the feature-test
                                       macro was not gthread/hosted
                                       gated in v1
  R6  ChangeLog indentation     fixed  self-found

Series layout, unchanged from v1:

  [1/3] libstdc++: Add infrastructure for std::hazard_pointer (C++26)
        <hazard_pointer> header, bits/hazard_ptr.h stub, version.def
        entry, Makefile.am registration, feature-test macro tests.
        Now includes the regenerated version.h (R5).

  [2/3] libstdc++: Implement std::hazard_pointer (P2530R3)
        Full implementation.  Carries R1, R2 and R3; the commit
        message has the reasoning for each.

  [3/3] libstdc++: Add tests for std::hazard_pointer
        20 files, up from 18: the rewritten concurrent.cc (R4), plus
        the new retire_no_alloc.cc and layout.cc, which pin the two
        claims R2 makes.  With the two feature-test macro tests in
        1/3 that is 22 in 30_threads/hazard_pointer/.

One item needs a maintainer decision rather than a review comment.
Fixing retire() requires the retire-list link to live inside
hazard_pointer_obj_base, which changes the layout of a
standard-specified type that users derive from -- so its size lands in
user binaries, and doc/xml/manual/abi.xml lists that as a prohibited
change after release.  v2 therefore takes P2530R3 sec. 1.5 at its word
and reserves the two extensions it names, a cohort pointer and a
64-bit counter, now rather than later.  Whether this is the right
moment to freeze that layout is a maintainer call; the argument is in
the review thread.

Tested on x86_64-pc-linux-gnu: 42/42 pass at -std=gnu++26 across the
22 files, including the negative compile tests, and both negative
controls fire.  In the standalone prototype the same algorithm is ASan
and TSan clean, gated by three herd7 litmus tests in CI, and green on
gcc, clang and MSVC.  I can post the litmus tests separately if that
is useful; they have no home in this tree.

The concurrent tests still run without a TSan target_board, as in v1.
The prototype runs the same test bodies under -fsanitize=thread in CI;
happy to add a parallel run under the libstdc++ tsan options if
reviewers would rather have it in the series than take my word for it.

Prototype repository, as in v1 -- single-header, namespace proto, and
the source of the measurements in the review thread:

  https://github.com/PaulXiCao/hazard_pointer_prototype

Still deferred, as in v1: contracts-based preconditions, waiting on a
macro that distinguishes "contracts are evaluated" from
__cpp_contracts.  Deferred deliberately, and new in v2: per-thread
record caching, which is the fix for the one case that is slower than
v1.  It is ABI-neutral, so it need not land with this series; the
argument for deferring rather than holding v2 is in the review thread.

The header is reformatted to libstdc++ house style in this version,
which makes a range-diff against v1 useless, hence the summary above.

Disclosure: the prose of this message was rephrased with LLM
assistance.

Paul Xi Cao (3):
  libstdc++: Add infrastructure for std::hazard_pointer (C++26)
  libstdc++: Implement std::hazard_pointer (P2530R3)
  libstdc++: Add tests for std::hazard_pointer

 libstdc++-v3/include/Makefile.am              |    2 +
 libstdc++-v3/include/Makefile.in              |    2 +
 libstdc++-v3/include/bits/hazard_ptr.h        | 1089 +++++++++++++++++
 libstdc++-v3/include/bits/version.def         |   10 +
 libstdc++-v3/include/bits/version.h           |   10 +
 libstdc++-v3/include/std/hazard_pointer       |   44 +
 .../testsuite/30_threads/hazard_pointer/1.cc  |   28 +
 .../30_threads/hazard_pointer/concurrent.cc   |  406 ++++++
 .../30_threads/hazard_pointer/ctor.cc         |  102 ++
 .../hazard_pointer/custom_deleter.cc          |  126 ++
 .../30_threads/hazard_pointer/empty.cc        |  105 ++
 .../30_threads/hazard_pointer/layout.cc       |   85 ++
 .../hazard_pointer/make_hazard_pointer.cc     |   84 ++
 .../30_threads/hazard_pointer/move_assign.cc  |   91 ++
 .../hazard_pointer/nodiscard_neg.cc           |   58 +
 .../30_threads/hazard_pointer/noexcept.cc     |   56 +
 .../30_threads/hazard_pointer/protect.cc      |   96 ++
 .../30_threads/hazard_pointer/protect_neg.cc  |   43 +
 .../hazard_pointer/reset_protection.cc        |  116 ++
 .../30_threads/hazard_pointer/retire.cc       |  119 ++
 .../30_threads/hazard_pointer/retire_neg.cc   |   39 +
 .../hazard_pointer/retire_no_alloc.cc         |  213 ++++
 .../hazard_pointer/retire_virtual_neg.cc      |   40 +
 .../30_threads/hazard_pointer/swap.cc         |  133 ++
 .../30_threads/hazard_pointer/thread_exit.cc  |   98 ++
 .../30_threads/hazard_pointer/try_protect.cc  |  132 ++
 .../hazard_pointer/type_constraints.cc        |   56 +
 .../30_threads/hazard_pointer/version.cc      |   29 +
 28 files changed, 3412 insertions(+)
 create mode 100644 libstdc++-v3/include/bits/hazard_ptr.h
 create mode 100644 libstdc++-v3/include/std/hazard_pointer
 create mode 100644 libstdc++-v3/testsuite/30_threads/hazard_pointer/1.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/hazard_pointer/concurrent.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/hazard_pointer/ctor.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/hazard_pointer/custom_deleter.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/hazard_pointer/empty.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/hazard_pointer/layout.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/hazard_pointer/make_hazard_pointer.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/hazard_pointer/move_assign.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/hazard_pointer/nodiscard_neg.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/hazard_pointer/noexcept.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/hazard_pointer/protect.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/hazard_pointer/protect_neg.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/hazard_pointer/reset_protection.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/hazard_pointer/retire.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/hazard_pointer/retire_neg.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/hazard_pointer/retire_no_alloc.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/hazard_pointer/retire_virtual_neg.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/hazard_pointer/swap.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/hazard_pointer/thread_exit.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/hazard_pointer/try_protect.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/hazard_pointer/type_constraints.cc
 create mode 100644 libstdc++-v3/testsuite/30_threads/hazard_pointer/version.cc

-- 
2.54.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.