Convert grpc malloc slice to use grpc_core::RefCount.

This shows up in profiles. Using grpc_core::RefCount lowers the time
spent in grpc_slice_malloc_large() by 8%.
pull/18147/head
Soheil Hassas Yeganeh 6 years ago
parent 8fd43c2e91
commit b4e069a5c3
  1. 44
      src/core/lib/slice/slice.cc

@ -26,6 +26,7 @@
#include <string.h> #include <string.h>
#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/iomgr/exec_ctx.h" #include "src/core/lib/iomgr/exec_ctx.h"
char* grpc_slice_to_c_string(grpc_slice slice) { char* grpc_slice_to_c_string(grpc_slice slice) {
@ -213,21 +214,35 @@ grpc_slice grpc_slice_from_copied_string(const char* source) {
return grpc_slice_from_copied_buffer(source, strlen(source)); return grpc_slice_from_copied_buffer(source, strlen(source));
} }
typedef struct { namespace {
struct MallocRefCount {
MallocRefCount(const grpc_slice_refcount_vtable* vtable) {
base.vtable = vtable;
base.sub_refcount = &base;
}
void Ref() { refs.Ref(); }
void Unref() {
if (refs.Unref()) {
gpr_free(this);
}
}
grpc_slice_refcount base; grpc_slice_refcount base;
gpr_refcount refs; grpc_core::RefCount refs;
} malloc_refcount; };
} // namespace
static void malloc_ref(void* p) { static void malloc_ref(void* p) {
malloc_refcount* r = static_cast<malloc_refcount*>(p); MallocRefCount* r = static_cast<MallocRefCount*>(p);
gpr_ref(&r->refs); r->Ref();
} }
static void malloc_unref(void* p) { static void malloc_unref(void* p) {
malloc_refcount* r = static_cast<malloc_refcount*>(p); MallocRefCount* r = static_cast<MallocRefCount*>(p);
if (gpr_unref(&r->refs)) { r->Unref();
gpr_free(r);
}
} }
static const grpc_slice_refcount_vtable malloc_vtable = { static const grpc_slice_refcount_vtable malloc_vtable = {
@ -246,15 +261,10 @@ grpc_slice grpc_slice_malloc_large(size_t length) {
refcount is a malloc_refcount refcount is a malloc_refcount
bytes is an array of bytes of the requested length bytes is an array of bytes of the requested length
Both parts are placed in the same allocation returned from gpr_malloc */ Both parts are placed in the same allocation returned from gpr_malloc */
malloc_refcount* rc = static_cast<malloc_refcount*>( void* data =
gpr_malloc(sizeof(malloc_refcount) + length)); static_cast<MallocRefCount*>(gpr_malloc(sizeof(MallocRefCount) + length));
/* Initial refcount on rc is 1 - and it's up to the caller to release
this reference. */
gpr_ref_init(&rc->refs, 1);
rc->base.vtable = &malloc_vtable; auto* rc = new (data) MallocRefCount(&malloc_vtable);
rc->base.sub_refcount = &rc->base;
/* Build up the slice to be returned. */ /* Build up the slice to be returned. */
/* The slices refcount points back to the allocated block. */ /* The slices refcount points back to the allocated block. */

Loading…
Cancel
Save