From 67d7cfc1355a0f4550263f3d24758840668017f8 Mon Sep 17 00:00:00 2001 From: dormando Date: Fri, 31 Aug 2012 18:49:50 -0700 Subject: remove global stats lock from item allocation This doesn't reduce mutex contention much, if at all, for the global stats lock, but it does remove a handful of instructions from the alloc hot path, which is always worth doing. Previous commits possibly added a handful of instructions for the loop and for the bucket readlock trylock, but this is still faster than .14 for writes overall. --- items.c | 32 ++++++++++++++++++++------------ items.h | 1 + memcached.c | 2 -- memcached.h | 1 + slabs.c | 5 +---- thread.c | 6 ++++++ 6 files changed, 29 insertions(+), 18 deletions(-) diff --git a/items.c b/items.c index d8f4188..85fd7e1 100644 --- a/items.c +++ b/items.c @@ -138,14 +138,8 @@ item *do_item_alloc(char *key, const size_t nkey, const int flags, /* Expired or flushed */ if ((search->exptime != 0 && search->exptime < current_time) || (search->time <= oldest_live && oldest_live <= current_time)) { - STATS_LOCK(); - stats.reclaimed++; - STATS_UNLOCK(); itemstats[id].reclaimed++; if ((search->it_flags & ITEM_FETCHED) == 0) { - STATS_LOCK(); - stats.expired_unfetched++; - STATS_UNLOCK(); itemstats[id].expired_unfetched++; } it = search; @@ -163,14 +157,8 @@ item *do_item_alloc(char *key, const size_t nkey, const int flags, if (search->exptime != 0) itemstats[id].evicted_nonzero++; if ((search->it_flags & ITEM_FETCHED) == 0) { - STATS_LOCK(); - stats.evicted_unfetched++; - STATS_UNLOCK(); itemstats[id].evicted_unfetched++; } - STATS_LOCK(); - stats.evictions++; - STATS_UNLOCK(); it = search; slabs_adjust_mem_requested(it->slabs_clsid, ITEM_ntotal(it), ntotal); do_item_unlink_nolock(it, hv); @@ -436,6 +424,26 @@ void item_stats_evictions(uint64_t *evicted) { mutex_unlock(&cache_lock); } +void do_item_stats_totals(ADD_STAT add_stats, void *c) { + itemstats_t totals; + memset(&totals, 0, sizeof(itemstats_t)); + int i; + for (i = 0; i < LARGEST_ID; i++) { + totals.expired_unfetched += itemstats[i].expired_unfetched; + totals.evicted_unfetched += itemstats[i].evicted_unfetched; + totals.evicted += itemstats[i].evicted; + totals.reclaimed += itemstats[i].reclaimed; + } + APPEND_STAT("expired_unfetched", "%llu", + (unsigned long long)totals.expired_unfetched); + APPEND_STAT("evicted_unfetched", "%llu", + (unsigned long long)totals.evicted_unfetched); + APPEND_STAT("evictions", "%llu", + (unsigned long long)totals.evicted); + APPEND_STAT("reclaimed", "%llu", + (unsigned long long)totals.reclaimed); +} + void do_item_stats(ADD_STAT add_stats, void *c) { int i; for (i = 0; i < LARGEST_ID; i++) { diff --git a/items.h b/items.h index 4b25dcc..4c75119 100644 --- a/items.h +++ b/items.h @@ -16,6 +16,7 @@ int do_item_replace(item *it, item *new_it, const uint32_t hv); /*@null@*/ char *do_item_cachedump(const unsigned int slabs_clsid, const unsigned int limit, unsigned int *bytes); void do_item_stats(ADD_STAT add_stats, void *c); +void do_item_stats_totals(ADD_STAT add_stats, void *c); /*@null@*/ void do_item_stats_sizes(ADD_STAT add_stats, void *c); void do_item_flush_expired(void); diff --git a/memcached.c b/memcached.c index 71d5ff0..23b771a 100644 --- a/memcached.c +++ b/memcached.c @@ -2585,8 +2585,6 @@ static void server_stats(ADD_STAT add_stats, conn *c) { APPEND_STAT("hash_power_level", "%u", stats.hash_power_level); APPEND_STAT("hash_bytes", "%llu", (unsigned long long)stats.hash_bytes); APPEND_STAT("hash_is_expanding", "%u", stats.hash_is_expanding); - APPEND_STAT("expired_unfetched", "%llu", stats.expired_unfetched); - APPEND_STAT("evicted_unfetched", "%llu", stats.evicted_unfetched); if (settings.slab_reassign) { APPEND_STAT("slab_reassign_running", "%u", stats.slab_reassign_running); APPEND_STAT("slabs_moved", "%llu", stats.slabs_moved); diff --git a/memcached.h b/memcached.h index 0594ab9..8a51352 100644 --- a/memcached.h +++ b/memcached.h @@ -533,6 +533,7 @@ int item_link(item *it); void item_remove(item *it); int item_replace(item *it, item *new_it, const uint32_t hv); void item_stats(ADD_STAT add_stats, void *c); +void item_stats_totals(ADD_STAT add_stats, void *c); void item_stats_sizes(ADD_STAT add_stats, void *c); void item_unlink(item *it); void item_update(item *it); diff --git a/slabs.c b/slabs.c index c61722f..753edd9 100644 --- a/slabs.c +++ b/slabs.c @@ -293,11 +293,8 @@ bool get_stats(const char *stat_type, int nkey, ADD_STAT add_stats, void *c) { APPEND_STAT("bytes", "%llu", (unsigned long long)stats.curr_bytes); APPEND_STAT("curr_items", "%u", stats.curr_items); APPEND_STAT("total_items", "%u", stats.total_items); - APPEND_STAT("evictions", "%llu", - (unsigned long long)stats.evictions); - APPEND_STAT("reclaimed", "%llu", - (unsigned long long)stats.reclaimed); STATS_UNLOCK(); + item_stats_totals(add_stats, c); } else if (nz_strcmp(nkey, stat_type, "items") == 0) { item_stats(add_stats, c); } else if (nz_strcmp(nkey, stat_type, "slabs") == 0) { diff --git a/thread.c b/thread.c index 086b783..4e3e239 100644 --- a/thread.c +++ b/thread.c @@ -631,6 +631,12 @@ void item_stats(ADD_STAT add_stats, void *c) { mutex_unlock(&cache_lock); } +void item_stats_totals(ADD_STAT add_stats, void *c) { + mutex_lock(&cache_lock); + do_item_stats_totals(add_stats, c); + mutex_unlock(&cache_lock); +} + /* * Dumps a list of objects of each size in 32-byte increments */ -- cgit v1.2.1