From acdfe4229a70c323e66c37e2768dfdea42694bb1 Mon Sep 17 00:00:00 2001 From: Brian Aker Date: Fri, 3 Aug 2012 07:11:58 -0400 Subject: [PATCH] Updated to latest memcached --- configure.ac | 1 - libtest/cmdline.cc | 12 +- memcached/{README => README.md} | 20 ++- memcached/assoc.c | 12 +- memcached/autogen.sh | 2 +- memcached/cache.c | 3 +- memcached/daemon.c | 6 +- memcached/devtools/clean-whitespace.pl | 2 +- memcached/doc/protocol.txt | 16 ++- memcached/hash.c | 10 +- memcached/items.c | 32 +++-- memcached/memcached.c | 123 +++++----------- memcached/memcached.h | 12 +- memcached/memcached.spec.in | 2 +- memcached/memcached_dtrace.d | 11 ++ memcached/slabs.c | 186 ++++++++++++++----------- memcached/slabs.h | 5 +- memcached/t/binary.t | 6 +- memcached/t/slabs_reassign.t | 12 +- memcached/t/whitespace.t | 5 +- memcached/testapp.c | 10 +- memcached/thread.c | 20 +-- memcached/util.c | 4 +- memcached/version.m4 | 1 - 24 files changed, 254 insertions(+), 259 deletions(-) rename memcached/{README => README.md} (74%) delete mode 100644 memcached/version.m4 diff --git a/configure.ac b/configure.ac index bcb2d320..7b6127a0 100644 --- a/configure.ac +++ b/configure.ac @@ -69,7 +69,6 @@ m4_include([libtest/yatl.m4]) m4_include([m4/memcached_sasl.m4]) m4_include([m4/gearmand.m4]) m4_include([m4/libgearman.m4]) -m4_include([memcached/version.m4]) AM_CONDITIONAL(BUILDING_LIBMEMCACHED, true) AM_CONDITIONAL(HAVE_LIBMEMCACHED, false) diff --git a/libtest/cmdline.cc b/libtest/cmdline.cc index 3179d192..f43b1c28 100644 --- a/libtest/cmdline.cc +++ b/libtest/cmdline.cc @@ -82,7 +82,6 @@ extern "C" { namespace { -#if 0 std::string print_argv(libtest::vchar_ptr_t& built_argv) { std::stringstream arg_buffer; @@ -96,8 +95,8 @@ namespace { return arg_buffer.str(); } -#endif +#if 0 std::string print_argv(char** argv) { std::stringstream arg_buffer; @@ -109,6 +108,8 @@ namespace { return arg_buffer.str(); } +#endif + static Application::error_t int_to_error_t(int arg) { @@ -458,6 +459,7 @@ Application::error_t Application::wait(bool nohang) if (exit_code == Application::INVALID) { Error << print_argv(built_argv, _argc); + / } #endif @@ -514,13 +516,11 @@ Application::error_t Application::join() slurp(); -#if 0 if (exit_code == Application::INVALID) { - Error << print_argv(built_argv, _argc); + Error << print_argv(built_argv); } -#endif - +; return exit_code; } diff --git a/memcached/README b/memcached/README.md similarity index 74% rename from memcached/README rename to memcached/README.md index f20dd8c1..27a68961 100644 --- a/memcached/README +++ b/memcached/README.md @@ -1,6 +1,12 @@ -Dependencies: +# Memcached - -- libevent, http://www.monkey.org/~provos/libevent/ (libevent-dev) +## Dependencies + +* libevent, http://www.monkey.org/~provos/libevent/ (libevent-dev) + +## Environment + +### Linux If using Linux, you need a kernel with epoll. Sure, libevent will work with normal select, but it sucks. @@ -11,6 +17,8 @@ epoll isn't in Linux 2.4, but there's a backport at: You want the epoll-lt patch (level-triggered). +### Mac OS X + If you're using MacOS, you'll want libevent 1.1 or higher to deal with a kqueue bug. @@ -19,10 +27,12 @@ dangerous when using a large cache. Just make sure the memcached machines don't swap. memcached does non-blocking network I/O, but not disk. (it should never go to disk, or you've lost the whole point of it) -The memcached website is at: +## Website + +* http://www.memcached.org - http://www.memcached.org +## Contributing Want to contribute? Up-to-date pointers should be at: - http://contributing.appspot.com/memcached +* http://contributing.appspot.com/memcached diff --git a/memcached/assoc.c b/memcached/assoc.c index f14d85d8..bcaf6f26 100644 --- a/memcached/assoc.c +++ b/memcached/assoc.c @@ -12,7 +12,6 @@ */ #include "memcached.h" - #include #include #include @@ -28,13 +27,6 @@ static pthread_cond_t maintenance_cond = PTHREAD_COND_INITIALIZER; -#ifndef __INTEL_COMPILER -#pragma GCC diagnostic ignored "-Wstrict-aliasing" -#endif - -#ifndef __INTEL_COMPILER -#pragma GCC diagnostic ignored "-Wunused-parameter" -#endif typedef unsigned long int ub4; /* unsigned 4-byte quantities */ typedef unsigned char ub1; /* unsigned 1-byte quantities */ @@ -243,7 +235,7 @@ static void *assoc_maintenance_thread(void *arg) { pthread_cond_wait(&maintenance_cond, &cache_lock); } - pthread_mutex_unlock(&cache_lock); + mutex_unlock(&cache_lock); } return NULL; } @@ -271,7 +263,7 @@ void stop_assoc_maintenance_thread() { mutex_lock(&cache_lock); do_run_maintenance_thread = 0; pthread_cond_signal(&maintenance_cond); - pthread_mutex_unlock(&cache_lock); + mutex_unlock(&cache_lock); /* Wait for the maintenance thread to stop */ pthread_join(maintenance_tid, NULL); diff --git a/memcached/autogen.sh b/memcached/autogen.sh index c735394d..a3a97672 100755 --- a/memcached/autogen.sh +++ b/memcached/autogen.sh @@ -39,7 +39,7 @@ $AUTOHEADER || exit 1 echo "automake..." if test x$AUTOMAKE = x; then - AUTOMAKE=`locate_binary automake-1.11 automake-1.10 automake-1.9 automake-1.7` + AUTOMAKE=`locate_binary automake-1.12 automake-1.11 automake-1.10 automake-1.9 automake-1.7` if test x$AUTOMAKE = x; then die "Did not find a supported automake" fi diff --git a/memcached/cache.c b/memcached/cache.c index 7dcf2fbb..fcb3d2bf 100644 --- a/memcached/cache.c +++ b/memcached/cache.c @@ -1,5 +1,5 @@ /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ -#include "memcached.h" +#include #include #include @@ -68,6 +68,7 @@ void cache_destroy(cache_t *cache) { free(cache->name); free(cache->ptr); pthread_mutex_destroy(&cache->mutex); + free(cache); } void* cache_alloc(cache_t *cache) { diff --git a/memcached/daemon.c b/memcached/daemon.c index 2f189157..d42e5b08 100644 --- a/memcached/daemon.c +++ b/memcached/daemon.c @@ -29,18 +29,20 @@ * SUCH DAMAGE. */ +#include + #if defined __SUNPRO_C || defined __DECC || defined __HP_cc # pragma ident "@(#)$Header: /cvsroot/wikipedia/willow/src/bin/willow/daemon.c,v 1.1 2005/05/02 19:15:21 kateturner Exp $" # pragma ident "$NetBSD: daemon.c,v 1.9 2003/08/07 16:42:46 agc Exp $" #endif -#include "memcached.h" - #include #include #include #include +#include "memcached.h" + int daemonize(int nochdir, int noclose) { int fd; diff --git a/memcached/devtools/clean-whitespace.pl b/memcached/devtools/clean-whitespace.pl index 95481ef4..fe058067 100755 --- a/memcached/devtools/clean-whitespace.pl +++ b/memcached/devtools/clean-whitespace.pl @@ -3,7 +3,7 @@ use strict; use FindBin qw($Bin); chdir "$Bin/.." or die; -my @exempted = qw(Makefile.am ChangeLog doc/Makefile.am); +my @exempted = qw(Makefile.am ChangeLog doc/Makefile.am README README.md); push(@exempted, glob("doc/*.xml")); push(@exempted, glob("doc/xml2rfc/*.xsl")); push(@exempted, glob("m4/*backport*m4")); diff --git a/memcached/doc/protocol.txt b/memcached/doc/protocol.txt index 1a844f0a..b26d9625 100644 --- a/memcached/doc/protocol.txt +++ b/memcached/doc/protocol.txt @@ -354,6 +354,8 @@ slabs reassign \r\n - is an id number for the slab class to steal a page from +A source class id of -1 means "pick from any valid class" + - is an id number for the slab class to move a page to The response line could be one of: @@ -385,12 +387,20 @@ more details. The automover can be enabled or disabled at runtime with this command. -slabs automove <1|0> +slabs automove <0|1> -- 1|0 is the indicator on whether to enable the slabs automover or not. +- 0|1|2 is the indicator on whether to enable the slabs automover or not. The response should always be "OK\r\n" +- <0> means to set the thread on standby + +- <1> means to run the builtin slow algorithm to choose pages to move + +- <2> is a highly aggressive mode which causes pages to be moved every time + there is an eviction. It is not recommended to run for very long in this + mode unless your access patterns are very well understood. + Statistics ---------- @@ -406,7 +416,7 @@ settings, documented below. In the other form it has some arguments: stats \r\n Depending on , various internal data is sent by the server. The -kinds of arguments and the data sent are not documented in this vesion +kinds of arguments and the data sent are not documented in this version of the protocol, and are subject to change for the convenience of memcache developers. diff --git a/memcached/hash.c b/memcached/hash.c index 6c9b9b6a..fcfc1ffc 100644 --- a/memcached/hash.c +++ b/memcached/hash.c @@ -16,11 +16,11 @@ * whether it's big or little-endian. ENDIAN_LITTLE and ENDIAN_BIG * are set in the configure script. */ -#if defined(ENDIAN_BIG) && ENDIAN_BIG == 1 +#if ENDIAN_BIG == 1 # define HASH_LITTLE_ENDIAN 0 # define HASH_BIG_ENDIAN 1 #else -# if defined(ENDIAN_LITTLE) && ENDIAN_LITTLE == 1 +# if ENDIAN_LITTLE == 1 # define HASH_LITTLE_ENDIAN 1 # define HASH_BIG_ENDIAN 0 # else @@ -178,8 +178,6 @@ uint32_t hash( case 2 : a+=k[0]&0xffff; break; case 1 : a+=k[0]&0xff; break; case 0 : return c; /* zero length strings require no mixing */ - default: - abort(); } #else /* make valgrind happy */ @@ -249,8 +247,6 @@ uint32_t hash( case 1 : a+=k8[0]; break; case 0 : return c; /* zero length strings require no mixing */ - default: - abort(); } } else { /* need to read the key one byte at a time */ @@ -293,8 +289,6 @@ uint32_t hash( case 1 : a+=k[0]; break; case 0 : return c; /* zero length strings require no mixing */ - default: - abort(); } } diff --git a/memcached/items.c b/memcached/items.c index 58fc8717..84011c44 100644 --- a/memcached/items.c +++ b/memcached/items.c @@ -44,7 +44,7 @@ static unsigned int sizes[LARGEST_ID]; void item_stats_reset(void) { mutex_lock(&cache_lock); memset(itemstats, 0, sizeof(itemstats)); - pthread_mutex_unlock(&cache_lock); + mutex_unlock(&cache_lock); } @@ -125,7 +125,7 @@ item *do_item_alloc(char *key, const size_t nkey, const int flags, const rel_tim } else if ((it = slabs_alloc(ntotal, id)) == NULL) { if (settings.evict_to_free == 0) { itemstats[id].outofmemory++; - pthread_mutex_unlock(&cache_lock); + mutex_unlock(&cache_lock); return NULL; } itemstats[id].evicted++; @@ -146,6 +146,16 @@ item *do_item_alloc(char *key, const size_t nkey, const int flags, const rel_tim do_item_unlink_nolock(it, hash(ITEM_key(it), it->nkey, 0)); /* Initialize the item block: */ it->slabs_clsid = 0; + + /* If we've just evicted an item, and the automover is set to + * angry bird mode, attempt to rip memory into this slab class. + * TODO: Move valid object detection into a function, and on a + * "successful" memory pull, look behind and see if the next alloc + * would be an eviction. Then kick off the slab mover before the + * eviction happens. + */ + if (settings.slab_automove == 2) + slabs_reassign(-1, id); } else { refcount_decr(&search->refcount); } @@ -171,7 +181,7 @@ item *do_item_alloc(char *key, const size_t nkey, const int flags, const rel_tim search->refcount = 1; do_item_unlink_nolock(search, hash(ITEM_key(search), search->nkey, 0)); } - pthread_mutex_unlock(&cache_lock); + mutex_unlock(&cache_lock); return NULL; } @@ -182,7 +192,7 @@ item *do_item_alloc(char *key, const size_t nkey, const int flags, const rel_tim * been removed from the slab LRU. */ it->refcount = 1; /* the caller will have a reference */ - pthread_mutex_unlock(&cache_lock); + mutex_unlock(&cache_lock); it->next = it->prev = it->h_next = 0; it->slabs_clsid = id; @@ -288,7 +298,7 @@ int do_item_link(item *it, const uint32_t hv) { assoc_insert(it, hv); item_link_q(it); refcount_incr(&it->refcount); - pthread_mutex_unlock(&cache_lock); + mutex_unlock(&cache_lock); return 1; } @@ -306,7 +316,7 @@ void do_item_unlink(item *it, const uint32_t hv) { item_unlink_q(it); do_item_remove(it); } - pthread_mutex_unlock(&cache_lock); + mutex_unlock(&cache_lock); } /* FIXME: Is it necessary to keep this copy/pasted code? */ @@ -344,7 +354,7 @@ void do_item_update(item *it) { it->time = current_time; item_link_q(it); } - pthread_mutex_unlock(&cache_lock); + mutex_unlock(&cache_lock); } } @@ -357,10 +367,6 @@ int do_item_replace(item *it, item *new_it, const uint32_t hv) { return do_item_link(new_it, hv); } -#ifndef __INTEL_COMPILER -#pragma GCC diagnostic ignored "-Wshadow" -#endif - /*@null@*/ char *do_item_cachedump(const unsigned int slabs_clsid, const unsigned int limit, unsigned int *bytes) { unsigned int memlimit = 2 * 1024 * 1024; /* 2MB max response size */ @@ -407,7 +413,7 @@ void item_stats_evictions(uint64_t *evicted) { for (i = 0; i < LARGEST_ID; i++) { evicted[i] = itemstats[i].evicted; } - pthread_mutex_unlock(&cache_lock); + mutex_unlock(&cache_lock); } void do_item_stats(ADD_STAT add_stats, void *c) { @@ -499,7 +505,7 @@ item *do_item_get(const char *key, const size_t nkey, const uint32_t hv) { it = NULL; } } - pthread_mutex_unlock(&cache_lock); + mutex_unlock(&cache_lock); int was_found = 0; if (settings.verbose > 2) { diff --git a/memcached/memcached.c b/memcached/memcached.c index 10374421..2cb0b206 100644 --- a/memcached/memcached.c +++ b/memcached/memcached.c @@ -125,9 +125,6 @@ static enum transmit_result transmit(conn *c); */ static volatile bool allow_new_conns = true; static struct event maxconnsevent; -#ifndef __INTEL_COMPILER -#pragma GCC diagnostic ignored "-Wunused-parameter" -#endif static void maxconns_handler(const int fd, const short which, void *arg) { struct timeval t = {.tv_sec = 0, .tv_usec = 10000}; @@ -227,7 +224,7 @@ static void settings_init(void) { settings.maxconns_fast = false; settings.hashpower_init = 0; settings.slab_reassign = false; - settings.slab_automove = false; + settings.slab_automove = 0; } /* @@ -336,7 +333,7 @@ bool conn_add_to_freelist(conn *c) { } static const char *prot_text(enum protocol prot) { - const char *rv = "unknown"; + char *rv = "unknown"; switch(prot) { case ascii_prot: rv = "ascii"; @@ -347,8 +344,6 @@ static const char *prot_text(enum protocol prot) { case negotiating_prot: rv = "auto-negotiate"; break; - default: - abort(); } return rv; } @@ -639,9 +634,6 @@ static const char *state_text(enum conn_states state) { return statenames[state]; } -#ifndef __INTEL_COMPILER -#pragma GCC diagnostic ignored "-Wtype-limits" -#endif /* * Sets a connection's current state in the state machine. Any special * processing that needs to happen on certain state transitions can @@ -791,9 +783,6 @@ static int build_udp_headers(conn *c) { } -#ifndef __INTEL_COMPILER -#pragma GCC diagnostic ignored "-Wsign-compare" -#endif static void out_string(conn *c, const char *str) { size_t len; @@ -1000,10 +989,6 @@ static void write_bin_error(conn *c, protocol_binary_response_status err, int sw case PROTOCOL_BINARY_RESPONSE_AUTH_ERROR: errstr = "Auth failure."; break; - case PROTOCOL_BINARY_RESPONSE_AUTH_CONTINUE: - assert(false); - case PROTOCOL_BINARY_RESPONSE_SUCCESS: - assert(false); default: assert(false); errstr = "UNHANDLED ERROR"; @@ -1029,7 +1014,7 @@ static void write_bin_error(conn *c, protocol_binary_response_status err, int sw } /* Form and send a response to a command over the binary protocol */ -static void write_bin_response(conn *c, const void *d, int hlen, int keylen, int dlen) { +static void write_bin_response(conn *c, void *d, int hlen, int keylen, int dlen) { if (!c->noreply || c->cmd == PROTOCOL_BINARY_CMD_GET || c->cmd == PROTOCOL_BINARY_CMD_GETK) { add_bin_header(c, 0, hlen, keylen, dlen); @@ -1133,10 +1118,6 @@ static void complete_incr_bin(conn *c) { case DELTA_ITEM_CAS_MISMATCH: write_bin_error(c, PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS, 0); break; - - default: - assert(0); - abort(); } } @@ -1204,9 +1185,6 @@ static void complete_update_bin(conn *c) { eno = PROTOCOL_BINARY_RESPONSE_NOT_STORED; } write_bin_error(c, eno, 0); - default: - assert(false); - abort(); } item_remove(c->item); /* release the c->item reference */ @@ -1219,8 +1197,8 @@ static void process_bin_touch(conn *c) { protocol_binary_response_get* rsp = (protocol_binary_response_get*)c->wbuf; char* key = binary_get_key(c); size_t nkey = c->binary_header.request.keylen; - protocol_binary_request_touch *t = (void *)&c->binary_header; - uint32_t exptime = ntohl(t->message.body.expiration); + protocol_binary_request_touch *t = binary_get_request(c); + time_t exptime = ntohl(t->message.body.expiration); if (settings.verbose > 1) { int ii; @@ -1387,9 +1365,6 @@ static void process_bin_get(conn *c) { } } -#ifndef __INTEL_COMPILER -#pragma GCC diagnostic ignored "-Wmissing-field-initializers" -#endif static void append_bin_stats(const char *key, const uint16_t klen, const char *val, const uint32_t vlen, conn *c) { @@ -1397,14 +1372,11 @@ static void append_bin_stats(const char *key, const uint16_t klen, uint32_t bodylen = klen + vlen; protocol_binary_response_header header = { .response.magic = (uint8_t)PROTOCOL_BINARY_RES, - .response.opcode = (uint8_t)PROTOCOL_BINARY_CMD_STAT, + .response.opcode = PROTOCOL_BINARY_CMD_STAT, .response.keylen = (uint16_t)htons(klen), - .response.extlen = (uint8_t)0, .response.datatype = (uint8_t)PROTOCOL_BINARY_RAW_BYTES, - .response.status = (uint16_t)0, .response.bodylen = htonl(bodylen), - .response.opaque = c->opaque, - .response.cas = (uint64_t)0 + .response.opaque = c->opaque }; memcpy(buf, header.bytes, sizeof(header.response)); @@ -1887,7 +1859,7 @@ static void dispatch_bin_command(conn *c) { switch (c->cmd) { case PROTOCOL_BINARY_CMD_VERSION: if (extlen == 0 && keylen == 0 && bodylen == 0) { - write_bin_response(c, RVERSION, 0, 0, strlen(RVERSION)); + write_bin_response(c, VERSION, 0, 0, strlen(VERSION)); } else { protocol_error = 1; } @@ -2246,10 +2218,6 @@ static void complete_nread_binary(conn *c) { case bin_reading_sasl_auth_data: process_bin_complete_sasl_auth(c); break; - case bin_reading_cas_header: - assert(0); - case bin_no_state: - assert(0); default: fprintf(stderr, "Not handling substate %d\n", c->substate); assert(0); @@ -2568,7 +2536,7 @@ static void server_stats(ADD_STAT add_stats, conn *c) { APPEND_STAT("pid", "%lu", (long)pid); APPEND_STAT("uptime", "%u", now); APPEND_STAT("time", "%ld", now + (long)process_started); - APPEND_STAT("version", "%s", RVERSION); + APPEND_STAT("version", "%s", VERSION); APPEND_STAT("libevent", "%s", event_get_version()); APPEND_STAT("pointer_size", "%d", (int)(8 * sizeof(void *))); @@ -2656,7 +2624,7 @@ static void process_stat_settings(ADD_STAT add_stats, void *c) { APPEND_STAT("maxconns_fast", "%s", settings.maxconns_fast ? "yes" : "no"); APPEND_STAT("hashpower_init", "%d", settings.hashpower_init); APPEND_STAT("slab_reassign", "%s", settings.slab_reassign ? "yes" : "no"); - APPEND_STAT("slab_automove", "%s", settings.slab_automove ? "yes" : "no"); + APPEND_STAT("slab_automove", "%d", settings.slab_automove); } static void process_stat(conn *c, token_t *tokens, const size_t ntokens) { @@ -2735,9 +2703,6 @@ static void process_stat(conn *c, token_t *tokens, const size_t ntokens) { } } -#ifndef __INTEL_COMPILER -#pragma GCC diagnostic ignored "-Wunused-but-set-parameter" -#endif /* ntokens is overwritten here... shrug.. */ static inline void process_get_command(conn *c, token_t *tokens, size_t ntokens, bool return_cas) { char *key; @@ -3072,9 +3037,6 @@ static void process_arithmetic_command(conn *c, token_t *tokens, const size_t nt break; case DELTA_ITEM_CAS_MISMATCH: break; /* Should never get here */ - default: - assert(false); - abort(); } } @@ -3156,7 +3118,7 @@ enum delta_result_type do_add_delta(conn *c, const char *key, const size_t nkey, need to update the CAS on the existing item. */ mutex_lock(&cache_lock); /* FIXME */ ITEM_set_cas(it, (settings.use_cas) ? get_cas_id() : 0); - pthread_mutex_unlock(&cache_lock); + mutex_unlock(&cache_lock); memcpy(ITEM_data(it), buf, res); memset(ITEM_data(it) + res, ' ', it->nbytes - res - 2); @@ -3244,9 +3206,9 @@ static void process_slabs_automove_command(conn *c, token_t *tokens, const size_ level = strtoul(tokens[2].value, NULL, 10); if (level == 0) { - settings.slab_automove = false; - } else if (level == 1) { - settings.slab_automove = true; + settings.slab_automove = 0; + } else if (level == 1 || level == 2) { + settings.slab_automove = level; } else { out_string(c, "ERROR"); return; @@ -3363,7 +3325,7 @@ static void process_command(conn *c, char *command) { } else if (ntokens == 2 && (strcmp(tokens[COMMAND_TOKEN].value, "version") == 0)) { - out_string(c, "VERSION " RVERSION); + out_string(c, "VERSION " VERSION); } else if (ntokens == 2 && (strcmp(tokens[COMMAND_TOKEN].value, "quit") == 0)) { @@ -3400,18 +3362,9 @@ static void process_command(conn *c, char *command) { case REASSIGN_NOSPARE: out_string(c, "NOSPARE source class has no spare pages"); break; - case REASSIGN_DEST_NOT_FULL: - out_string(c, "NOTFULL dest class has spare memory"); - break; - case REASSIGN_SRC_NOT_SAFE: - out_string(c, "UNSAFE src class is in an unsafe state"); - break; case REASSIGN_SRC_DST_SAME: out_string(c, "SAME src and dst class are identical"); break; - default: - assert(false); - abort(); } return; } else if (ntokens == 4 && @@ -3866,9 +3819,6 @@ static void drive_machine(conn *c) { case READ_MEMORY_ERROR: /* Failed to allocate more memory */ /* State already set by try_read_network */ break; - default: - assert(false); - abort(); } break; @@ -4078,9 +4028,6 @@ static void drive_machine(conn *c) { case TRANSMIT_SOFT_ERROR: stop = true; break; - default: - assert(false); - abort(); } break; @@ -4095,9 +4042,6 @@ static void drive_machine(conn *c) { case conn_max_state: assert(false); break; - default: - assert(false); - abort(); } } @@ -4242,12 +4186,7 @@ static int server_socket(const char *interface, } #endif - error = setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &flags, sizeof(flags)); - if (error != 0) - { - perror("setsockopt(SO_REUSEADDR)"); - } - + setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, (void *)&flags, sizeof(flags)); if (IS_UDP(transport)) { maximize_sndbuf(sfd); } else { @@ -4504,7 +4443,7 @@ static void clock_handler(const int fd, const short which, void *arg) { } static void usage(void) { - printf(RPACKAGE " " RVERSION "\n"); + printf(PACKAGE " " VERSION "\n"); printf("-p TCP port number to listen on (default: 11211)\n" "-U UDP port number to listen on (default: 11211, 0 is off)\n" "-s UNIX socket path to listen on (disables network support)\n" @@ -4569,7 +4508,7 @@ static void usage(void) { } static void usage_license(void) { - printf(RPACKAGE " " RVERSION "\n\n"); + printf(PACKAGE " " VERSION "\n\n"); printf( "Copyright (c) 2003, Danga Interactive, Inc. \n" "All rights reserved.\n" @@ -4731,7 +4670,7 @@ static int enable_large_pages(void) { return ret; #else - return 0; + return -1; #endif } @@ -4788,10 +4727,10 @@ int main (int argc, char **argv) { SLAB_AUTOMOVE }; char *const subopts_tokens[] = { - [MAXCONNS_FAST] = (char*)"maxconns_fast", - [HASHPOWER_INIT] = (char*)"hashpower", - [SLAB_REASSIGN] = (char*)"slab_reassign", - [SLAB_AUTOMOVE] = (char*)"slab_automove", + [MAXCONNS_FAST] = "maxconns_fast", + [HASHPOWER_INIT] = "hashpower", + [SLAB_REASSIGN] = "slab_reassign", + [SLAB_AUTOMOVE] = "slab_automove", NULL }; @@ -4952,6 +4891,10 @@ int main (int argc, char **argv) { case 'L' : if (enable_large_pages() == 0) { preallocate = true; + } else { + fprintf(stderr, "Cannot enable large pages on this system\n" + "(There is no Linux support as of this version)\n"); + return 1; } break; case 'C' : @@ -5041,7 +4984,15 @@ int main (int argc, char **argv) { settings.slab_reassign = true; break; case SLAB_AUTOMOVE: - settings.slab_automove = true; + if (subopts_value == NULL) { + settings.slab_automove = 1; + break; + } + settings.slab_automove = atoi(subopts_value); + if (settings.slab_automove < 0 || settings.slab_automove > 2) { + fprintf(stderr, "slab_automove must be between 0 and 2\n"); + return 1; + } break; default: printf("Illegal suboption \"%s\"\n", subopts_value); @@ -5283,10 +5234,8 @@ int main (int argc, char **argv) { stop_assoc_maintenance_thread(); /* remove the PID file if we're a daemon */ -#if 0 if (do_daemonize) remove_pidfile(pid_file); -#endif /* Clean up strdup() call for bind() address */ if (settings.inter) free(settings.inter); diff --git a/memcached/memcached.h b/memcached/memcached.h index d070502c..edd7fcf8 100644 --- a/memcached/memcached.h +++ b/memcached/memcached.h @@ -10,7 +10,6 @@ #endif #include -#include #include #include #include @@ -74,7 +73,6 @@ #define POWER_SMALLEST 1 #define POWER_LARGEST 200 #define CHUNK_ALIGN_BYTES 8 -#define DONT_PREALLOC_SLABS #define MAX_NUMBER_OF_SLAB_CLASSES (POWER_LARGEST + 1) /** How long an object can reasonably be assumed to be locked before @@ -303,13 +301,10 @@ struct settings { bool sasl; /* SASL on/off */ bool maxconns_fast; /* Whether or not to early close connections */ bool slab_reassign; /* Whether or not slab reassignment is allowed */ - bool slab_automove; /* Whether or not to automatically move slabs */ + int slab_automove; /* Whether or not to automatically move slabs */ int hashpower_init; /* Starting hash power level */ }; -#ifndef __INTEL_COMPILER -#pragma GCC diagnostic ignored "-Wshadow" -#endif extern struct stats stats; extern time_t process_started; extern struct settings settings; @@ -322,9 +317,6 @@ extern struct settings settings; #define ITEM_FETCHED 8 -#ifndef __INTEL_COMPILER -#pragma GCC diagnostic ignored "-Wshadow" -#endif /** * Structure for storing items within memcached. */ @@ -556,7 +548,7 @@ void append_stat(const char *name, ADD_STAT add_stats, conn *c, enum store_item_type store_item(item *item, int comm, conn *c); -#if defined(HAVE_DROP_PRIVILEGES) && HAVE_DROP_PRIVILEGES +#if HAVE_DROP_PRIVILEGES extern void drop_privileges(void); #else #define drop_privileges() diff --git a/memcached/memcached.spec.in b/memcached/memcached.spec.in index f473d8fa..678be90a 100644 --- a/memcached/memcached.spec.in +++ b/memcached/memcached.spec.in @@ -83,7 +83,7 @@ exit 0 %files %defattr(-,root,root,-) -%doc AUTHORS ChangeLog COPYING NEWS README doc/CONTRIBUTORS doc/*.txt +%doc AUTHORS ChangeLog COPYING NEWS README.md doc/CONTRIBUTORS doc/*.txt %config(noreplace) %{_sysconfdir}/sysconfig/%{name} %dir %attr(750,nobody,nobody) %{_localstatedir}/run/memcached diff --git a/memcached/memcached_dtrace.d b/memcached/memcached_dtrace.d index eeffb6f3..0fe132c4 100644 --- a/memcached/memcached_dtrace.d +++ b/memcached/memcached_dtrace.d @@ -250,6 +250,17 @@ provider memcached { */ probe command__append(int connid, const char *key, int keylen, int size, int64_t casid); + /** + * Fired for an touch-command. + * @param connid connection id + * @param key requested key + * @param keylen length of the key + * @param size the new size of the key's data (or signed int -1 if + * not found) + * @param casid the casid for the item + */ + probe command__touch(int connid, const char *key, int keylen, int size, int64_t casid); + /** * Fired for a cas-command. * @param connid connection id diff --git a/memcached/slabs.c b/memcached/slabs.c index 7cffe434..b74617e2 100644 --- a/memcached/slabs.c +++ b/memcached/slabs.c @@ -30,9 +30,6 @@ typedef struct { void *slots; /* list of item ptrs */ unsigned int sl_curr; /* total free items in list */ - void *end_page_ptr; /* pointer to next free item at end of page, or 0 */ - unsigned int end_page_free; /* number of items remaining at end of last alloced page */ - unsigned int slabs; /* how many slabs were allocated for this class */ void **slab_list; /* array of slab pointers */ @@ -55,14 +52,15 @@ static size_t mem_avail = 0; * Access to the slab allocator is protected by this lock */ static pthread_mutex_t slabs_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t slabs_rebalance_lock = PTHREAD_MUTEX_INITIALIZER; /* * Forward Declarations */ static int do_slabs_newslab(const unsigned int id); static void *memory_allocate(size_t size); +static void do_slabs_free(void *ptr, const size_t size, unsigned int id); -#ifndef DONT_PREALLOC_SLABS /* Preallocate as many slab pages as possible (called from slabs_init) on start-up, so users don't get confused out-of-memory errors when they do have free (in-slab) space, but no space to make new slabs. @@ -70,7 +68,6 @@ static void *memory_allocate(size_t size); slab types can be made. if max memory is less than 18 MB, only the smaller ones will be made. */ static void slabs_preallocate (const unsigned int maxslabs); -#endif /* * Figures out which slab class (chunk size) is required to store an item of @@ -146,18 +143,11 @@ void slabs_init(const size_t limit, const double factor, const bool prealloc) { } -#ifndef DONT_PREALLOC_SLABS - { - char *pre_alloc = getenv("T_MEMD_SLABS_ALLOC"); - - if (pre_alloc == NULL || atoi(pre_alloc) != 0) { - slabs_preallocate(power_largest); - } + if (prealloc) { + slabs_preallocate(power_largest); } -#endif } -#ifndef DONT_PREALLOC_SLABS static void slabs_preallocate (const unsigned int maxslabs) { int i; unsigned int prealloc = 0; @@ -171,11 +161,15 @@ static void slabs_preallocate (const unsigned int maxslabs) { for (i = POWER_SMALLEST; i <= POWER_LARGEST; i++) { if (++prealloc > maxslabs) return; - do_slabs_newslab(i); + if (do_slabs_newslab(i) == 0) { + fprintf(stderr, "Error while preallocating slab memory!\n" + "If using -L or other prealloc options, max memory must be " + "at least %d megabytes.\n", power_largest); + exit(1); + } } } -#endif static int grow_slab_list (const unsigned int id) { slabclass_t *p = &slabclass[id]; @@ -189,9 +183,14 @@ static int grow_slab_list (const unsigned int id) { return 1; } -#ifndef __INTEL_COMPILER -#pragma GCC diagnostic ignored "-Wsign-compare" -#endif +static void split_slab_page_into_freelist(char *ptr, const unsigned int id) { + slabclass_t *p = &slabclass[id]; + int x; + for (x = 0; x < p->perslab; x++) { + do_slabs_free(ptr, 0, id); + ptr += p->size; + } +} static int do_slabs_newslab(const unsigned int id) { slabclass_t *p = &slabclass[id]; @@ -208,8 +207,7 @@ static int do_slabs_newslab(const unsigned int id) { } memset(ptr, 0, (size_t)len); - p->end_page_ptr = ptr; - p->end_page_free = p->perslab; + split_slab_page_into_freelist(ptr, id); p->slab_list[p->slabs++] = ptr; mem_malloced += len; @@ -232,21 +230,9 @@ static void *do_slabs_alloc(const size_t size, unsigned int id) { p = &slabclass[id]; assert(p->sl_curr == 0 || ((item *)p->slots)->slabs_clsid == 0); -#ifdef USE_SYSTEM_MALLOC - if (mem_limit && mem_malloced + size > mem_limit) { - MEMCACHED_SLABS_ALLOCATE_FAILED(size, id); - return 0; - } - mem_malloced += size; - ret = malloc(size); - MEMCACHED_SLABS_ALLOCATE(size, id, 0, ret); - return ret; -#endif - /* fail unless we have space at the end of a recently allocated page, we have something on our freelist, or we could allocate a new page */ - if (! (p->end_page_ptr != 0 || p->sl_curr != 0 || - do_slabs_newslab(id) != 0)) { + if (! (p->sl_curr != 0 || do_slabs_newslab(id) != 0)) { /* We don't have more memory available */ ret = NULL; } else if (p->sl_curr != 0) { @@ -256,15 +242,6 @@ static void *do_slabs_alloc(const size_t size, unsigned int id) { if (it->next) it->next->prev = 0; p->sl_curr--; ret = (void *)it; - } else { - /* if we recently allocated a whole page, return from that */ - assert(p->end_page_ptr != NULL); - ret = p->end_page_ptr; - if (--p->end_page_free != 0) { - p->end_page_ptr = ((caddr_t)p->end_page_ptr) + p->size; - } else { - p->end_page_ptr = 0; - } } if (ret) { @@ -289,12 +266,6 @@ static void do_slabs_free(void *ptr, const size_t size, unsigned int id) { MEMCACHED_SLABS_FREE(size, id, ptr); p = &slabclass[id]; -#ifdef USE_SYSTEM_MALLOC - mem_malloced -= size; - free(ptr); - return; -#endif - it = (item *)ptr; it->it_flags |= ITEM_SLABBED; it->prev = 0; @@ -367,9 +338,10 @@ static void do_slabs_stats(ADD_STAT add_stats, void *c) { APPEND_NUM_STAT(i, "total_pages", "%u", slabs); APPEND_NUM_STAT(i, "total_chunks", "%u", slabs * perslab); APPEND_NUM_STAT(i, "used_chunks", "%u", - slabs*perslab - p->sl_curr - p->end_page_free); + slabs*perslab - p->sl_curr); APPEND_NUM_STAT(i, "free_chunks", "%u", p->sl_curr); - APPEND_NUM_STAT(i, "free_chunks_end", "%u", p->end_page_free); + /* Stat is dead, but displaying zero instead of removing it. */ + APPEND_NUM_STAT(i, "free_chunks_end", "%u", 0); APPEND_NUM_STAT(i, "mem_requested", "%llu", (unsigned long long)p->requested); APPEND_NUM_STAT(i, "get_hits", "%llu", @@ -464,14 +436,15 @@ void slabs_adjust_mem_requested(unsigned int id, size_t old, size_t ntotal) } static pthread_cond_t maintenance_cond = PTHREAD_COND_INITIALIZER; +static pthread_cond_t slab_rebalance_cond = PTHREAD_COND_INITIALIZER; static volatile int do_run_slab_thread = 1; +static volatile int do_run_slab_rebalance_thread = 1; #define DEFAULT_SLAB_BULK_CHECK 1 int slab_bulk_check = DEFAULT_SLAB_BULK_CHECK; static int slab_rebalance_start(void) { slabclass_t *s_cls; - slabclass_t *d_cls; int no_go = 0; pthread_mutex_lock(&cache_lock); @@ -485,10 +458,8 @@ static int slab_rebalance_start(void) { no_go = -2; s_cls = &slabclass[slab_rebal.s_clsid]; - d_cls = &slabclass[slab_rebal.d_clsid]; - if (d_cls->end_page_ptr || s_cls->end_page_ptr || - !grow_slab_list(slab_rebal.d_clsid)) { + if (!grow_slab_list(slab_rebal.d_clsid)) { no_go = -1; } @@ -597,9 +568,6 @@ static int slab_rebalance_move(void) { break; case MOVE_PASS: break; - default: - assert(false); - abort(); } slab_rebal.slab_pos = (char *)slab_rebal.slab_pos + s_cls->size; @@ -642,8 +610,8 @@ static void slab_rebalance_finish(void) { memset(slab_rebal.slab_start, 0, (size_t)settings.item_size_max); d_cls->slab_list[d_cls->slabs++] = slab_rebal.slab_start; - d_cls->end_page_ptr = slab_rebal.slab_start; - d_cls->end_page_free = d_cls->perslab; + split_slab_page_into_freelist(slab_rebal.slab_start, + slab_rebal.d_clsid); slab_rebal.done = 0; slab_rebal.s_clsid = 0; @@ -735,43 +703,83 @@ static int slab_automove_decision(int *src, int *dst) { return 0; } -#ifndef __INTEL_COMPILER -#pragma GCC diagnostic ignored "-Wunused-parameter" -#endif /* Slab rebalancer thread. * Does not use spinlocks since it is not timing sensitive. Burn less CPU and * go to sleep if locks are contended */ static void *slab_maintenance_thread(void *arg) { - int was_busy = 0; int src, dest; while (do_run_slab_thread) { + if (settings.slab_automove == 1) { + if (slab_automove_decision(&src, &dest) == 1) { + /* Blind to the return codes. It will retry on its own */ + slabs_reassign(src, dest); + } + sleep(1); + } else { + /* Don't wake as often if we're not enabled. + * This is lazier than setting up a condition right now. */ + sleep(5); + } + } + return NULL; +} + +/* Slab mover thread. + * Sits waiting for a condition to jump off and shovel some memory about + */ +static void *slab_rebalance_thread(void *arg) { + int was_busy = 0; + + while (do_run_slab_rebalance_thread) { if (slab_rebalance_signal == 1) { if (slab_rebalance_start() < 0) { /* Handle errors with more specifity as required. */ slab_rebalance_signal = 0; } + was_busy = 0; } else if (slab_rebalance_signal && slab_rebal.slab_start != NULL) { - /* If we have a decision to continue, continue it */ was_busy = slab_rebalance_move(); - } else if (settings.slab_automove && slab_automove_decision(&src, &dest) == 1) { - /* Blind to the return codes. It will retry on its own */ - slabs_reassign(src, dest); } if (slab_rebal.done) { slab_rebalance_finish(); + } else if (was_busy) { + /* Stuck waiting for some items to unlock, so slow down a bit + * to give them a chance to free up */ + usleep(50); } - /* Sleep a bit if no work to do, or waiting on busy objects */ - if (was_busy || !slab_rebalance_signal) - sleep(1); + if (slab_rebalance_signal == 0) { + /* always hold this lock while we're running */ + pthread_cond_wait(&slab_rebalance_cond, &slabs_rebalance_lock); + } } return NULL; } +/* Iterate at most once through the slab classes and pick a "random" source. + * I like this better than calling rand() since rand() is slow enough that we + * can just check all of the classes once instead. + */ +static int slabs_reassign_pick_any(int dst) { + static int cur = POWER_SMALLEST - 1; + int tries = power_largest - POWER_SMALLEST + 1; + for (; tries > 0; tries--) { + cur++; + if (cur > power_largest) + cur = POWER_SMALLEST; + if (cur == dst) + continue; + if (slabclass[cur].slabs > 1) { + return cur; + } + } + return -1; +} + static enum reassign_result_type do_slabs_reassign(int src, int dst) { if (slab_rebalance_signal != 0) return REASSIGN_RUNNING; @@ -779,6 +787,12 @@ static enum reassign_result_type do_slabs_reassign(int src, int dst) { if (src == dst) return REASSIGN_SRC_DST_SAME; + /* Special indicator to choose ourselves. */ + if (src == -1) { + src = slabs_reassign_pick_any(dst); + /* TODO: If we end up back at -1, return a new error type */ + } + if (src < POWER_SMALLEST || src > power_largest || dst < POWER_SMALLEST || dst > power_largest) return REASSIGN_BADCLASS; @@ -786,29 +800,27 @@ static enum reassign_result_type do_slabs_reassign(int src, int dst) { if (slabclass[src].slabs < 2) return REASSIGN_NOSPARE; - if (slabclass[dst].end_page_ptr) - return REASSIGN_DEST_NOT_FULL; - - if (slabclass[src].end_page_ptr) - return REASSIGN_SRC_NOT_SAFE; - slab_rebal.s_clsid = src; slab_rebal.d_clsid = dst; slab_rebalance_signal = 1; + pthread_cond_signal(&slab_rebalance_cond); return REASSIGN_OK; } enum reassign_result_type slabs_reassign(int src, int dst) { enum reassign_result_type ret; - mutex_lock(&slabs_lock); + if (pthread_mutex_trylock(&slabs_rebalance_lock) != 0) { + return REASSIGN_RUNNING; + } ret = do_slabs_reassign(src, dst); - pthread_mutex_unlock(&slabs_lock); + pthread_mutex_unlock(&slabs_rebalance_lock); return ret; } static pthread_t maintenance_tid; +static pthread_t rebalance_tid; int start_slab_maintenance_thread(void) { int ret; @@ -821,9 +833,21 @@ int start_slab_maintenance_thread(void) { slab_bulk_check = DEFAULT_SLAB_BULK_CHECK; } } + + if (pthread_cond_init(&slab_rebalance_cond, NULL) != 0) { + fprintf(stderr, "Can't intiialize rebalance condition\n"); + return -1; + } + pthread_mutex_init(&slabs_rebalance_lock, NULL); + if ((ret = pthread_create(&maintenance_tid, NULL, slab_maintenance_thread, NULL)) != 0) { - fprintf(stderr, "Can't create thread: %s\n", strerror(ret)); + fprintf(stderr, "Can't create slab maint thread: %s\n", strerror(ret)); + return -1; + } + if ((ret = pthread_create(&rebalance_tid, NULL, + slab_rebalance_thread, NULL)) != 0) { + fprintf(stderr, "Can't create rebal thread: %s\n", strerror(ret)); return -1; } return 0; @@ -832,9 +856,11 @@ int start_slab_maintenance_thread(void) { void stop_slab_maintenance_thread(void) { mutex_lock(&cache_lock); do_run_slab_thread = 0; + do_run_slab_rebalance_thread = 0; pthread_cond_signal(&maintenance_cond); pthread_mutex_unlock(&cache_lock); /* Wait for the maintenance thread to stop */ pthread_join(maintenance_tid, NULL); + pthread_join(rebalance_tid, NULL); } diff --git a/memcached/slabs.h b/memcached/slabs.h index 90e2bd82..7c6140b2 100644 --- a/memcached/slabs.h +++ b/memcached/slabs.h @@ -16,9 +16,6 @@ void slabs_init(const size_t limit, const double factor, const bool prealloc); * 0 means error: can't store such a large object */ -#ifndef __INTEL_COMPILER -#pragma GCC diagnostic ignored "-Wshadow" -#endif unsigned int slabs_clsid(const size_t size); /** Allocate object of given length. 0 on error */ /*@null@*/ @@ -41,7 +38,7 @@ void stop_slab_maintenance_thread(void); enum reassign_result_type { REASSIGN_OK=0, REASSIGN_RUNNING, REASSIGN_BADCLASS, REASSIGN_NOSPARE, - REASSIGN_DEST_NOT_FULL, REASSIGN_SRC_NOT_SAFE, REASSIGN_SRC_DST_SAME + REASSIGN_SRC_DST_SAME }; enum reassign_result_type slabs_reassign(int src, int dst); diff --git a/memcached/t/binary.t b/memcached/t/binary.t index 504ddef1..3eb8e0b2 100755 --- a/memcached/t/binary.t +++ b/memcached/t/binary.t @@ -2,7 +2,7 @@ use strict; use warnings; -use Test::More tests => 3539; +use Test::More tests => 3549; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; @@ -273,6 +273,10 @@ is($mc->decr("x", 211), 0, "Floor is zero"); $check->("totouch", 0, "toast2"); # Test miss as well + $mc->set("totouch", "toast3", 0, 1); + $res = $mc->touch("totouch", 1); + sleep 3; + $empty->("totouch"); } # diag "Silent set."; diff --git a/memcached/t/slabs_reassign.t b/memcached/t/slabs_reassign.t index cf4b6f8d..ae5ddce3 100644 --- a/memcached/t/slabs_reassign.t +++ b/memcached/t/slabs_reassign.t @@ -2,7 +2,7 @@ use strict; use warnings; -use Test::More tests => 131; +use Test::More tests => 130; use FindBin qw($Bin); use lib "$Bin/lib"; use MemcachedTest; @@ -52,14 +52,16 @@ ok($slabs_before->{"31:total_pages"} != $slabs_after->{"31:total_pages"}, ok($slabs_before->{"25:total_pages"} != $slabs_after->{"25:total_pages"}, "slab 25 pagecount changed"); -# Try to move another slab, see that it complains +# Try to move another slab, see that you can move two in a row print $sock "slabs reassign 31 25\r\n"; -like(scalar <$sock>, qr/^NOTFULL/, "Cannot re-run against class with empty space"); +like(scalar <$sock>, qr/^OK/, "Cannot re-run against class with empty space"); # Try to move a page backwards. Should complain that source class isn't "safe" # to move from. -print $sock "slabs reassign 25 31\r\n"; -like(scalar <$sock>, qr/^UNSAFE/, "Cannot move an unsafe slab back"); +# TODO: Wait until the above command completes, then try to move it back? +# Seems pointless... +#print $sock "slabs reassign 25 31\r\n"; +#like(scalar <$sock>, qr/^UNSAFE/, "Cannot move an unsafe slab back"); # Try to insert items into both slabs print $sock "set bfoo51 0 0 70000\r\n", $bigdata, "\r\n"; diff --git a/memcached/t/whitespace.t b/memcached/t/whitespace.t index 22c610cb..7d5d9169 100755 --- a/memcached/t/whitespace.t +++ b/memcached/t/whitespace.t @@ -6,10 +6,11 @@ our @files; BEGIN { chdir "$Bin/.." or die; - my @exempted = qw(Makefile.am ChangeLog doc/Makefile.am); + my @exempted = qw(Makefile.am ChangeLog doc/Makefile.am README README.md); push(@exempted, glob("doc/*.xml")); push(@exempted, glob("doc/xml2rfc/*.xsl")); push(@exempted, glob("m4/*backport*m4")); + push(@exempted, glob("*.orig")); my %exempted_hash = map { $_ => 1 } @exempted; my @stuff = split /\0/, `git ls-files -z -c -m -o --exclude-standard`; @@ -29,7 +30,7 @@ BEGIN { use Test::More tests => scalar(@files); foreach my $f (@files) { - open(my $fh, $f) or die; + open(my $fh, $f) or die "Cannot open file $f: $!"; my $before = do { local $/; <$fh>; }; close ($fh); my $after = $before; diff --git a/memcached/testapp.c b/memcached/testapp.c index aba0b905..9faccf4e 100644 --- a/memcached/testapp.c +++ b/memcached/testapp.c @@ -382,8 +382,8 @@ static pid_t start_server(in_port_t *port_out, bool daemon, int timeout) { if (daemon) { /* loop and wait for the pid file.. There is a potential race * condition that the server just created the file but isn't - * finished writing the content, but I'll take the chance.... - */ + * finished writing the content, so we loop a few times + * reading as well */ while (access(pid_file, F_OK) == -1) { usleep(10); } @@ -394,7 +394,11 @@ static pid_t start_server(in_port_t *port_out, bool daemon, int timeout) { strerror(errno)); assert(false); } - assert(fgets(buffer, sizeof(buffer), fp) != NULL); + + /* Avoid race by retrying 20 times */ + for (int x = 0; x < 20 && fgets(buffer, sizeof(buffer), fp) == NULL; x++) { + usleep(10); + } fclose(fp); int32_t val; diff --git a/memcached/thread.c b/memcached/thread.c index e3622497..f4bbe1e7 100644 --- a/memcached/thread.c +++ b/memcached/thread.c @@ -88,7 +88,7 @@ unsigned short refcount_incr(unsigned short *refcount) { mutex_lock(&atomics_mutex); (*refcount)++; res = *refcount; - pthread_mutex_unlock(&atomics_mutex); + mutex_unlock(&atomics_mutex); return res; #endif } @@ -103,7 +103,7 @@ unsigned short refcount_decr(unsigned short *refcount) { mutex_lock(&atomics_mutex); (*refcount)--; res = *refcount; - pthread_mutex_unlock(&atomics_mutex); + mutex_unlock(&atomics_mutex); return res; #endif } @@ -113,7 +113,7 @@ void item_lock(uint32_t hv) { } void item_unlock(uint32_t hv) { - pthread_mutex_unlock(&item_locks[hv & item_lock_mask]); + mutex_unlock(&item_locks[hv & item_lock_mask]); } /* @@ -299,9 +299,6 @@ static void *worker_libevent(void *arg) { } -#ifndef __INTEL_COMPILER -#pragma GCC diagnostic ignored "-Wunused-parameter" -#endif /* * Processes an incoming "handle a new connection" item. This is called when * input arrives on the libevent wakeup pipe. @@ -508,7 +505,7 @@ enum store_item_type store_item(item *item, int comm, conn* c) { void item_flush_expired() { mutex_lock(&cache_lock); do_item_flush_expired(); - pthread_mutex_unlock(&cache_lock); + mutex_unlock(&cache_lock); } /* @@ -519,7 +516,7 @@ char *item_cachedump(unsigned int slabs_clsid, unsigned int limit, unsigned int mutex_lock(&cache_lock); ret = do_item_cachedump(slabs_clsid, limit, bytes); - pthread_mutex_unlock(&cache_lock); + mutex_unlock(&cache_lock); return ret; } @@ -529,7 +526,7 @@ char *item_cachedump(unsigned int slabs_clsid, unsigned int limit, unsigned int void item_stats(ADD_STAT add_stats, void *c) { mutex_lock(&cache_lock); do_item_stats(add_stats, c); - pthread_mutex_unlock(&cache_lock); + mutex_unlock(&cache_lock); } /* @@ -538,7 +535,7 @@ void item_stats(ADD_STAT add_stats, void *c) { void item_stats_sizes(ADD_STAT add_stats, void *c) { mutex_lock(&cache_lock); do_item_stats_sizes(add_stats, c); - pthread_mutex_unlock(&cache_lock); + mutex_unlock(&cache_lock); } /******************************* GLOBAL STATS ******************************/ @@ -658,9 +655,6 @@ void slab_stats_aggregate(struct thread_stats *stats, struct slab_stats *out) { } } -#ifndef __INTEL_COMPILER -#pragma GCC diagnostic ignored "-Wsign-compare" -#endif /* * Initializes the thread subsystem, creating various worker threads. * diff --git a/memcached/util.c b/memcached/util.c index d92e6212..ee1605c5 100644 --- a/memcached/util.c +++ b/memcached/util.c @@ -1,4 +1,4 @@ -#include "memcached.h" +#include #include #include @@ -8,6 +8,8 @@ #include #include +#include "memcached.h" + /* Avoid warnings on solaris, where isspace() is an index into an array, and gcc uses signed chars */ #define xisspace(c) isspace((unsigned char)c) diff --git a/memcached/version.m4 b/memcached/version.m4 deleted file mode 100644 index 59142923..00000000 --- a/memcached/version.m4 +++ /dev/null @@ -1 +0,0 @@ -m4_define([VERSION_NUMBER], [1.4.13]) -- 2.30.2