Rewrite channelz registry in terms of inlined vector

pull/15982/head
ncteisen 7 years ago
parent 4ba4d18960
commit aca5043ca3
  1. 30
      src/core/lib/channel/channelz_registry.cc
  2. 19
      src/core/lib/channel/channelz_registry.h
  3. 9
      test/core/channel/channelz_registry_test.cc

@ -26,27 +26,14 @@
#include <grpc/support/alloc.h> #include <grpc/support/alloc.h>
#include <grpc/support/log.h> #include <grpc/support/log.h>
#include <cstring>
namespace grpc_core { namespace grpc_core {
namespace { namespace {
// singleton instance of the registry. // singleton instance of the registry.
ChannelzRegistry* g_channelz_registry = nullptr; ChannelzRegistry* g_channelz_registry = nullptr;
// avl vtable for uuid (intptr_t) -> channelz_obj (void*)
// this table is only looking, it does not own anything.
void destroy_intptr(void* not_used, void* user_data) {}
void* copy_intptr(void* key, void* user_data) { return key; }
long compare_intptr(void* key1, void* key2, void* user_data) {
return GPR_ICMP(key1, key2);
}
void destroy_channelz_obj(void* channelz_obj, void* user_data) {}
void* copy_channelz_obj(void* channelz_obj, void* user_data) {
return channelz_obj;
}
const grpc_avl_vtable avl_vtable = {destroy_intptr, copy_intptr, compare_intptr,
destroy_channelz_obj, copy_channelz_obj};
} // anonymous namespace } // anonymous namespace
void ChannelzRegistry::Init() { g_channelz_registry = New<ChannelzRegistry>(); } void ChannelzRegistry::Init() { g_channelz_registry = New<ChannelzRegistry>(); }
@ -58,19 +45,24 @@ ChannelzRegistry* ChannelzRegistry::Default() {
return g_channelz_registry; return g_channelz_registry;
} }
ChannelzRegistry::ChannelzRegistry() : uuid_(1) { ChannelzRegistry::ChannelzRegistry() {
gpr_mu_init(&mu_); gpr_mu_init(&mu_);
avl_ = grpc_avl_create(&avl_vtable); // init elements to nullptr
memset(entities_.data(), 0, sizeof(void*) * entities_.capacity());
} }
ChannelzRegistry::~ChannelzRegistry() { ChannelzRegistry::~ChannelzRegistry() {
grpc_avl_unref(avl_, nullptr); // null out all elements so that the destructors don't try to run.
// this is a "view only" object.
memset(entities_.data(), 0, sizeof(void*) * entities_.capacity());
gpr_mu_destroy(&mu_); gpr_mu_destroy(&mu_);
} }
void ChannelzRegistry::InternalUnregister(intptr_t uuid) { void ChannelzRegistry::InternalUnregister(intptr_t uuid) {
GPR_ASSERT(uuid >= 1);
gpr_mu_lock(&mu_); gpr_mu_lock(&mu_);
avl_ = grpc_avl_remove(avl_, (void*)uuid, nullptr); GPR_ASSERT((size_t)uuid <= entities_.size());
entities_[uuid - 1] = nullptr;
gpr_mu_unlock(&mu_); gpr_mu_unlock(&mu_);
} }

@ -23,6 +23,7 @@
#include "src/core/lib/avl/avl.h" #include "src/core/lib/avl/avl.h"
#include "src/core/lib/channel/channel_trace.h" #include "src/core/lib/channel/channel_trace.h"
#include "src/core/lib/gprpp/inlined_vector.h"
#include <stdint.h> #include <stdint.h>
@ -67,11 +68,11 @@ class ChannelzRegistry {
// globally registers a channelz Object. Returns its unique uuid // globally registers a channelz Object. Returns its unique uuid
template <typename Object> template <typename Object>
intptr_t InternalRegister(Object* object) { intptr_t InternalRegister(Object* object) {
intptr_t prior = gpr_atm_no_barrier_fetch_add(&uuid_, 1);
gpr_mu_lock(&mu_); gpr_mu_lock(&mu_);
avl_ = grpc_avl_add(avl_, (void*)prior, object, nullptr); entities_.push_back(static_cast<void*>(object));
intptr_t uuid = entities_.size();
gpr_mu_unlock(&mu_); gpr_mu_unlock(&mu_);
return prior; return uuid;
} }
// globally unregisters the object that is associated to uuid. // globally unregisters the object that is associated to uuid.
@ -82,16 +83,20 @@ class ChannelzRegistry {
template <typename Object> template <typename Object>
Object* InternalGet(intptr_t uuid) { Object* InternalGet(intptr_t uuid) {
gpr_mu_lock(&mu_); gpr_mu_lock(&mu_);
Object* ret = if (uuid < 1 || uuid > static_cast<intptr_t>(entities_.size())) {
static_cast<Object*>(grpc_avl_get(avl_, (void*)uuid, nullptr)); gpr_mu_unlock(&mu_);
return nullptr;
}
Object* ret = static_cast<Object*>(entities_[uuid - 1]);
gpr_mu_unlock(&mu_); gpr_mu_unlock(&mu_);
return ret; return ret;
} }
// private members // private members
// protects entities_ and uuid_
gpr_mu mu_; gpr_mu mu_;
grpc_avl avl_; InlinedVector<void*, 20> entities_;
gpr_atm uuid_;
}; };
} // namespace grpc_core } // namespace grpc_core

@ -82,6 +82,15 @@ TEST(ChannelzRegistryTest, MultipleTypeTest) {
EXPECT_EQ(&str_to_register, retrieved_str); EXPECT_EQ(&str_to_register, retrieved_str);
} }
TEST(ChannelzRegistryTest, RegisterManyItems) {
int object_to_register = 42;
for (int i = 0; i < 100; i++) {
intptr_t uuid = ChannelzRegistry::Register(&object_to_register);
int* retrieved = ChannelzRegistry::Get<int>(uuid);
EXPECT_EQ(&object_to_register, retrieved);
}
}
namespace { namespace {
class Foo { class Foo {
public: public:

Loading…
Cancel
Save