blob: c2c703e783d98afb9373cd164876bce4a6956a5e [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "table_set.h"
#include <lib/ddk/trace/event.h>
#include <zircon/compiler.h>
#include "macros.h"
#include "table_holder.h"
namespace {
constexpr uint32_t kChurnCountThreshold = 256;
} // namespace
TableSet::TableSet() : allocator_(std::make_unique<Arena>()) {}
fidl::AnyArena& TableSet::allocator() {
CountChurn();
return *allocator_;
}
void TableSet::MitigateChurn() {
if (churn_count_ < kChurnCountThreshold) {
return;
}
GcTables();
}
void TableSet::GcTables() {
auto old_allocator = std::move(allocator_);
allocator_ = std::make_unique<Arena>();
{
TRACE_DURATION("gfx", "TableSet::MitigateChurn() clone_to_new_allocator() loop");
for (auto table_holder_base : tables_) {
table_holder_base->clone_to_new_allocator();
}
}
// Set this back to 0 last, so any churn_count_ increments during main part of MitigateChurn()
// don't get counted, since that could lead to degenerate behavior with a large enough working
// set.
churn_count_ = 0;
// ~old_allocator
}
void TableSet::CountChurn() { ++churn_count_; }
void TableSet::TrackTableHolder(TableHolderBase* table_holder) {
CountChurn();
tables_.insert(table_holder);
}
void TableSet::UntrackTableHolder(TableHolderBase* table_holder) {
CountChurn();
tables_.erase(table_holder);
}