Require explicit copies for Ref/WeakRef
This commit is contained in:
@@ -27,6 +27,18 @@ template <typename T> struct PointerTraits<std::shared_ptr<T>> {
|
||||
return std::make_shared<T>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
static pointer_type copy(const pointer_type &ptr) {
|
||||
return ptr; // std::shared_ptr copies implicitly
|
||||
}
|
||||
|
||||
static weak_type as_weak(const pointer_type &ptr) {
|
||||
return ptr; // std::weak_ptr converts implicitly from std::shared_ptr
|
||||
}
|
||||
|
||||
static weak_type copy_weak(const weak_type &weak) {
|
||||
return weak; // std::weak_ptr copies implicitly
|
||||
}
|
||||
|
||||
static const char *name() { return "std::shared_ptr"; }
|
||||
static const char *weak_name() { return "std::weak_ptr"; }
|
||||
};
|
||||
@@ -39,6 +51,18 @@ template <typename T> struct PointerTraits<Ref<T>> {
|
||||
return make_ref<T>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
static pointer_type copy(const pointer_type &ptr) {
|
||||
return ptr.copy(); // Ref requires explicit copy
|
||||
}
|
||||
|
||||
static weak_type as_weak(const pointer_type &ptr) {
|
||||
return ptr.as_weak(); // Ref requires explicit as_weak
|
||||
}
|
||||
|
||||
static weak_type copy_weak(const weak_type &weak) {
|
||||
return weak.copy(); // WeakRef requires explicit copy
|
||||
}
|
||||
|
||||
static const char *name() { return "Ref"; }
|
||||
static const char *weak_name() { return "WeakRef"; }
|
||||
};
|
||||
@@ -67,7 +91,7 @@ void benchmark_copy(ankerl::nanobench::Bench &bench) {
|
||||
|
||||
auto original = Traits::make(TestObject{123});
|
||||
bench.run(std::string(Traits::name()) + " copy", [&] {
|
||||
auto copy = original;
|
||||
auto copy = Traits::copy(original);
|
||||
ankerl::nanobench::doNotOptimizeAway(copy);
|
||||
});
|
||||
}
|
||||
@@ -91,9 +115,9 @@ void benchmark_weak_copy(ankerl::nanobench::Bench &bench) {
|
||||
force_multithreaded();
|
||||
|
||||
auto strong_ptr = Traits::make(TestObject{123});
|
||||
typename Traits::weak_type weak_original = strong_ptr;
|
||||
typename Traits::weak_type weak_original = Traits::as_weak(strong_ptr);
|
||||
bench.run(std::string(Traits::weak_name()) + " copy", [&] {
|
||||
auto weak_copy = weak_original;
|
||||
auto weak_copy = Traits::copy_weak(weak_original);
|
||||
ankerl::nanobench::doNotOptimizeAway(weak_copy);
|
||||
});
|
||||
}
|
||||
@@ -103,7 +127,7 @@ void benchmark_weak_move(ankerl::nanobench::Bench &bench) {
|
||||
using Traits = PointerTraits<PtrType>;
|
||||
|
||||
auto strong_ptr = Traits::make(TestObject{123});
|
||||
typename Traits::weak_type weak_original = strong_ptr;
|
||||
typename Traits::weak_type weak_original = Traits::as_weak(strong_ptr);
|
||||
bench.run(std::string(Traits::weak_name()) + " move", [&] {
|
||||
auto weak_moved = std::move(weak_original);
|
||||
ankerl::nanobench::doNotOptimizeAway(weak_moved);
|
||||
@@ -126,7 +150,7 @@ void benchmark_weak_lock_success(ankerl::nanobench::Bench &bench) {
|
||||
using Traits = PointerTraits<PtrType>;
|
||||
|
||||
auto strong_ptr = Traits::make(TestObject{789});
|
||||
typename Traits::weak_type weak_ptr = strong_ptr;
|
||||
typename Traits::weak_type weak_ptr = Traits::as_weak(strong_ptr);
|
||||
bench.run(std::string(Traits::weak_name()) + " lock success", [&] {
|
||||
auto locked = weak_ptr.lock();
|
||||
ankerl::nanobench::doNotOptimizeAway(locked);
|
||||
@@ -140,7 +164,7 @@ void benchmark_weak_lock_failure(ankerl::nanobench::Bench &bench) {
|
||||
typename Traits::weak_type weak_ptr;
|
||||
{
|
||||
auto strong_ptr = Traits::make(TestObject{999});
|
||||
weak_ptr = strong_ptr;
|
||||
weak_ptr = Traits::as_weak(strong_ptr);
|
||||
}
|
||||
bench.run(std::string(Traits::weak_name()) + " lock failure", [&] {
|
||||
auto locked = weak_ptr.lock();
|
||||
@@ -163,7 +187,7 @@ void benchmark_multithreaded_copy(ankerl::nanobench::Bench &bench,
|
||||
for (int i = 0; i < num_threads - 1; ++i) {
|
||||
background_threads.emplace_back([&]() {
|
||||
while (keep_running.load(std::memory_order_relaxed)) {
|
||||
auto copy = ptr;
|
||||
auto copy = Traits::copy(ptr);
|
||||
ankerl::nanobench::doNotOptimizeAway(copy);
|
||||
}
|
||||
});
|
||||
@@ -171,7 +195,7 @@ void benchmark_multithreaded_copy(ankerl::nanobench::Bench &bench,
|
||||
|
||||
// Benchmark the foreground thread under contention
|
||||
bench.run(std::string(Traits::name()) + " copy under contention", [&] {
|
||||
auto copy = ptr;
|
||||
auto copy = Traits::copy(ptr);
|
||||
ankerl::nanobench::doNotOptimizeAway(copy);
|
||||
});
|
||||
|
||||
@@ -189,7 +213,7 @@ void benchmark_multithreaded_weak_lock(ankerl::nanobench::Bench &bench,
|
||||
|
||||
// Create the shared object and weak reference outside the benchmark
|
||||
auto strong_ptr = Traits::make(TestObject{789});
|
||||
typename Traits::weak_type weak_ptr = strong_ptr;
|
||||
typename Traits::weak_type weak_ptr = Traits::as_weak(strong_ptr);
|
||||
|
||||
// Create background threads that will create contention
|
||||
std::atomic<bool> keep_running{true};
|
||||
@@ -224,7 +248,7 @@ void benchmark_weak_copy_with_strong_contention(ankerl::nanobench::Bench &bench,
|
||||
|
||||
// Create the shared object and weak reference outside the benchmark
|
||||
auto strong_ptr = Traits::make(TestObject{456});
|
||||
typename Traits::weak_type weak_ptr = strong_ptr;
|
||||
typename Traits::weak_type weak_ptr = Traits::as_weak(strong_ptr);
|
||||
|
||||
// Create background threads copying the strong pointer
|
||||
std::atomic<bool> keep_running{true};
|
||||
@@ -233,7 +257,7 @@ void benchmark_weak_copy_with_strong_contention(ankerl::nanobench::Bench &bench,
|
||||
for (int i = 0; i < num_threads - 1; ++i) {
|
||||
background_threads.emplace_back([&]() {
|
||||
while (keep_running.load(std::memory_order_relaxed)) {
|
||||
auto copy = strong_ptr;
|
||||
auto copy = Traits::copy(strong_ptr);
|
||||
ankerl::nanobench::doNotOptimizeAway(copy);
|
||||
}
|
||||
});
|
||||
@@ -242,7 +266,7 @@ void benchmark_weak_copy_with_strong_contention(ankerl::nanobench::Bench &bench,
|
||||
// Benchmark weak reference copying under strong reference contention
|
||||
bench.run(std::string(Traits::weak_name()) + " copy with strong contention",
|
||||
[&] {
|
||||
auto weak_copy = weak_ptr;
|
||||
auto weak_copy = Traits::copy_weak(weak_ptr);
|
||||
ankerl::nanobench::doNotOptimizeAway(weak_copy);
|
||||
});
|
||||
|
||||
@@ -260,7 +284,7 @@ void benchmark_strong_copy_with_weak_contention(ankerl::nanobench::Bench &bench,
|
||||
|
||||
// Create the shared object and weak reference outside the benchmark
|
||||
auto strong_ptr = Traits::make(TestObject{789});
|
||||
typename Traits::weak_type weak_ptr = strong_ptr;
|
||||
typename Traits::weak_type weak_ptr = Traits::as_weak(strong_ptr);
|
||||
|
||||
// Create background threads copying the weak pointer
|
||||
std::atomic<bool> keep_running{true};
|
||||
@@ -269,7 +293,7 @@ void benchmark_strong_copy_with_weak_contention(ankerl::nanobench::Bench &bench,
|
||||
for (int i = 0; i < num_threads - 1; ++i) {
|
||||
background_threads.emplace_back([&]() {
|
||||
while (keep_running.load(std::memory_order_relaxed)) {
|
||||
auto weak_copy = weak_ptr;
|
||||
auto weak_copy = Traits::copy_weak(weak_ptr);
|
||||
ankerl::nanobench::doNotOptimizeAway(weak_copy);
|
||||
}
|
||||
});
|
||||
@@ -277,7 +301,7 @@ void benchmark_strong_copy_with_weak_contention(ankerl::nanobench::Bench &bench,
|
||||
|
||||
// Benchmark strong reference copying under weak reference contention
|
||||
bench.run(std::string(Traits::name()) + " copy with weak contention", [&] {
|
||||
auto strong_copy = strong_ptr;
|
||||
auto strong_copy = Traits::copy(strong_ptr);
|
||||
ankerl::nanobench::doNotOptimizeAway(strong_copy);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user