Skip to content

Commit

Permalink
maintain a free slot index set in TLS InstanceImpl to allocate in O(1…
Browse files Browse the repository at this point in the history
…) time

Signed-off-by: Xin Zhuang <stevenzzz@google.com>
  • Loading branch information
stevenzzzz committed Aug 20, 2019
1 parent 9421bdd commit 12a2a95
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 9 deletions.
20 changes: 11 additions & 9 deletions source/common/thread_local/thread_local_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,16 @@ SlotPtr InstanceImpl::allocateSlot() {
ASSERT(std::this_thread::get_id() == main_thread_id_);
ASSERT(!shutdown_);

for (uint64_t i = 0; i < slots_.size(); i++) {
if (slots_[i] == nullptr) {
std::unique_ptr<SlotImpl> slot(new SlotImpl(*this, i));
slots_[i] = slot.get();
return slot;
}
if (free_slot_indexes_.empty()) {
std::unique_ptr<SlotImpl> slot(new SlotImpl(*this, slots_.size()));
slots_.push_back(slot.get());
return slot;
}

std::unique_ptr<SlotImpl> slot(new SlotImpl(*this, slots_.size()));
slots_.push_back(slot.get());
uint32_t idx = *free_slot_indexes_.begin();
free_slot_indexes_.erase(idx);
ASSERT(idx < slots_.size());
std::unique_ptr<SlotImpl> slot(new SlotImpl(*this, idx));
slots_[idx] = slot.get();
return slot;
}

Expand Down Expand Up @@ -73,6 +73,8 @@ void InstanceImpl::removeSlot(SlotImpl& slot) {

const uint64_t index = slot.index_;
slots_[index] = nullptr;
auto ret = free_slot_indexes_.emplace(index);
ASSERT(ret.second, fmt::format("slot index {} already in free slot set!", index));
runOnAllThreads([index]() -> void {
// This runs on each thread and clears the slot, making it available for a new allocations.
// This is safe even if a new allocation comes in, because everything happens with post() and
Expand Down
5 changes: 5 additions & 0 deletions source/common/thread_local/thread_local_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

#include "common/common/logger.h"

#include "absl/container/flat_hash_set.h"

namespace Envoy {
namespace ThreadLocal {

Expand Down Expand Up @@ -57,6 +59,9 @@ class InstanceImpl : Logger::Loggable<Logger::Id::main>, public Instance {

static thread_local ThreadLocalData thread_local_data_;
std::vector<SlotImpl*> slots_;
// A set of index of freed slots.
absl::flat_hash_set<uint32_t> free_slot_indexes_;

std::list<std::reference_wrapper<Event::Dispatcher>> registered_threads_;
std::thread::id main_thread_id_;
Event::Dispatcher* main_thread_dispatcher_{};
Expand Down

0 comments on commit 12a2a95

Please sign in to comment.