Updated to latest memcached
authorBrian Aker <brian@tangent.org>
Fri, 3 Aug 2012 11:11:58 +0000 (07:11 -0400)
committerBrian Aker <brian@tangent.org>
Fri, 3 Aug 2012 11:11:58 +0000 (07:11 -0400)
25 files changed:
configure.ac
libtest/cmdline.cc
memcached/README [deleted file]
memcached/README.md [new file with mode: 0644]
memcached/assoc.c
memcached/autogen.sh
memcached/cache.c
memcached/daemon.c
memcached/devtools/clean-whitespace.pl
memcached/doc/protocol.txt
memcached/hash.c
memcached/items.c
memcached/memcached.c
memcached/memcached.h
memcached/memcached.spec.in
memcached/memcached_dtrace.d
memcached/slabs.c
memcached/slabs.h
memcached/t/binary.t
memcached/t/slabs_reassign.t
memcached/t/whitespace.t
memcached/testapp.c
memcached/thread.c
memcached/util.c
memcached/version.m4 [deleted file]

index bcb2d32064666219281cf23c26eb85af75a0eb65..7b6127a078cd9d9c6c2ca32a1378a282ada65c0e 100644 (file)
@@ -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([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)
 
 AM_CONDITIONAL(BUILDING_LIBMEMCACHED, true)
 AM_CONDITIONAL(HAVE_LIBMEMCACHED, false)
index 3179d1928c89a07c101a57d2b5ce16172018deff..f43b1c28b72ca970d679e0b274ca5faa7ddc7628 100644 (file)
@@ -82,7 +82,6 @@ extern "C" {
 
 namespace {
 
 
 namespace {
 
-#if 0
   std::string print_argv(libtest::vchar_ptr_t& built_argv)
   {
     std::stringstream arg_buffer;
   std::string print_argv(libtest::vchar_ptr_t& built_argv)
   {
     std::stringstream arg_buffer;
@@ -96,8 +95,8 @@ namespace {
 
     return arg_buffer.str();
   }
 
     return arg_buffer.str();
   }
-#endif
 
 
+#if 0
   std::string print_argv(char** argv)
   {
     std::stringstream arg_buffer;
   std::string print_argv(char** argv)
   {
     std::stringstream arg_buffer;
@@ -109,6 +108,8 @@ namespace {
 
     return arg_buffer.str();
   }
 
     return arg_buffer.str();
   }
+#endif
+
 
   static Application::error_t int_to_error_t(int arg)
   {
 
   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);
   if (exit_code == Application::INVALID)
   {
     Error << print_argv(built_argv, _argc);
+    /
   }
 #endif
 
   }
 #endif
 
@@ -514,13 +516,11 @@ Application::error_t Application::join()
 
   slurp();
 
 
   slurp();
 
-#if 0
   if (exit_code == Application::INVALID)
   {
   if (exit_code == Application::INVALID)
   {
-    Error << print_argv(built_argv, _argc);
+    Error << print_argv(built_argv);
   }
   }
-#endif
-
+;
   return exit_code;
 }
 
   return exit_code;
 }
 
diff --git a/memcached/README b/memcached/README
deleted file mode 100644 (file)
index f20dd8c..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-Dependencies:
-
-   -- libevent, http://www.monkey.org/~provos/libevent/ (libevent-dev)
-
-If using Linux, you need a kernel with epoll.  Sure, libevent will
-work with normal select, but it sucks.
-
-epoll isn't in Linux 2.4, but there's a backport at:
-
-    http://www.xmailserver.org/linux-patches/nio-improve.html
-
-You want the epoll-lt patch (level-triggered).
-
-If you're using MacOS, you'll want libevent 1.1 or higher to deal with
-a kqueue bug.
-
-Also, be warned that the -k (mlockall) option to memcached might be
-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:
-
-    http://www.memcached.org
-
-Want to contribute?  Up-to-date pointers should be at:
-
-    http://contributing.appspot.com/memcached
diff --git a/memcached/README.md b/memcached/README.md
new file mode 100644 (file)
index 0000000..27a6896
--- /dev/null
@@ -0,0 +1,38 @@
+# Memcached
+
+## 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.
+
+epoll isn't in Linux 2.4, but there's a backport at:
+
+    http://www.xmailserver.org/linux-patches/nio-improve.html
+
+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.
+
+Also, be warned that the -k (mlockall) option to memcached might be
+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)
+
+## Website
+
+* http://www.memcached.org
+
+## Contributing
+
+Want to contribute?  Up-to-date pointers should be at:
+
+* http://contributing.appspot.com/memcached
index f14d85d80a20168420f907924c5a505cd49f420f..bcaf6f2692e4b4785b4580b07ba034a2f31c089f 100644 (file)
@@ -12,7 +12,6 @@
  */
 
 #include "memcached.h"
  */
 
 #include "memcached.h"
-
 #include <sys/stat.h>
 #include <sys/socket.h>
 #include <sys/signal.h>
 #include <sys/stat.h>
 #include <sys/socket.h>
 #include <sys/signal.h>
 
 static pthread_cond_t maintenance_cond = PTHREAD_COND_INITIALIZER;
 
 
 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 */
 
 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_cond_wait(&maintenance_cond, &cache_lock);
         }
 
-        pthread_mutex_unlock(&cache_lock);
+        mutex_unlock(&cache_lock);
     }
     return NULL;
 }
     }
     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);
     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);
 
     /* Wait for the maintenance thread to stop */
     pthread_join(maintenance_tid, NULL);
index c735394da8bb20c135d01bf86ecd03b5b4e0e1c6..a3a97672f82149af95e47871b0339877804b121b 100755 (executable)
@@ -39,7 +39,7 @@ $AUTOHEADER || exit 1
 
 echo "automake..."
 if test x$AUTOMAKE = x; then
 
 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
   if test x$AUTOMAKE = x; then
     die "Did not find a supported automake"
   fi
index 7dcf2fbb4468136ab79b4288a0b2e42216aeee7c..fcb3d2bfe1fd32083ec5401f11864df42a0e41bb 100644 (file)
@@ -1,5 +1,5 @@
 /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
 /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
-#include "memcached.h"
+#include <config.h>
 
 #include <stdlib.h>
 #include <string.h>
 
 #include <stdlib.h>
 #include <string.h>
@@ -68,6 +68,7 @@ void cache_destroy(cache_t *cache) {
     free(cache->name);
     free(cache->ptr);
     pthread_mutex_destroy(&cache->mutex);
     free(cache->name);
     free(cache->ptr);
     pthread_mutex_destroy(&cache->mutex);
+    free(cache);
 }
 
 void* cache_alloc(cache_t *cache) {
 }
 
 void* cache_alloc(cache_t *cache) {
index 2f189157633069fc8d4e2a0432e080bf631f979b..d42e5b08778df0810f4aa6cf6ef536fb534e711f 100644 (file)
  * SUCH DAMAGE.
  */
 
  * SUCH DAMAGE.
  */
 
+#include <config.h>
+
 #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
 
 #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 <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 
 #include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 
+#include "memcached.h"
+
 int daemonize(int nochdir, int noclose)
 {
     int fd;
 int daemonize(int nochdir, int noclose)
 {
     int fd;
index 95481ef401bcfb1825b6032622698b8d59a09d89..fe0580673ca95b87a051f9e450c1a742dea3f212 100755 (executable)
@@ -3,7 +3,7 @@ use strict;
 use FindBin qw($Bin);
 chdir "$Bin/.." or die;
 
 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"));
 push(@exempted, glob("doc/*.xml"));
 push(@exempted, glob("doc/xml2rfc/*.xsl"));
 push(@exempted, glob("m4/*backport*m4"));
index 1a844f0aaa539b33d8488cc8df2f406fdf75a0c3..b26d9625dfb3a6ab76088ce584c0d48b60a422b1 100644 (file)
@@ -354,6 +354,8 @@ slabs reassign <source class> <dest class>\r\n
 
 - <source class> is an id number for the slab class to steal a page from
 
 
 - <source class> 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"
+
 - <dest class> is an id number for the slab class to move a page to
 
 The response line could be one of:
 - <dest 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.
 
 
 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"
 
 
 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
 ----------
 
 Statistics
 ----------
 
@@ -406,7 +416,7 @@ settings, documented below.  In the other form it has some arguments:
 stats <args>\r\n
 
 Depending on <args>, various internal data is sent by the server. The
 stats <args>\r\n
 
 Depending on <args>, 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.
 
 of the protocol, and are subject to change for the convenience of
 memcache developers.
 
index 6c9b9b6aa5b9861e0fe207446fc0d89a003ef914..fcfc1ffcd321ed6658323fe3635b3123b6ad4a35 100644 (file)
  * whether it's big or little-endian. ENDIAN_LITTLE and ENDIAN_BIG
  * are set in the configure script.
  */
  * 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
 # 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
 #  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 */
     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 */
     }
 
 #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 */
     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 */
     }
 
   } 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 */
     case 1 : a+=k[0];
              break;
     case 0 : return c;  /* zero length strings require no mixing */
-    default:
-             abort();
     }
   }
 
     }
   }
 
index 58fc871787aae955ca21243b50c5ab26a3db5310..84011c4402a39f71eba3b097e11e6799b6f31b0a 100644 (file)
@@ -44,7 +44,7 @@ static unsigned int sizes[LARGEST_ID];
 void item_stats_reset(void) {
     mutex_lock(&cache_lock);
     memset(itemstats, 0, sizeof(itemstats));
 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++;
         } 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++;
                 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;
             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);
         }
         } 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));
         }
             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;
     }
 
         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 */
      * 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;
 
     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);
     assoc_insert(it, hv);
     item_link_q(it);
     refcount_incr(&it->refcount);
-    pthread_mutex_unlock(&cache_lock);
+    mutex_unlock(&cache_lock);
 
     return 1;
 }
 
     return 1;
 }
@@ -306,7 +316,7 @@ void do_item_unlink(item *it, const uint32_t hv) {
         item_unlink_q(it);
         do_item_remove(it);
     }
         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? */
 }
 
 /* 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);
         }
             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);
 }
 
     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 */
 /*@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;
     }
     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) {
 }
 
 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;
         }
     }
             it = NULL;
         }
     }
-    pthread_mutex_unlock(&cache_lock);
+    mutex_unlock(&cache_lock);
     int was_found = 0;
 
     if (settings.verbose > 2) {
     int was_found = 0;
 
     if (settings.verbose > 2) {
index 10374421c39f8b068e8cc221a39c7ef8e9ba125e..2cb0b2069028f91e62473a3869e0699ffe0d59bb 100644 (file)
@@ -125,9 +125,6 @@ static enum transmit_result transmit(conn *c);
  */
 static volatile bool allow_new_conns = true;
 static struct event maxconnsevent;
  */
 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};
 
 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.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) {
 }
 
 static const char *prot_text(enum protocol prot) {
-    const char *rv = "unknown";
+    char *rv = "unknown";
     switch(prot) {
         case ascii_prot:
             rv = "ascii";
     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;
         case negotiating_prot:
             rv = "auto-negotiate";
             break;
-        default:
-            abort();
     }
     return rv;
 }
     }
     return rv;
 }
@@ -639,9 +634,6 @@ static const char *state_text(enum conn_states state) {
     return statenames[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
 /*
  * 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;
 
 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_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";
     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 */
 }
 
 /* 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);
     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;
     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);
             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 */
     }
 
     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_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;
 
     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) {
 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,
     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.keylen = (uint16_t)htons(klen),
-        .response.extlen = (uint8_t)0,
         .response.datatype = (uint8_t)PROTOCOL_BINARY_RAW_BYTES,
         .response.datatype = (uint8_t)PROTOCOL_BINARY_RAW_BYTES,
-        .response.status = (uint16_t)0,
         .response.bodylen = htonl(bodylen),
         .response.bodylen = htonl(bodylen),
-        .response.opaque = c->opaque,
-        .response.cas = (uint64_t)0
+        .response.opaque = c->opaque
     };
 
     memcpy(buf, header.bytes, sizeof(header.response));
     };
 
     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) {
     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;
             }
             } 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_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);
     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("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 *)));
 
     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("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) {
 }
 
 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;
 /* 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 */
         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);
            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);
 
         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) {
 
     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;
     } 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)) {
 
 
     } 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)) {
 
 
     } 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_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;
             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 &&
             }
             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;
             case READ_MEMORY_ERROR: /* Failed to allocate more memory */
                 /* State already set by try_read_network */
                 break;
-            default:
-                assert(false);
-                abort();
             }
             break;
 
             }
             break;
 
@@ -4078,9 +4028,6 @@ static void drive_machine(conn *c) {
             case TRANSMIT_SOFT_ERROR:
                 stop = true;
                 break;
             case TRANSMIT_SOFT_ERROR:
                 stop = true;
                 break;
-            default:
-                assert(false);
-                abort();
             }
             break;
 
             }
             break;
 
@@ -4095,9 +4042,6 @@ static void drive_machine(conn *c) {
         case conn_max_state:
             assert(false);
             break;
         case conn_max_state:
             assert(false);
             break;
-        default:
-            assert(false);
-            abort();
         }
     }
 
         }
     }
 
@@ -4242,12 +4186,7 @@ static int server_socket(const char *interface,
         }
 #endif
 
         }
 #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 {
         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) {
 }
 
 static void usage(void) {
-    printf(RPACKAGE " " RVERSION "\n");
+    printf(PACKAGE " " VERSION "\n");
     printf("-p <num>      TCP port number to listen on (default: 11211)\n"
            "-U <num>      UDP port number to listen on (default: 11211, 0 is off)\n"
            "-s <file>     UNIX socket path to listen on (disables network support)\n"
     printf("-p <num>      TCP port number to listen on (default: 11211)\n"
            "-U <num>      UDP port number to listen on (default: 11211, 0 is off)\n"
            "-s <file>     UNIX socket path to listen on (disables network support)\n"
@@ -4569,7 +4508,7 @@ static void usage(void) {
 }
 
 static void usage_license(void) {
 }
 
 static void usage_license(void) {
-    printf(RPACKAGE " " RVERSION "\n\n");
+    printf(PACKAGE " " VERSION "\n\n");
     printf(
     "Copyright (c) 2003, Danga Interactive, Inc. <http://www.danga.com/>\n"
     "All rights reserved.\n"
     printf(
     "Copyright (c) 2003, Danga Interactive, Inc. <http://www.danga.com/>\n"
     "All rights reserved.\n"
@@ -4731,7 +4670,7 @@ static int enable_large_pages(void) {
 
     return ret;
 #else
 
     return ret;
 #else
-    return 0;
+    return -1;
 #endif
 }
 
 #endif
 }
 
@@ -4788,10 +4727,10 @@ int main (int argc, char **argv) {
         SLAB_AUTOMOVE
     };
     char *const subopts_tokens[] = {
         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
     };
 
         NULL
     };
 
@@ -4952,6 +4891,10 @@ int main (int argc, char **argv) {
         case 'L' :
             if (enable_large_pages() == 0) {
                 preallocate = true;
         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' :
             }
             break;
         case 'C' :
@@ -5041,7 +4984,15 @@ int main (int argc, char **argv) {
                 settings.slab_reassign = true;
                 break;
             case SLAB_AUTOMOVE:
                 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);
                 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 */
     stop_assoc_maintenance_thread();
 
     /* remove the PID file if we're a daemon */
-#if 0
     if (do_daemonize)
         remove_pidfile(pid_file);
     if (do_daemonize)
         remove_pidfile(pid_file);
-#endif
     /* Clean up strdup() call for bind() address */
     if (settings.inter)
       free(settings.inter);
     /* Clean up strdup() call for bind() address */
     if (settings.inter)
       free(settings.inter);
index d070502c023c70c8d99e8b44032afe715c84659f..edd7fcf8cfefbbc42dbcb732785a0778524f18f6 100644 (file)
@@ -10,7 +10,6 @@
 #endif
 
 #include <stdbool.h>
 #endif
 
 #include <stdbool.h>
-#include <stdlib.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/time.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/time.h>
@@ -74,7 +73,6 @@
 #define POWER_SMALLEST 1
 #define POWER_LARGEST  200
 #define CHUNK_ALIGN_BYTES 8
 #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
 #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 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 */
 };
 
     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;
 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
 
 
 #define ITEM_FETCHED 8
 
-#ifndef __INTEL_COMPILER
-#pragma GCC diagnostic ignored "-Wshadow"
-#endif
 /**
  * Structure for storing items within memcached.
  */
 /**
  * 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);
 
 
 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()
 extern void drop_privileges(void);
 #else
 #define drop_privileges()
index f473d8fa3ad01ff3d3646205fba492070c75024f..678be90a633767645bffbef618688c3f0055df88 100644 (file)
@@ -83,7 +83,7 @@ exit 0
 
 %files
 %defattr(-,root,root,-)
 
 %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
 %config(noreplace) %{_sysconfdir}/sysconfig/%{name}
 
 %dir %attr(750,nobody,nobody) %{_localstatedir}/run/memcached
index eeffb6f3e67bc9ba8e1a99e044333c1cf31d9ab1..0fe132c442933393504b242bb64bb82322b5e77e 100644 (file)
@@ -250,6 +250,17 @@ provider memcached {
     */
    probe command__append(int connid, const char *key, int keylen, int size, int64_t casid);
 
     */
    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
    /**
     * Fired for a cas-command.
     * @param connid connection id
index 7cffe43474927aa1bfb953e23611455214fac6d0..b74617e25de9ebc2c814e0515c8a63bb0315d358 100644 (file)
@@ -30,9 +30,6 @@ typedef struct {
     void *slots;           /* list of item ptrs */
     unsigned int sl_curr;   /* total free items in list */
 
     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 */
     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;
  * 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);
 
 /*
  * 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.
 /* 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);
    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
 
 /*
  * 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;
 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;
     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];
 
 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;
 }
 
     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];
 
 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);
     }
 
     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;
 
     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);
 
     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 */
     /* 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) {
         /* 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;
         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) {
     }
 
     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];
 
     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;
     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",
             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", "%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",
             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 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_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;
 
 #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);
     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];
         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;
     }
 
         no_go = -1;
     }
 
@@ -597,9 +568,6 @@ static int slab_rebalance_move(void) {
                 break;
             case MOVE_PASS:
                 break;
                 break;
             case MOVE_PASS:
                 break;
-            default:
-                assert(false);
-                abort();
         }
 
         slab_rebal.slab_pos = (char *)slab_rebal.slab_pos + s_cls->size;
         }
 
         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;
     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;
 
     slab_rebal.done       = 0;
     slab_rebal.s_clsid    = 0;
@@ -735,43 +703,83 @@ static int slab_automove_decision(int *src, int *dst) {
     return 0;
 }
 
     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) {
 /* 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) {
     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;
             }
 
         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) {
         } else if (slab_rebalance_signal && slab_rebal.slab_start != NULL) {
-            /* If we have a decision to continue, continue it */
             was_busy = slab_rebalance_move();
             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();
         }
 
         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;
 }
 
     }
     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;
 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;
 
     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;
     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[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;
     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;
 
     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);
     ret = do_slabs_reassign(src, dst);
-    pthread_mutex_unlock(&slabs_lock);
+    pthread_mutex_unlock(&slabs_rebalance_lock);
     return ret;
 }
 
 static pthread_t maintenance_tid;
     return ret;
 }
 
 static pthread_t maintenance_tid;
+static pthread_t rebalance_tid;
 
 int start_slab_maintenance_thread(void) {
     int ret;
 
 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;
         }
     }
             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) {
     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;
         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;
 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_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);
 }
 }
index 90e2bd820fd601876887dfd35df08571597c7289..7c6140b2b40458fe58d83b84ad70007f0589385d 100644 (file)
@@ -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
  */
 
  * 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@*/
 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,
 
 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);
 };
 
 enum reassign_result_type slabs_reassign(int src, int dst);
index 504ddef1d7b6076801b4a15cc22ba46d433cc0fe..3eb8e0b243139e3c59bcf6e5126c89ab0db3392f 100755 (executable)
@@ -2,7 +2,7 @@
 
 use strict;
 use warnings;
 
 use strict;
 use warnings;
-use Test::More tests => 3539;
+use Test::More tests => 3549;
 use FindBin qw($Bin);
 use lib "$Bin/lib";
 use MemcachedTest;
 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
     $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.";
 }
 
 # diag "Silent set.";
index cf4b6f8d927a76fceafb6d8261bee2e21b38b65e..ae5ddce31232350d9df14cc3beed9d8ce6105df8 100644 (file)
@@ -2,7 +2,7 @@
 
 use strict;
 use warnings;
 
 use strict;
 use warnings;
-use Test::More tests => 131;
+use Test::More tests => 130;
 use FindBin qw($Bin);
 use lib "$Bin/lib";
 use MemcachedTest;
 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");
 
 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";
 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.
 
 # 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";
 
 # Try to insert items into both slabs
 print $sock "set bfoo51 0 0 70000\r\n", $bigdata, "\r\n";
index 22c610cbda2563d813b9258db1dfa61ce730491e..7d5d91691341f64ccfd38da9df77df4e165f53c5 100755 (executable)
@@ -6,10 +6,11 @@ our @files;
 BEGIN {
     chdir "$Bin/.." or die;
 
 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("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`;
     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) {
 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;
     my $before = do { local $/; <$fh>; };
     close ($fh);
     my $after = $before;
index aba0b90519b78d9726be67ebaf1a1083ecae4bb8..9faccf4e11cc2fe0e59600a31d82cb490ce2481a 100644 (file)
@@ -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
     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);
         }
         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);
         }
                     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;
         fclose(fp);
 
         int32_t val;
index e362249733d47674f39b683898a85da0c880bf38..f4bbe1e78d4e5ed8ff90ca80933239adc7e9fbc6 100644 (file)
@@ -88,7 +88,7 @@ unsigned short refcount_incr(unsigned short *refcount) {
     mutex_lock(&atomics_mutex);
     (*refcount)++;
     res = *refcount;
     mutex_lock(&atomics_mutex);
     (*refcount)++;
     res = *refcount;
-    pthread_mutex_unlock(&atomics_mutex);
+    mutex_unlock(&atomics_mutex);
     return res;
 #endif
 }
     return res;
 #endif
 }
@@ -103,7 +103,7 @@ unsigned short refcount_decr(unsigned short *refcount) {
     mutex_lock(&atomics_mutex);
     (*refcount)--;
     res = *refcount;
     mutex_lock(&atomics_mutex);
     (*refcount)--;
     res = *refcount;
-    pthread_mutex_unlock(&atomics_mutex);
+    mutex_unlock(&atomics_mutex);
     return res;
 #endif
 }
     return res;
 #endif
 }
@@ -113,7 +113,7 @@ void item_lock(uint32_t hv) {
 }
 
 void item_unlock(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.
 /*
  * 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();
 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);
 
     mutex_lock(&cache_lock);
     ret = do_item_cachedump(slabs_clsid, limit, bytes);
-    pthread_mutex_unlock(&cache_lock);
+    mutex_unlock(&cache_lock);
     return ret;
 }
 
     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);
 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);
 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 ******************************/
 }
 
 /******************************* 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.
  *
 /*
  * Initializes the thread subsystem, creating various worker threads.
  *
index d92e6212b8846d38d6401b73dd34b1b241c9a6b3..ee1605c52900e915aaafdb5c0649eca3fa19c166 100644 (file)
@@ -1,4 +1,4 @@
-#include "memcached.h"
+#include <config.h>
 
 #include <stdio.h>
 #include <assert.h>
 
 #include <stdio.h>
 #include <assert.h>
@@ -8,6 +8,8 @@
 #include <stdlib.h>
 #include <stdarg.h>
 
 #include <stdlib.h>
 #include <stdarg.h>
 
+#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)
 
 /* 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 (file)
index 5914292..0000000
+++ /dev/null
@@ -1 +0,0 @@
-m4_define([VERSION_NUMBER], [1.4.13])