Skip to content

Commit

Permalink
Invoke shrink handler only when there are non-zero number of objects …
Browse files Browse the repository at this point in the history
…to drain

in ShrinkOtherCache.

This also adds a test that tries to shrink an empty cache. It fails without the fix in this cl.

PiperOrigin-RevId: 571438100
Change-Id: Ieb6347b926ac7603efab80c2bbad5ecf87a06c3b
  • Loading branch information
v-gogte authored and copybara-github committed Oct 6, 2023
1 parent a1a7c2c commit dd8f4b4
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 2 deletions.
7 changes: 5 additions & 2 deletions tcmalloc/internal/percpu_tcmalloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -1449,10 +1449,13 @@ size_t TcmallocSlab<NumClasses>::ShrinkOtherCache(
// slab.

const uint16_t unused = hdr.end_copy - hdr.current;
uint16_t actual_pop = 0;
if (unused < len) {
const uint16_t expected_pop = len - unused;
const uint16_t actual_pop =
std::min<uint16_t>(expected_pop, hdr.current - begin);
actual_pop = std::min<uint16_t>(expected_pop, hdr.current - begin);
}

if (actual_pop > 0) {
void** batch = reinterpret_cast<void**>(CpuMemoryStart(slabs, shift, cpu)) +
hdr.current - actual_pop;
TSANAcquireBatch(batch, actual_pop);
Expand Down
27 changes: 27 additions & 0 deletions tcmalloc/internal/percpu_tcmalloc_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,32 @@ TEST_F(TcmallocSlabTest, Unit) {
}
}

TEST_F(TcmallocSlabTest, ShrinkEmptyCache) {
if (MallocExtension::PerCpuCachesActive()) {
// This test unregisters rseq temporarily, as to decrease flakiness.
GTEST_SKIP() << "per-CPU TCMalloc is incompatible with unregistering rseq";
}

if (!IsFast()) {
GTEST_SKIP() << "Need fast percpu. Skipping.";
return;
}
constexpr int kCpu = 1;
constexpr int kSizeClass = 1;
slab_.InitCpu(kCpu, [](size_t size_class) { return kCapacity; });
EXPECT_EQ(
slab_.ShrinkOtherCache(kCpu, kSizeClass, /*len=*/1,
[](size_t size_class, void** batch, size_t n) {
EXPECT_LT(size_class, kStressSlabs);
EXPECT_LE(n, kStressCapacity);
EXPECT_GT(n, 0);
for (size_t i = 0; i < n; ++i) {
EXPECT_NE(batch[i], nullptr);
}
}),
0);
}

TEST_F(TcmallocSlabTest, SimulatedMadviseFailure) {
if (!IsFast()) {
GTEST_SKIP() << "Need fast percpu. Skipping.";
Expand Down Expand Up @@ -652,6 +678,7 @@ void StressThread(size_t thread_id, Context& ctx) {
[&block](size_t size_class, void** batch, size_t n) {
EXPECT_LT(size_class, kStressSlabs);
EXPECT_LE(n, kStressCapacity);
EXPECT_GT(n, 0);
for (size_t i = 0; i < n; ++i) {
EXPECT_NE(batch[i], nullptr);
block.push_back(batch[i]);
Expand Down

0 comments on commit dd8f4b4

Please sign in to comment.