From efad616d1cd8bf8eb5d6e7573a1952cacb3073ee Mon Sep 17 00:00:00 2001 From: Trond Norbye Date: Fri, 12 Nov 2010 08:36:06 -0800 Subject: Issue 163: Buggy mem_requested values --- items.c | 1 + slabs.c | 14 ++++++++++++++ slabs.h | 3 +++ t/issue_163.t | 37 +++++++++++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+) create mode 100644 t/issue_163.t diff --git a/items.c b/items.c index f92fc2e..ee1185e 100644 --- a/items.c +++ b/items.c @@ -114,6 +114,7 @@ item *do_item_alloc(char *key, const size_t nkey, const int flags, const rel_tim STATS_UNLOCK(); itemstats[id].reclaimed++; it->refcount = 1; + slabs_adjust_mem_requested(it->slabs_clsid, ITEM_ntotal(it), ntotal); do_item_unlink(it); /* Initialize the item block: */ it->slabs_clsid = 0; diff --git a/slabs.c b/slabs.c index a725a0b..069317f 100644 --- a/slabs.c +++ b/slabs.c @@ -438,3 +438,17 @@ void slabs_stats(ADD_STAT add_stats, void *c) { do_slabs_stats(add_stats, c); pthread_mutex_unlock(&slabs_lock); } + +void slabs_adjust_mem_requested(unsigned int id, size_t old, size_t ntotal) +{ + pthread_mutex_lock(&slabs_lock); + slabclass_t *p; + if (id < POWER_SMALLEST || id > power_largest) { + fprintf(stderr, "Internal error! Invalid slab class\n"); + abort(); + } + + p = &slabclass[id]; + p->requested = p->requested - old + ntotal; + pthread_mutex_unlock(&slabs_lock); +} diff --git a/slabs.h b/slabs.h index ec14455..21da116 100644 --- a/slabs.h +++ b/slabs.h @@ -24,6 +24,9 @@ void *slabs_alloc(const size_t size, unsigned int id); /** Free previously allocated object */ void slabs_free(void *ptr, size_t size, unsigned int id); +/** Adjust the stats for memory requested */ +void slabs_adjust_mem_requested(unsigned int id, size_t old, size_t ntotal); + /** Return a datum for stats in binary protocol */ bool get_stats(const char *stat_type, int nkey, ADD_STAT add_stats, void *c); diff --git a/t/issue_163.t b/t/issue_163.t new file mode 100644 index 0000000..7af1259 --- /dev/null +++ b/t/issue_163.t @@ -0,0 +1,37 @@ +#!/usr/bin/perl + +use strict; +use Test::More tests => 7; +use FindBin qw($Bin); +use lib "$Bin/lib"; +use MemcachedTest; + +my $server = new_memcached(); +my $sock = $server->sock; +my $value1 = "A"x66560; +my $value2 = "B"x66570; + +print $sock "set key 0 1 66560\r\n$value1\r\n"; +is (scalar <$sock>, "STORED\r\n", "stored key"); + +my $stats = mem_stats($sock, "slabs"); +my $requested = $stats->{"31:mem_requested"}; +isnt ($requested, "0", "We should have requested some memory"); + +sleep(2); +print $sock "set key 0 0 66570\r\n$value2\r\n"; +is (scalar <$sock>, "STORED\r\n", "stored key"); + +my $stats = mem_stats($sock, "items"); +my $reclaimed = $stats->{"items:31:reclaimed"}; +is ($reclaimed, "1", "Objects should be reclaimed"); + +print $sock "delete key\r\n"; +is (scalar <$sock>, "DELETED\r\n", "deleted key"); + +print $sock "set key 0 0 66560\r\n$value1\r\n"; +is (scalar <$sock>, "STORED\r\n", "stored key"); + +my $stats = mem_stats($sock, "slabs"); +my $requested2 = $stats->{"31:mem_requested"}; +is ($requested2, $requested, "we've not allocated and freed the same amont"); -- cgit v1.2.1