[libcxx-commits] [libcxx] [libc++] Impelement P2545R4 Read-Copy Update (RCU) (PR #175451)
via libcxx-commits
libcxx-commits at lists.llvm.org
Sun Jan 25 02:48:21 PST 2026
github-actions[bot] wrote:
<!--LLVM CODE FORMAT COMMENT: {clang-format}-->
:warning: C/C++ code formatter, clang-format found issues in your code. :warning:
<details>
<summary>
You can test this locally with the following command:
</summary>
``````````bash
git-clang-format --diff origin/main HEAD --extensions ,cpp,inc,h -- libcxx/include/__rcu/rcu_domain.h libcxx/include/__rcu/rcu_list.h libcxx/include/__rcu/rcu_obj_base.h libcxx/include/rcu libcxx/test/std/language.support/support.limits/support.limits.general/rcu.version.compile.pass.cpp libcxx/test/std/thread/saferecl/saferecl.rcu/general.pass.cpp libcxx/test/std/thread/saferecl/saferecl.rcu/read_write_lock_compare.pass.cpp libcxx/test/std/thread/saferecl/saferecl.rcu/retire.pass.cpp libcxx/include/__configuration/experimental.h libcxx/include/version libcxx/modules/std/rcu.inc libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp --diff_from_common_commit
``````````
:warning:
The reproduction instructions above might return results for more than one PR
in a stack if you are using a stacked PR workflow. You can limit the results by
changing `origin/main` to the base branch/commit you want to compare against.
:warning:
</details>
<details>
<summary>
View the diff from clang-format here.
</summary>
``````````diff
diff --git a/libcxx/include/__rcu/rcu_domain.h b/libcxx/include/__rcu/rcu_domain.h
index 3ac359728..75439fce4 100644
--- a/libcxx/include/__rcu/rcu_domain.h
+++ b/libcxx/include/__rcu/rcu_domain.h
@@ -148,7 +148,7 @@ class rcu_domain {
void __synchronize() noexcept {
__cxx_atomic_thread_fence(memory_order_seq_cst);
std::unique_lock __lk(__grace_period_mutex_);
- //std::printf("rcu_domain::__synchronize() going through phase 1\n");
+ // std::printf("rcu_domain::__synchronize() going through phase 1\n");
auto __ready_callbacks = __update_phase_and_wait();
// Invoke the ready callbacks outside of the grace period mutex
@@ -157,7 +157,7 @@ class rcu_domain {
__lk.lock();
__barrier();
- //std::printf("rcu_domain::__synchronize() going through phase 2\n");
+ // std::printf("rcu_domain::__synchronize() going through phase 2\n");
__ready_callbacks = __update_phase_and_wait();
// Invoke the ready callbacks outside of the grace period mutex
@@ -175,7 +175,7 @@ class rcu_domain {
auto __old_phase =
__global_reader_phase_.fetch_xor(__reader_states::__grace_period_phase_mask, std::memory_order_relaxed);
auto __new_phase = __old_phase ^ __reader_states::__grace_period_phase_mask;
- //std::printf("rcu_domain::__update_phase_and_wait() new phase: 0x%04x\n", __new_phase);
+ // std::printf("rcu_domain::__update_phase_and_wait() new phase: 0x%04x\n", __new_phase);
__barrier();
// Wait for all threads to quiesce in the old phase
diff --git a/libcxx/include/__rcu/rcu_list.h b/libcxx/include/__rcu/rcu_list.h
index 2547d7223..933d2faec 100644
--- a/libcxx/include/__rcu/rcu_list.h
+++ b/libcxx/include/__rcu/rcu_list.h
@@ -71,7 +71,6 @@ public:
}
};
-
#endif // _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_THREADS && _LIBCPP_HAS_EXPERIMENTAL_RCU
_LIBCPP_END_NAMESPACE_STD
diff --git a/libcxx/include/__rcu/rcu_obj_base.h b/libcxx/include/__rcu/rcu_obj_base.h
index 3d1de3536..41a1c107a 100644
--- a/libcxx/include/__rcu/rcu_obj_base.h
+++ b/libcxx/include/__rcu/rcu_obj_base.h
@@ -28,8 +28,7 @@ class rcu_obj_base : private __rcu_node {
public:
void retire(D d = D(), rcu_domain& dom = rcu_default_domain()) noexcept {
auto ptr = static_cast<T*>(this);
- dom.__retire_callback(
- [ptr, d = std::move(d)]() mutable { d(ptr); });
+ dom.__retire_callback([ptr, d = std::move(d)]() mutable { d(ptr); });
}
protected:
@@ -39,7 +38,6 @@ protected:
rcu_obj_base& operator=(const rcu_obj_base&) = default;
rcu_obj_base& operator=(rcu_obj_base&&) = default;
~rcu_obj_base() = default;
-
};
#endif // _LIBCPP_STD_VER >= 26 && _LIBCPP_HAS_THREADS && _LIBCPP_HAS_EXPERIMENTAL_RCU
diff --git a/libcxx/modules/std/rcu.inc b/libcxx/modules/std/rcu.inc
index 0dbad7264..26b39a90c 100644
--- a/libcxx/modules/std/rcu.inc
+++ b/libcxx/modules/std/rcu.inc
@@ -16,5 +16,5 @@ export namespace std {
using std::rcu_barrier;
using std::rcu_retire;
using std::rcu_synchronize;
-# endif // _LIBCPP_STD_VER >= 23
+#endif // _LIBCPP_STD_VER >= 23
} // namespace std
diff --git a/libcxx/test/std/thread/saferecl/saferecl.rcu/general.pass.cpp b/libcxx/test/std/thread/saferecl/saferecl.rcu/general.pass.cpp
index 88412976f..d85861d9b 100644
--- a/libcxx/test/std/thread/saferecl/saferecl.rcu/general.pass.cpp
+++ b/libcxx/test/std/thread/saferecl/saferecl.rcu/general.pass.cpp
@@ -39,7 +39,7 @@ int main(int, char**) {
std::this_thread::sleep_for(std::chrono::seconds(1));
log(start, "t1: leaving rcu read-side critical section " + std::to_string(i));
dom.unlock();
- log(start, "t1: printing all reader states");
+ log(start, "t1: printing all reader states");
dom.printAllReaderStatesInHex();
}
});
@@ -54,7 +54,7 @@ int main(int, char**) {
std::this_thread::sleep_for(std::chrono::seconds(1));
log(start, "t2: leaving rcu read-side critical section " + std::to_string(i));
dom.unlock();
- log(start, "t2: printing all reader states");
+ log(start, "t2: printing all reader states");
dom.printAllReaderStatesInHex();
}
});
@@ -69,7 +69,7 @@ int main(int, char**) {
std::this_thread::sleep_for(std::chrono::seconds(1));
log(start, "t3: leaving rcu read-side critical section " + std::to_string(i));
dom.unlock();
- log(start, "t3: printing all reader states");
+ log(start, "t3: printing all reader states");
dom.printAllReaderStatesInHex();
}
});
@@ -83,7 +83,7 @@ int main(int, char**) {
std::this_thread::sleep_for(std::chrono::seconds(1));
log(start, "t4: leaving rcu read-side critical section " + std::to_string(i));
dom.unlock();
- log(start, "t4: printing all reader states");
+ log(start, "t4: printing all reader states");
dom.printAllReaderStatesInHex();
}
});
@@ -99,15 +99,13 @@ int main(int, char**) {
}); */
std::this_thread::sleep_for(std::chrono::milliseconds(10));
- for (int i = 0; i < loop_num+5; ++i) {
-
- log(start, "t0: calling rcu_synchronize" + std::to_string(i));
- std::rcu_synchronize();
- log(start, "t0: rcu_synchronize returned" + std::to_string(i));
+ for (int i = 0; i < loop_num + 5; ++i) {
+ log(start, "t0: calling rcu_synchronize" + std::to_string(i));
+ std::rcu_synchronize();
+ log(start, "t0: rcu_synchronize returned" + std::to_string(i));
std::this_thread::sleep_for(std::chrono::seconds(1));
}
-
t1.join();
t2.join();
t3.join();
diff --git a/libcxx/test/std/thread/saferecl/saferecl.rcu/read_write_lock_compare.pass.cpp b/libcxx/test/std/thread/saferecl/saferecl.rcu/read_write_lock_compare.pass.cpp
index 2fc790139..4ac3f1b8d 100644
--- a/libcxx/test/std/thread/saferecl/saferecl.rcu/read_write_lock_compare.pass.cpp
+++ b/libcxx/test/std/thread/saferecl/saferecl.rcu/read_write_lock_compare.pass.cpp
@@ -45,7 +45,6 @@ struct alignas(128) MyObject : public std::rcu_obj_base<MyObject> {
}
};
-
void test_read_write_lock() {
MyObject* globalObjRWLock = new MyObject();
std::shared_mutex globalObjMutex;
@@ -92,7 +91,7 @@ void test_read_write_lock() {
}
void test_rcu() {
- std::rcu_domain& dom = std::rcu_default_domain();
+ std::rcu_domain& dom = std::rcu_default_domain();
std::atomic<MyObject*> global_obj_rcu = new MyObject();
std::vector<std::jthread> readers;
diff --git a/libcxx/test/std/thread/saferecl/saferecl.rcu/retire.pass.cpp b/libcxx/test/std/thread/saferecl/saferecl.rcu/retire.pass.cpp
index dde6cdd32..4267e8656 100644
--- a/libcxx/test/std/thread/saferecl/saferecl.rcu/retire.pass.cpp
+++ b/libcxx/test/std/thread/saferecl/saferecl.rcu/retire.pass.cpp
@@ -35,9 +35,7 @@ struct MyObject : public std::rcu_obj_base<MyObject> {
inline static int instance_count = 0;
MyObject() : data_(std::to_string(instance_count++) + " instance very very very long string") {}
- ~MyObject() {
- std::println(std::cout, "MyObject {} destructor called", data_);
- }
+ ~MyObject() { std::println(std::cout, "MyObject {} destructor called", data_); }
};
std::atomic<MyObject*> global_obj = nullptr;
@@ -52,8 +50,9 @@ int main(int, char**) {
auto obj = global_obj.load();
log(start, "t1: reading: " + (obj ? obj->data_ : "nullptr"));
std::this_thread::sleep_for(std::chrono::seconds(1));
- log(start, "t1: leaving rcu read-side critical section " + std::to_string(i) + " with object " +
- (obj ? obj->data_ : "nullptr"));
+ log(start,
+ "t1: leaving rcu read-side critical section " + std::to_string(i) + " with object " +
+ (obj ? obj->data_ : "nullptr"));
dom.unlock();
log(start, "t1: printing all reader states");
dom.printAllReaderStatesInHex();
@@ -69,8 +68,9 @@ int main(int, char**) {
auto obj = global_obj.load();
log(start, "t2: reading: " + (obj ? obj->data_ : "nullptr"));
std::this_thread::sleep_for(std::chrono::seconds(1));
- log(start, "t2: leaving rcu read-side critical section " + std::to_string(i) + " with object " +
- (obj ? obj->data_ : "nullptr"));
+ log(start,
+ "t2: leaving rcu read-side critical section " + std::to_string(i) + " with object " +
+ (obj ? obj->data_ : "nullptr"));
dom.unlock();
log(start, "t2: printing all reader states");
dom.printAllReaderStatesInHex();
@@ -86,8 +86,9 @@ int main(int, char**) {
auto obj = global_obj.load();
log(start, "t3: reading: " + (obj ? obj->data_ : "nullptr"));
std::this_thread::sleep_for(std::chrono::seconds(1));
- log(start, "t3: leaving rcu read-side critical section " + std::to_string(i) + " with object " +
- (obj ? obj->data_ : "nullptr"));
+ log(start,
+ "t3: leaving rcu read-side critical section " + std::to_string(i) + " with object " +
+ (obj ? obj->data_ : "nullptr"));
dom.unlock();
log(start, "t3: printing all reader states");
dom.printAllReaderStatesInHex();
@@ -102,8 +103,9 @@ int main(int, char**) {
auto obj = global_obj.load();
log(start, "t4: reading: " + (obj ? obj->data_ : "nullptr"));
std::this_thread::sleep_for(std::chrono::seconds(1));
- log(start, "t4: leaving rcu read-side critical section " + std::to_string(i) + " with object " +
- (obj ? obj->data_ : "nullptr"));
+ log(start,
+ "t4: leaving rcu read-side critical section " + std::to_string(i) + " with object " +
+ (obj ? obj->data_ : "nullptr"));
dom.unlock();
log(start, "t4: printing all reader states");
dom.printAllReaderStatesInHex();
``````````
</details>
https://github.com/llvm/llvm-project/pull/175451
More information about the libcxx-commits
mailing list