Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/install-build-env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ group "configure.py"
--compiler "$CPP" \
--c-compiler "$CC" \
--mode "$MODE" \
--heap-profiling \
"${cook_args[@]}" \
"${ccache_opt[@]}" \
$OPTIONS \
Expand Down
16 changes: 16 additions & 0 deletions include/seastar/core/chunked_hash_map.hh
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,23 @@

#include <seastar/core/chunked_vector.hh>

// abseil LTS 20220623 and earlier include <ciso646> from
// absl/base/options.h. libstdc++ 16 warns on that header for C++20 and later,
// and seastar builds with -Werror.
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-W#warnings"
#elif defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcpp"
#endif
#include <absl/hash/hash.h>
#if defined(__clang__)
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#pragma GCC diagnostic pop
#endif

#include <ankerl/unordered_dense.h>
#include <fmt/format.h>
#include <fmt/ranges.h>
Expand Down
31 changes: 24 additions & 7 deletions tests/unit/alloc_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,15 @@ SEASTAR_TEST_CASE(test_sampled_profile_collection_small)
BOOST_REQUIRE_EQUAL(stats.size(), 0);
}

std::size_t count = 100;
// The two loops below are distinct call sites and the assertions require
// both of them to be sampled, so each loop has to cover enough sampling
// intervals that missing one entirely is not plausible. The sampler draws
// the gap to the next sample from an exponential distribution whose mean is
// the sampling interval, so a loop allocating N intervals worth of bytes
// records nothing with probability e^-N. count/2 * 10 bytes against the 100
// byte interval below is N=50, putting the chance of recording one call
// site instead of two at about 2*e^-50.
std::size_t count = 1000;
std::vector<volatile char*> ptrs(count);

seastar::memory::set_heap_profiling_sampling_rate(100);
Expand All @@ -615,20 +623,20 @@ SEASTAR_TEST_CASE(test_sampled_profile_collection_small)
auto stats1 = seastar::memory::sampled_memory_profile();

// two back-to-back copies of the sample should have the same value
BOOST_CHECK_EQUAL(stats0, stats1);
BOOST_CHECK_EQUAL_COLLECTIONS(stats0.begin(), stats0.end(), stats1.begin(), stats1.end());

// check that we get the same value from the raw array iterface
std::vector<seastar::memory::allocation_site> stats2(stats0.size());
auto sz2 = seastar::memory::sampled_memory_profile(stats2.data(), stats2.size());
BOOST_CHECK_EQUAL(stats0.size(), sz2);
BOOST_CHECK_EQUAL(stats0, stats2);
BOOST_CHECK_EQUAL_COLLECTIONS(stats0.begin(), stats0.end(), stats2.begin(), stats2.end());
Comment on lines 625 to +632

@travisdowns travisdowns Sep 10, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair but, pre-existing, filed CORE-17350.


// check with +1 size, we expect to still only get size elements
std::vector<seastar::memory::allocation_site> stats3(stats0.size() + 1);
auto sz3 = seastar::memory::sampled_memory_profile(stats3.data(), stats3.size());
BOOST_CHECK_EQUAL(stats0.size(), sz3);
stats3.resize(sz3);
BOOST_CHECK_EQUAL(stats0, stats3);
BOOST_CHECK_EQUAL_COLLECTIONS(stats0.begin(), stats0.end(), stats3.begin(), stats3.end());

return stats0;
};
Expand Down Expand Up @@ -668,7 +676,16 @@ SEASTAR_TEST_CASE(test_sampled_profile_collection_large)
std::size_t count = 100;
std::vector<volatile char*> ptrs(count);

seastar::memory::set_heap_profiling_sampling_rate(1000000);
// Both loops have to be sampled, as in
// test_sampled_profile_collection_small: count/2 * 100000 bytes against
// this interval is N=25 intervals per loop, so the chance of recording one
// call site instead of two is about 2*e^-25. The interval also has to stay
// above the 131072 bytes that a 100000 byte request actually allocates, so
// that sample_size() accounts each sample as one full interval and the
// size == count * sample_rate check below holds.
std::size_t sample_rate = 200000;

seastar::memory::set_heap_profiling_sampling_rate(sample_rate);

#ifdef __clang__
#pragma nounroll
Expand All @@ -690,10 +707,10 @@ SEASTAR_TEST_CASE(test_sampled_profile_collection_large)
{
auto stats = seastar::memory::sampled_memory_profile();
BOOST_REQUIRE_EQUAL(stats.size(), 2);
BOOST_REQUIRE_EQUAL(stats[0].size, stats[0].count * 1000000);
BOOST_REQUIRE_EQUAL(stats[0].size, stats[0].count * sample_rate);
}

seastar::memory::set_heap_profiling_sampling_rate(1000000);
seastar::memory::set_heap_profiling_sampling_rate(sample_rate);

for (auto ptr : ptrs) {
free((void*)ptr);
Expand Down
Loading