|
|
|
@ -120,11 +120,11 @@ AllocatedMetadata::AllocatedMetadata(const grpc_slice& key, |
|
|
|
|
AllocatedMetadata::~AllocatedMetadata() { |
|
|
|
|
grpc_slice_unref_internal(key_); |
|
|
|
|
grpc_slice_unref_internal(value_); |
|
|
|
|
if (user_data_.user_data) { |
|
|
|
|
void* user_data = user_data_.data.Load(grpc_core::MemoryOrder::RELAXED); |
|
|
|
|
if (user_data) { |
|
|
|
|
destroy_user_data_func destroy_user_data = |
|
|
|
|
(destroy_user_data_func)gpr_atm_no_barrier_load( |
|
|
|
|
&user_data_.destroy_user_data); |
|
|
|
|
destroy_user_data((void*)user_data_.user_data); |
|
|
|
|
user_data_.destroy_user_data.Load(grpc_core::MemoryOrder::RELAXED); |
|
|
|
|
destroy_user_data(user_data); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -151,17 +151,17 @@ InternedMetadata::InternedMetadata(const grpc_slice& key, |
|
|
|
|
InternedMetadata::~InternedMetadata() { |
|
|
|
|
grpc_slice_unref_internal(key_); |
|
|
|
|
grpc_slice_unref_internal(value_); |
|
|
|
|
if (user_data_.user_data) { |
|
|
|
|
void* user_data = user_data_.data.Load(grpc_core::MemoryOrder::RELAXED); |
|
|
|
|
if (user_data) { |
|
|
|
|
destroy_user_data_func destroy_user_data = |
|
|
|
|
(destroy_user_data_func)gpr_atm_no_barrier_load( |
|
|
|
|
&user_data_.destroy_user_data); |
|
|
|
|
destroy_user_data((void*)user_data_.user_data); |
|
|
|
|
user_data_.destroy_user_data.Load(grpc_core::MemoryOrder::RELAXED); |
|
|
|
|
destroy_user_data(user_data); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
intptr_t InternedMetadata::CleanupLinkedMetadata( |
|
|
|
|
size_t InternedMetadata::CleanupLinkedMetadata( |
|
|
|
|
InternedMetadata::BucketLink* head) { |
|
|
|
|
intptr_t num_freed = 0; |
|
|
|
|
size_t num_freed = 0; |
|
|
|
|
InternedMetadata::BucketLink* prev_next = head; |
|
|
|
|
InternedMetadata *md, *next; |
|
|
|
|
|
|
|
|
@ -249,11 +249,12 @@ void InternedMetadata::RefWithShardLocked(mdtab_shard* shard) { |
|
|
|
|
|
|
|
|
|
static void gc_mdtab(mdtab_shard* shard) { |
|
|
|
|
GPR_TIMER_SCOPE("gc_mdtab", 0); |
|
|
|
|
intptr_t num_freed = 0; |
|
|
|
|
size_t num_freed = 0; |
|
|
|
|
for (size_t i = 0; i < shard->capacity; ++i) { |
|
|
|
|
num_freed += InternedMetadata::CleanupLinkedMetadata(&shard->elems[i]); |
|
|
|
|
} |
|
|
|
|
gpr_atm_no_barrier_fetch_add(&shard->free_estimate, -num_freed); |
|
|
|
|
gpr_atm_no_barrier_fetch_add(&shard->free_estimate, |
|
|
|
|
-static_cast<intptr_t>(num_freed)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void grow_mdtab(mdtab_shard* shard) { |
|
|
|
@ -375,9 +376,9 @@ grpc_mdelem grpc_mdelem_from_grpc_metadata(grpc_metadata* metadata) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void* get_user_data(UserData* user_data, void (*destroy_func)(void*)) { |
|
|
|
|
if (gpr_atm_acq_load(&user_data->destroy_user_data) == |
|
|
|
|
(gpr_atm)destroy_func) { |
|
|
|
|
return (void*)gpr_atm_no_barrier_load(&user_data->user_data); |
|
|
|
|
if (user_data->destroy_user_data.Load(grpc_core::MemoryOrder::ACQUIRE) == |
|
|
|
|
destroy_func) { |
|
|
|
|
return user_data->data.Load(grpc_core::MemoryOrder::RELAXED); |
|
|
|
|
} else { |
|
|
|
|
return nullptr; |
|
|
|
|
} |
|
|
|
@ -403,40 +404,40 @@ void* grpc_mdelem_get_user_data(grpc_mdelem md, void (*destroy_func)(void*)) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void* set_user_data(UserData* ud, void (*destroy_func)(void*), |
|
|
|
|
void* user_data) { |
|
|
|
|
GPR_ASSERT((user_data == nullptr) == (destroy_func == nullptr)); |
|
|
|
|
void* data) { |
|
|
|
|
GPR_ASSERT((data == nullptr) == (destroy_func == nullptr)); |
|
|
|
|
grpc_core::ReleasableMutexLock lock(&ud->mu_user_data); |
|
|
|
|
if (gpr_atm_no_barrier_load(&ud->destroy_user_data)) { |
|
|
|
|
if (ud->destroy_user_data.Load(grpc_core::MemoryOrder::RELAXED)) { |
|
|
|
|
/* user data can only be set once */ |
|
|
|
|
lock.Unlock(); |
|
|
|
|
if (destroy_func != nullptr) { |
|
|
|
|
destroy_func(user_data); |
|
|
|
|
destroy_func(data); |
|
|
|
|
} |
|
|
|
|
return (void*)gpr_atm_no_barrier_load(&ud->user_data); |
|
|
|
|
return ud->data.Load(grpc_core::MemoryOrder::RELAXED); |
|
|
|
|
} |
|
|
|
|
gpr_atm_no_barrier_store(&ud->user_data, (gpr_atm)user_data); |
|
|
|
|
gpr_atm_rel_store(&ud->destroy_user_data, (gpr_atm)destroy_func); |
|
|
|
|
return user_data; |
|
|
|
|
ud->data.Store(data, grpc_core::MemoryOrder::RELAXED); |
|
|
|
|
ud->destroy_user_data.Store(destroy_func, grpc_core::MemoryOrder::RELEASE); |
|
|
|
|
return data; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void* grpc_mdelem_set_user_data(grpc_mdelem md, void (*destroy_func)(void*), |
|
|
|
|
void* user_data) { |
|
|
|
|
void* data) { |
|
|
|
|
switch (GRPC_MDELEM_STORAGE(md)) { |
|
|
|
|
case GRPC_MDELEM_STORAGE_EXTERNAL: |
|
|
|
|
destroy_func(user_data); |
|
|
|
|
destroy_func(data); |
|
|
|
|
return nullptr; |
|
|
|
|
case GRPC_MDELEM_STORAGE_STATIC: |
|
|
|
|
destroy_func(user_data); |
|
|
|
|
destroy_func(data); |
|
|
|
|
return (void*)grpc_static_mdelem_user_data[GRPC_MDELEM_DATA(md) - |
|
|
|
|
grpc_static_mdelem_table]; |
|
|
|
|
case GRPC_MDELEM_STORAGE_ALLOCATED: { |
|
|
|
|
auto* am = reinterpret_cast<AllocatedMetadata*>(GRPC_MDELEM_DATA(md)); |
|
|
|
|
return set_user_data(am->user_data(), destroy_func, user_data); |
|
|
|
|
return set_user_data(am->user_data(), destroy_func, data); |
|
|
|
|
} |
|
|
|
|
case GRPC_MDELEM_STORAGE_INTERNED: { |
|
|
|
|
auto* im = reinterpret_cast<InternedMetadata*> GRPC_MDELEM_DATA(md); |
|
|
|
|
GPR_ASSERT(!is_mdelem_static(md)); |
|
|
|
|
return set_user_data(im->user_data(), destroy_func, user_data); |
|
|
|
|
return set_user_data(im->user_data(), destroy_func, data); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
GPR_UNREACHABLE_CODE(return nullptr); |
|
|
|
|