Hello community, here is the log from the commit of package memcached for openSUSE:Factory checked in at 2012-11-12 07:04:17 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/memcached (Old) and /work/SRC/openSUSE:Factory/.memcached.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "memcached", Maintainer is "[email protected]" Changes: -------- --- /work/SRC/openSUSE:Factory/memcached/memcached.changes 2012-08-15 11:20:02.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.memcached.new/memcached.changes 2012-11-12 07:04:18.000000000 +0100 @@ -1,0 +2,24 @@ +Wed Nov 7 20:47:22 UTC 2012 - [email protected] + +- update to version 1.4.15 + * Add some mild thread documentation + * README.md was missing from dist tarball + * Issue 286 : --disable-coverage drops "-pthread" option + * Reduce odds of getting OOM errors in some odd cases +- rebase use-endian_h, autofoo patch and 1.4.5.dif +- fix build <= 1140 + * export LIBEVENT_CFLAGS and LIBEVENT_LIBS so we dont need + pkgconfig check for libevent on <= 1140 + +------------------------------------------------------------------- +Wed Nov 7 19:58:59 UTC 2012 - [email protected] + +- fix build on older distros + - memcached-autofoo.patch: removed no-dist-gzip dist-xz + - added new conditional to guard all the systemd stuff and + guarded the general bcond_without with an suse_version > 12.2 + - export LIBEVENT_CFLAGS and LIBEVENT_LIBS so we dont need + pkgconfig check for libevent on sles11 + - use makeinstall instead of make_install + +------------------------------------------------------------------- Old: ---- memcached-1.4.14.tar.gz New: ---- memcached-1.4.15.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ memcached.spec ++++++ --- /var/tmp/diff_new_pack.Eg19fT/_old 2012-11-12 07:04:20.000000000 +0100 +++ /var/tmp/diff_new_pack.Eg19fT/_new 2012-11-12 07:04:20.000000000 +0100 @@ -16,8 +16,12 @@ # +%if 0%{?suse_version} > 1210 +%bcond_without systemd +%endif + Name: memcached -Version: 1.4.14 +Version: 1.4.15 Release: 0 %define pkg_name memcached %define pkg_version %{version} @@ -32,7 +36,9 @@ BuildRequires: automake BuildRequires: cyrus-sasl-devel BuildRequires: pkgconfig +%if %{with systemd} BuildRequires: systemd +%endif PreReq: %insserv_prereq %fillup_prereq /usr/sbin/groupadd /usr/sbin/useradd Conflicts: memcached-unstable %define home_dir /var/lib/%{pkg_name} @@ -50,8 +56,9 @@ Summary: A high-performance, distributed memory object caching system License: BSD-3-Clause Group: Productivity/Networking/Other +%if %{with systemd} %{?systemd_requires} - +%endif %description Memcached is a high-performance, distributed memory object caching system, generic in nature, but intended for use in speeding up dynamic @@ -73,6 +80,10 @@ %build autoreconf -fiv +%if 0%{?suse_version} <= 1140 +export LIBEVENT_CFLAGS="-I%{_includedir}" +export LIBEVENT_LIBS="-levent" +%endif %configure --enable-sasl --disable-coverage --bindir=%{_sbindir} make %{?_smp_mflags} @@ -81,32 +92,44 @@ %{__make} test %install -%make_install +%makeinstall %{__install} -D -m 0755 scripts/memcached-tool %{buildroot}%{_sbindir}/memcached-tool %{__install} -Dd -m 0755 %{buildroot}%{home_dir} %{__install} -D -m 0755 %{S:1} %{buildroot}%{_sysconfdir}/init.d/%{pkg_name} %{__ln_s} -f ../..%{_sysconfdir}/init.d/%{pkg_name} %{buildroot}%{_sbindir}/rc%{pkg_name} %{__install} -D -m 0644 %{S:2} %{buildroot}/var/adm/fillup-templates/sysconfig.%{pkg_name} +%if %{with systemd} %{__install} -D -m 0644 %{S:4} %{buildroot}%{_unitdir}/%{pkg_name}.service +%endif + %clean %{__rm} -rf %{buildroot}; %pre /usr/sbin/groupadd -r %{pkg_name} &>/dev/null || : /usr/sbin/useradd -o -g %{pkg_name} -s /bin/false -r -c "user for %{pkg_name}" -d %{home_dir} %{pkg_name} &>/dev/null || : +%if %{with systemd} %service_add_pre %{pkg_name}.service +%endif %post %fillup_and_insserv %{pkg_name} +%if %{with systemd} %service_add_post %{pkg_name}.service +%endif + %preun %stop_on_removal %{pkg_name} +%if %{with systemd} %service_del_preun %{pkg_name}.service +%endif %postun %restart_on_update %{pkg_name} %{insserv_cleanup} +%if %{with systemd} %service_del_postun %{pkg_name}.service +%endif %files %defattr(-,root,root) @@ -120,6 +143,8 @@ %{_includedir}/%{pkg_name} /var/adm/fillup-templates/sysconfig.%{pkg_name} %dir %attr(755,root,root) %{home_dir} +%if %{with systemd} %{_unitdir}/%{pkg_name}.service +%endif %changelog ++++++ memcached-1.4.14.tar.gz -> memcached-1.4.15.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/memcached-1.4.14/Makefile.am new/memcached-1.4.15/Makefile.am --- old/memcached-1.4.14/Makefile.am 2012-01-06 19:19:50.000000000 +0100 +++ new/memcached-1.4.15/Makefile.am 2012-09-03 20:23:23.000000000 +0200 @@ -69,7 +69,7 @@ SUBDIRS = doc DIST_DIRS = scripts -EXTRA_DIST = doc scripts t memcached.spec memcached_dtrace.d version.m4 +EXTRA_DIST = doc scripts t memcached.spec memcached_dtrace.d version.m4 README.md MOSTLYCLEANFILES = *.gcov *.gcno *.gcda *.tcov diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/memcached-1.4.14/Makefile.in new/memcached-1.4.15/Makefile.in --- old/memcached-1.4.14/Makefile.in 2012-07-30 22:56:58.000000000 +0200 +++ new/memcached-1.4.15/Makefile.in 2012-09-04 02:13:01.000000000 +0200 @@ -324,7 +324,7 @@ CLEANFILES = $(am__append_6) $(am__append_11) SUBDIRS = doc DIST_DIRS = scripts -EXTRA_DIST = doc scripts t memcached.spec memcached_dtrace.d version.m4 +EXTRA_DIST = doc scripts t memcached.spec memcached_dtrace.d version.m4 README.md MOSTLYCLEANFILES = *.gcov *.gcno *.gcda *.tcov all: $(BUILT_SOURCES) config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/memcached-1.4.14/README.md new/memcached-1.4.15/README.md --- old/memcached-1.4.14/README.md 1970-01-01 01:00:00.000000000 +0100 +++ new/memcached-1.4.15/README.md 2012-07-30 03:05:16.000000000 +0200 @@ -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 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/memcached-1.4.14/assoc.c new/memcached-1.4.15/assoc.c --- old/memcached-1.4.14/assoc.c 2012-07-30 22:21:59.000000000 +0200 +++ new/memcached-1.4.15/assoc.c 2012-09-03 20:23:23.000000000 +0200 @@ -32,7 +32,7 @@ typedef unsigned char ub1; /* unsigned 1-byte quantities */ /* how many powers of 2's worth of buckets we use */ -static unsigned int hashpower = HASHPOWER_DEFAULT; +unsigned int hashpower = HASHPOWER_DEFAULT; #define hashsize(n) ((ub4)1<<(n)) #define hashmask(n) (hashsize(n)-1) @@ -51,6 +51,7 @@ /* Flag: Are we in the middle of expanding now? */ static bool expanding = false; +static bool started_expanding = false; /* * During expansion we migrate values with bucket granularity; this is how @@ -136,13 +137,19 @@ stats.hash_bytes += hashsize(hashpower) * sizeof(void *); stats.hash_is_expanding = 1; STATS_UNLOCK(); - pthread_cond_signal(&maintenance_cond); } else { primary_hashtable = old_hashtable; /* Bad news, but we can keep running. */ } } +static void assoc_start_expand(void) { + if (started_expanding) + return; + started_expanding = true; + pthread_cond_signal(&maintenance_cond); +} + /* Note: this isn't an assoc_update. The key must not already exist to call this */ int assoc_insert(item *it, const uint32_t hv) { unsigned int oldbucket; @@ -161,7 +168,7 @@ hash_items++; if (! expanding && hash_items > (hashsize(hashpower) * 3) / 2) { - assoc_expand(); + assoc_start_expand(); } MEMCACHED_ASSOC_INSERT(ITEM_key(it), it->nkey, hash_items); @@ -201,6 +208,7 @@ /* Lock the cache, and bulk move multiple buckets to the new * hash table. */ + item_lock_global(); mutex_lock(&cache_lock); for (ii = 0; ii < hash_bulk_move && expanding; ++ii) { @@ -230,12 +238,25 @@ } } + mutex_unlock(&cache_lock); + item_unlock_global(); + if (!expanding) { + /* finished expanding. tell all threads to use fine-grained locks */ + switch_item_lock_type(ITEM_LOCK_GRANULAR); + slabs_rebalancer_resume(); /* We are done expanding.. just wait for next invocation */ + mutex_lock(&cache_lock); + started_expanding = false; pthread_cond_wait(&maintenance_cond, &cache_lock); + /* Before doing anything, tell threads to use a global lock */ + mutex_unlock(&cache_lock); + slabs_rebalancer_pause(); + switch_item_lock_type(ITEM_LOCK_GLOBAL); + mutex_lock(&cache_lock); + assoc_expand(); + mutex_unlock(&cache_lock); } - - mutex_unlock(&cache_lock); } return NULL; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/memcached-1.4.14/assoc.h new/memcached-1.4.15/assoc.h --- old/memcached-1.4.14/assoc.h 2012-01-06 19:19:50.000000000 +0100 +++ new/memcached-1.4.15/assoc.h 2012-09-03 20:23:23.000000000 +0200 @@ -6,4 +6,4 @@ void do_assoc_move_next_bucket(void); int start_assoc_maintenance_thread(void); void stop_assoc_maintenance_thread(void); - +extern unsigned int hashpower; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/memcached-1.4.14/configure new/memcached-1.4.15/configure --- old/memcached-1.4.14/configure 2012-07-30 22:56:58.000000000 +0200 +++ new/memcached-1.4.15/configure 2012-09-04 02:13:01.000000000 +0200 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.65 for memcached 1.4.14. +# Generated by GNU Autoconf 2.65 for memcached 1.4.15. # # Report bugs to <[email protected]>. # @@ -552,8 +552,8 @@ # Identity of this package. PACKAGE_NAME='memcached' PACKAGE_TARNAME='memcached' -PACKAGE_VERSION='1.4.14' -PACKAGE_STRING='memcached 1.4.14' +PACKAGE_VERSION='1.4.15' +PACKAGE_STRING='memcached 1.4.15' PACKAGE_BUGREPORT='[email protected]' PACKAGE_URL='' @@ -1272,7 +1272,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures memcached 1.4.14 to adapt to many kinds of systems. +\`configure' configures memcached 1.4.15 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1343,7 +1343,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of memcached 1.4.14:";; + short | recursive ) echo "Configuration of memcached 1.4.15:";; esac cat <<\_ACEOF @@ -1441,7 +1441,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -memcached configure 1.4.14 +memcached configure 1.4.15 generated by GNU Autoconf 2.65 Copyright (C) 2009 Free Software Foundation, Inc. @@ -1905,7 +1905,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by memcached $as_me 1.4.14, which was +It was created by memcached $as_me 1.4.15, which was generated by GNU Autoconf 2.65. Invocation command line was $ $0 $@ @@ -2825,7 +2825,7 @@ # Define the identity of the package. PACKAGE=memcached - VERSION=1.4.14 + VERSION=1.4.15 cat >>confdefs.h <<_ACEOF @@ -4294,6 +4294,9 @@ fi +if test "$ICC" = "yes" -o "$GCC" = "yes"; then : + CFLAGS="$CFLAGS -pthread" +fi if test "$ICC" = "no"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5 @@ -4848,10 +4851,7 @@ if test "x$enable_coverage" != "xno"; then - if test "$ICC" = "yes" - then - CFLAGS="$CFLAGS -pthread" - elif test "$GCC" = "yes" + if test "$GCC" = "yes" -a "$ICC" != "yes" then CFLAGS="$CFLAGS -pthread" # Extract the first word of "gcov", so it can be a program name with args. @@ -6822,7 +6822,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by memcached $as_me 1.4.14, which was +This file was extended by memcached $as_me 1.4.15, which was generated by GNU Autoconf 2.65. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -6888,7 +6888,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -memcached config.status 1.4.14 +memcached config.status 1.4.15 configured by $0, generated by GNU Autoconf 2.65, with options \\"\$ac_cs_config\\" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/memcached-1.4.14/configure.ac new/memcached-1.4.15/configure.ac --- old/memcached-1.4.14/configure.ac 2012-02-02 07:01:29.000000000 +0100 +++ new/memcached-1.4.15/configure.ac 2012-09-03 09:35:54.000000000 +0200 @@ -49,6 +49,8 @@ ]) DETECT_SUNCC([CFLAGS="-mt $CFLAGS"], []) +AS_IF([test "$ICC" = "yes" -o "$GCC" = "yes"], + [CFLAGS="$CFLAGS -pthread"]) if test "$ICC" = "no"; then AC_PROG_CC_C99 @@ -140,11 +142,7 @@ [AS_HELP_STRING([--disable-coverage],[Disable code coverage])]) if test "x$enable_coverage" != "xno"; then - if test "$ICC" = "yes" - then - dnl ICC trying to be gcc, but not well - CFLAGS="$CFLAGS -pthread" - elif test "$GCC" = "yes" + if test "$GCC" = "yes" -a "$ICC" != "yes" then CFLAGS="$CFLAGS -pthread" AC_PATH_PROG([PROFILER], [gcov], "no", [$PATH]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/memcached-1.4.14/doc/Makefile new/memcached-1.4.15/doc/Makefile --- old/memcached-1.4.14/doc/Makefile 2012-07-30 22:57:03.000000000 +0200 +++ new/memcached-1.4.15/doc/Makefile 2012-09-04 02:13:06.000000000 +0200 @@ -82,7 +82,7 @@ AWK = gawk CC = gcc -std=gnu99 CCDEPMODE = depmode=gcc3 -CFLAGS = -g -O2 -pthread -Wall -Werror -pedantic -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -fno-strict-aliasing +CFLAGS = -g -O2 -pthread -pthread -Wall -Werror -pedantic -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -fno-strict-aliasing CPP = gcc -E CPPFLAGS = CYGPATH_W = echo @@ -112,10 +112,10 @@ PACKAGE = memcached PACKAGE_BUGREPORT = [email protected] PACKAGE_NAME = memcached -PACKAGE_STRING = memcached 1.4.14 +PACKAGE_STRING = memcached 1.4.15 PACKAGE_TARNAME = memcached PACKAGE_URL = -PACKAGE_VERSION = 1.4.14 +PACKAGE_VERSION = 1.4.15 PATH_SEPARATOR = : PROFILER = /usr/bin/gcov PROFILER_FLAGS = -fprofile-arcs -ftest-coverage @@ -123,7 +123,7 @@ SET_MAKE = SHELL = /bin/bash STRIP = -VERSION = 1.4.14 +VERSION = 1.4.15 XML2RFC = no XSLTPROC = /usr/bin/xsltproc abs_builddir = /home/dormando/p/danga/git/memcached/doc diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/memcached-1.4.14/doc/threads.txt new/memcached-1.4.15/doc/threads.txt --- old/memcached-1.4.14/doc/threads.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/memcached-1.4.15/doc/threads.txt 2012-09-04 00:17:10.000000000 +0200 @@ -0,0 +1,46 @@ +WARNING: This document is currently a stub. It is incomplete, but provided to +give a vague overview of how threads are implemented. + +Multithreading in memcached *was* originally simple: + +- One listener thread +- N "event worker" threads +- Some misc background threads + +Each worker thread is assigned connections, and runs its own epoll loop. The +central hash table, LRU lists, and some statistics counters are covered by +global locks. Protocol parsing, data transfer happens in threads. Data lookups +and modifications happen under central locks. + +THIS HAS CHANGED! + +I do need to flesh this out more, and it'll need a lot more tuning, but it has +changed in the following ways: + +- A secondary small hash table of locks is used to lock an item by its hash + value. This prevents multiple threads from acting on the same item at the + same time. +- This secondary hash table is mapped to the central hash tables buckets. This + allows multiple threads to access the hash table in parallel. Only one + thread may read or write against a particular hash table bucket. +- atomic refcounts per item are used to manage garbage collection and + mutability. +- A central lock is still held around any "item modifications" - any change to + any item flags on any item, the LRU state, or refcount incrementing are + still centrally locked. + +- When pulling an item off of the LRU tail for eviction or re-allocation, the + system must attempt to lock the item's bucket, which is done with a trylock + to avoid deadlocks. If a bucket is in use (and not by that thread) it will + walk up the LRU a little in an attempt to fetch a non-busy item. + +Since I'm sick of hearing it: + +- If you remove the per-thread stats lock, CPU usage goes down by less than a + point of a percent, and it does not improve scalability. +- In my testing, the remaining global STATS_LOCK calls never seem to collide. + +Yes, more stats can be moved to threads, and those locks can actually be +removed entirely on x86-64 systems. However my tests haven't shown that as +beneficial so far, so I've prioritized other work. Apologies for the rant but +it's a common question. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/memcached-1.4.14/items.c new/memcached-1.4.15/items.c --- old/memcached-1.4.14/items.c 2012-07-30 22:23:37.000000000 +0200 +++ new/memcached-1.4.15/items.c 2012-09-03 20:23:23.000000000 +0200 @@ -85,7 +85,9 @@ } /*@null@*/ -item *do_item_alloc(char *key, const size_t nkey, const int flags, const rel_time_t exptime, const int nbytes) { +item *do_item_alloc(char *key, const size_t nkey, const int flags, + const rel_time_t exptime, const int nbytes, + const uint32_t cur_hv) { uint8_t nsuffix; item *it = NULL; char suffix[40]; @@ -100,87 +102,93 @@ mutex_lock(&cache_lock); /* do a quick check if we have any expired items in the tail.. */ + int tries = 5; + int tried_alloc = 0; item *search; + void *hold_lock = NULL; rel_time_t oldest_live = settings.oldest_live; search = tails[id]; - if (search != NULL && (refcount_incr(&search->refcount) == 2)) { + /* We walk up *only* for locked items. Never searching for expired. + * Waste of CPU for almost all deployments */ + for (; tries > 0 && search != NULL; tries--, search=search->prev) { + uint32_t hv = hash(ITEM_key(search), search->nkey, 0); + /* Attempt to hash item lock the "search" item. If locked, no + * other callers can incr the refcount + */ + /* FIXME: I think we need to mask the hv here for comparison? */ + if (hv != cur_hv && (hold_lock = item_trylock(hv)) == NULL) + continue; + /* Now see if the item is refcount locked */ + if (refcount_incr(&search->refcount) != 2) { + refcount_decr(&search->refcount); + /* Old rare bug could cause a refcount leak. We haven't seen + * it in years, but we leave this code in to prevent failures + * just in case */ + if (search->time + TAIL_REPAIR_TIME < current_time) { + itemstats[id].tailrepairs++; + search->refcount = 1; + do_item_unlink_nolock(search, hv); + } + if (hold_lock) + item_trylock_unlock(hold_lock); + continue; + } + + /* Expired or flushed */ if ((search->exptime != 0 && search->exptime < current_time) - || (search->time <= oldest_live && oldest_live <= current_time)) { // dead by flush - STATS_LOCK(); - stats.reclaimed++; - STATS_UNLOCK(); + || (search->time <= oldest_live && oldest_live <= current_time)) { itemstats[id].reclaimed++; if ((search->it_flags & ITEM_FETCHED) == 0) { - STATS_LOCK(); - stats.expired_unfetched++; - STATS_UNLOCK(); itemstats[id].expired_unfetched++; } it = search; slabs_adjust_mem_requested(it->slabs_clsid, ITEM_ntotal(it), ntotal); - do_item_unlink_nolock(it, hash(ITEM_key(it), it->nkey, 0)); + do_item_unlink_nolock(it, hv); /* Initialize the item block: */ it->slabs_clsid = 0; } else if ((it = slabs_alloc(ntotal, id)) == NULL) { + tried_alloc = 1; if (settings.evict_to_free == 0) { itemstats[id].outofmemory++; - mutex_unlock(&cache_lock); - return NULL; - } - itemstats[id].evicted++; - itemstats[id].evicted_time = current_time - search->time; - if (search->exptime != 0) - itemstats[id].evicted_nonzero++; - if ((search->it_flags & ITEM_FETCHED) == 0) { - STATS_LOCK(); - stats.evicted_unfetched++; - STATS_UNLOCK(); - itemstats[id].evicted_unfetched++; + } else { + itemstats[id].evicted++; + itemstats[id].evicted_time = current_time - search->time; + if (search->exptime != 0) + itemstats[id].evicted_nonzero++; + if ((search->it_flags & ITEM_FETCHED) == 0) { + itemstats[id].evicted_unfetched++; + } + it = search; + slabs_adjust_mem_requested(it->slabs_clsid, ITEM_ntotal(it), ntotal); + do_item_unlink_nolock(it, hv); + /* 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); } - STATS_LOCK(); - stats.evictions++; - STATS_UNLOCK(); - it = search; - slabs_adjust_mem_requested(it->slabs_clsid, ITEM_ntotal(it), ntotal); - 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 { - /* If the LRU is empty or locked, attempt to allocate memory */ - it = slabs_alloc(ntotal, id); - if (search != NULL) - refcount_decr(&search->refcount); + + refcount_decr(&search->refcount); + /* If hash values were equal, we don't grab a second lock */ + if (hold_lock) + item_trylock_unlock(hold_lock); + break; } + if (!tried_alloc && (tries == 0 || search == NULL)) + it = slabs_alloc(ntotal, id); + if (it == NULL) { itemstats[id].outofmemory++; - /* Last ditch effort. There was a very rare bug which caused - * refcount leaks. We leave this just in case they ever happen again. - * We can reasonably assume no item can stay locked for more than - * three hours, so if we find one in the tail which is that old, - * free it anyway. - */ - if (search != NULL && - search->refcount != 2 && - search->time + TAIL_REPAIR_TIME < current_time) { - itemstats[id].tailrepairs++; - search->refcount = 1; - do_item_unlink_nolock(search, hash(ITEM_key(search), search->nkey, 0)); - } mutex_unlock(&cache_lock); return NULL; } @@ -416,6 +424,26 @@ mutex_unlock(&cache_lock); } +void do_item_stats_totals(ADD_STAT add_stats, void *c) { + itemstats_t totals; + memset(&totals, 0, sizeof(itemstats_t)); + int i; + for (i = 0; i < LARGEST_ID; i++) { + totals.expired_unfetched += itemstats[i].expired_unfetched; + totals.evicted_unfetched += itemstats[i].evicted_unfetched; + totals.evicted += itemstats[i].evicted; + totals.reclaimed += itemstats[i].reclaimed; + } + APPEND_STAT("expired_unfetched", "%llu", + (unsigned long long)totals.expired_unfetched); + APPEND_STAT("evicted_unfetched", "%llu", + (unsigned long long)totals.evicted_unfetched); + APPEND_STAT("evictions", "%llu", + (unsigned long long)totals.evicted); + APPEND_STAT("reclaimed", "%llu", + (unsigned long long)totals.reclaimed); +} + void do_item_stats(ADD_STAT add_stats, void *c) { int i; for (i = 0; i < LARGEST_ID; i++) { @@ -491,7 +519,7 @@ /** wrapper around assoc_find which does the lazy expiration logic */ item *do_item_get(const char *key, const size_t nkey, const uint32_t hv) { - mutex_lock(&cache_lock); + //mutex_lock(&cache_lock); item *it = assoc_find(key, nkey, hv); if (it != NULL) { refcount_incr(&it->refcount); @@ -505,7 +533,7 @@ it = NULL; } } - mutex_unlock(&cache_lock); + //mutex_unlock(&cache_lock); int was_found = 0; if (settings.verbose > 2) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/memcached-1.4.14/items.h new/memcached-1.4.15/items.h --- old/memcached-1.4.14/items.h 2012-01-09 05:36:49.000000000 +0100 +++ new/memcached-1.4.15/items.h 2012-09-03 20:23:23.000000000 +0200 @@ -2,7 +2,7 @@ uint64_t get_cas_id(void); /*@null@*/ -item *do_item_alloc(char *key, const size_t nkey, const int flags, const rel_time_t exptime, const int nbytes); +item *do_item_alloc(char *key, const size_t nkey, const int flags, const rel_time_t exptime, const int nbytes, const uint32_t cur_hv); void item_free(item *it); bool item_size_ok(const size_t nkey, const int flags, const int nbytes); @@ -16,6 +16,7 @@ /*@null@*/ char *do_item_cachedump(const unsigned int slabs_clsid, const unsigned int limit, unsigned int *bytes); void do_item_stats(ADD_STAT add_stats, void *c); +void do_item_stats_totals(ADD_STAT add_stats, void *c); /*@null@*/ void do_item_stats_sizes(ADD_STAT add_stats, void *c); void do_item_flush_expired(void); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/memcached-1.4.14/memcached.c new/memcached-1.4.15/memcached.c --- old/memcached-1.4.14/memcached.c 2012-07-30 22:26:47.000000000 +0200 +++ new/memcached-1.4.15/memcached.c 2012-09-03 20:23:23.000000000 +0200 @@ -2325,7 +2325,7 @@ flags = (int) strtol(ITEM_suffix(old_it), (char **) NULL, 10); - new_it = item_alloc(key, it->nkey, flags, old_it->exptime, it->nbytes + old_it->nbytes - 2 /* CRLF */); + new_it = do_item_alloc(key, it->nkey, flags, old_it->exptime, it->nbytes + old_it->nbytes - 2 /* CRLF */, hv); if (new_it == NULL) { /* SERVER_ERROR out of memory */ @@ -2585,8 +2585,6 @@ APPEND_STAT("hash_power_level", "%u", stats.hash_power_level); APPEND_STAT("hash_bytes", "%llu", (unsigned long long)stats.hash_bytes); APPEND_STAT("hash_is_expanding", "%u", stats.hash_is_expanding); - APPEND_STAT("expired_unfetched", "%llu", stats.expired_unfetched); - APPEND_STAT("evicted_unfetched", "%llu", stats.evicted_unfetched); if (settings.slab_reassign) { APPEND_STAT("slab_reassign_running", "%u", stats.slab_reassign_running); APPEND_STAT("slabs_moved", "%llu", stats.slabs_moved); @@ -3101,7 +3099,7 @@ res = strlen(buf); if (res + 2 > it->nbytes || it->refcount != 1) { /* need to realloc */ item *new_it; - new_it = item_alloc(ITEM_key(it), it->nkey, atoi(ITEM_suffix(it) + 1), it->exptime, res + 2 ); + new_it = do_item_alloc(ITEM_key(it), it->nkey, atoi(ITEM_suffix(it) + 1), it->exptime, res + 2, hv); if (new_it == 0) { do_item_remove(it); return EOM; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/memcached-1.4.14/memcached.h new/memcached-1.4.15/memcached.h --- old/memcached-1.4.14/memcached.h 2012-07-30 00:40:49.000000000 +0200 +++ new/memcached-1.4.15/memcached.h 2012-09-03 20:23:23.000000000 +0200 @@ -180,6 +180,11 @@ udp_transport }; +enum item_lock_types { + ITEM_LOCK_GRANULAR = 0, + ITEM_LOCK_GLOBAL +}; + #define IS_UDP(x) (x == udp_transport) #define NREAD_ADD 1 @@ -352,6 +357,7 @@ struct thread_stats stats; /* Stats generated by this thread */ struct conn_queue *new_conn_queue; /* queue of new connections to handle */ cache_t *suffix_cache; /* suffix cache */ + uint8_t item_lock_type; /* use fine-grained or global item lock */ } LIBEVENT_THREAD; typedef struct { @@ -527,12 +533,18 @@ void item_remove(item *it); int item_replace(item *it, item *new_it, const uint32_t hv); void item_stats(ADD_STAT add_stats, void *c); +void item_stats_totals(ADD_STAT add_stats, void *c); void item_stats_sizes(ADD_STAT add_stats, void *c); void item_unlink(item *it); void item_update(item *it); +void item_lock_global(void); +void item_unlock_global(void); void item_lock(uint32_t hv); +void *item_trylock(uint32_t hv); +void item_trylock_unlock(void *arg); void item_unlock(uint32_t hv); +void switch_item_lock_type(enum item_lock_types type); unsigned short refcount_incr(unsigned short *refcount); unsigned short refcount_decr(unsigned short *refcount); void STATS_LOCK(void); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/memcached-1.4.14/memcached.spec new/memcached-1.4.15/memcached.spec --- old/memcached-1.4.14/memcached.spec 2012-07-30 22:56:56.000000000 +0200 +++ new/memcached-1.4.15/memcached.spec 2012-09-04 02:12:59.000000000 +0200 @@ -1,12 +1,12 @@ Name: memcached -Version: 1.4.14 +Version: 1.4.15 Release: 1%{?dist} Summary: High Performance, Distributed Memory Object Cache Group: System Environment/Daemons License: BSD URL: http://www.danga.com/memcached/ -Source0: http://memcached.googlecode.com/files/%{name}-1.4.14.tar.gz +Source0: http://memcached.googlecode.com/files/%{name}-1.4.15.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRequires: libevent-devel @@ -23,7 +23,7 @@ web applications by alleviating database load. %prep -%setup -q -n %{name}-1.4.14 +%setup -q -n %{name}-1.4.15 %build diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/memcached-1.4.14/slabs.c new/memcached-1.4.15/slabs.c --- old/memcached-1.4.14/slabs.c 2012-07-30 06:09:13.000000000 +0200 +++ new/memcached-1.4.15/slabs.c 2012-09-03 20:23:23.000000000 +0200 @@ -293,11 +293,8 @@ APPEND_STAT("bytes", "%llu", (unsigned long long)stats.curr_bytes); APPEND_STAT("curr_items", "%u", stats.curr_items); APPEND_STAT("total_items", "%u", stats.total_items); - APPEND_STAT("evictions", "%llu", - (unsigned long long)stats.evictions); - APPEND_STAT("reclaimed", "%llu", - (unsigned long long)stats.reclaimed); STATS_UNLOCK(); + item_stats_totals(add_stats, c); } else if (nz_strcmp(nkey, stat_type, "items") == 0) { item_stats(add_stats, c); } else if (nz_strcmp(nkey, stat_type, "slabs") == 0) { @@ -498,7 +495,7 @@ } enum move_status { - MOVE_PASS=0, MOVE_DONE, MOVE_BUSY + MOVE_PASS=0, MOVE_DONE, MOVE_BUSY, MOVE_LOCKED }; /* refcount == 0 is safe since nobody can incr while cache_lock is held. @@ -522,36 +519,43 @@ item *it = slab_rebal.slab_pos; status = MOVE_PASS; if (it->slabs_clsid != 255) { - refcount = refcount_incr(&it->refcount); - if (refcount == 1) { /* item is unlinked, unused */ - if (it->it_flags & ITEM_SLABBED) { - /* remove from slab freelist */ - if (s_cls->slots == it) { - s_cls->slots = it->next; + void *hold_lock = NULL; + uint32_t hv = hash(ITEM_key(it), it->nkey, 0); + if ((hold_lock = item_trylock(hv)) == NULL) { + status = MOVE_LOCKED; + } else { + refcount = refcount_incr(&it->refcount); + if (refcount == 1) { /* item is unlinked, unused */ + if (it->it_flags & ITEM_SLABBED) { + /* remove from slab freelist */ + if (s_cls->slots == it) { + s_cls->slots = it->next; + } + if (it->next) it->next->prev = it->prev; + if (it->prev) it->prev->next = it->next; + s_cls->sl_curr--; + status = MOVE_DONE; + } else { + status = MOVE_BUSY; + } + } else if (refcount == 2) { /* item is linked but not busy */ + if ((it->it_flags & ITEM_LINKED) != 0) { + do_item_unlink_nolock(it, hash(ITEM_key(it), it->nkey, 0)); + status = MOVE_DONE; + } else { + /* refcount == 1 + !ITEM_LINKED means the item is being + * uploaded to, or was just unlinked but hasn't been freed + * yet. Let it bleed off on its own and try again later */ + status = MOVE_BUSY; } - if (it->next) it->next->prev = it->prev; - if (it->prev) it->prev->next = it->next; - s_cls->sl_curr--; - status = MOVE_DONE; - } else { - status = MOVE_BUSY; - } - } else if (refcount == 2) { /* item is linked but not busy */ - if ((it->it_flags & ITEM_LINKED) != 0) { - do_item_unlink_nolock(it, hash(ITEM_key(it), it->nkey, 0)); - status = MOVE_DONE; } else { - /* refcount == 1 + !ITEM_LINKED means the item is being - * uploaded to, or was just unlinked but hasn't been freed - * yet. Let it bleed off on its own and try again later */ + if (settings.verbose > 2) { + fprintf(stderr, "Slab reassign hit a busy item: refcount: %d (%d -> %d)\n", + it->refcount, slab_rebal.s_clsid, slab_rebal.d_clsid); + } status = MOVE_BUSY; } - } else { - if (settings.verbose > 2) { - fprintf(stderr, "Slab reassign hit a busy item: refcount: %d (%d -> %d)\n", - it->refcount, slab_rebal.s_clsid, slab_rebal.d_clsid); - } - status = MOVE_BUSY; + item_trylock_unlock(hold_lock); } } @@ -562,9 +566,10 @@ it->slabs_clsid = 255; break; case MOVE_BUSY: + refcount_decr(&it->refcount); + case MOVE_LOCKED: slab_rebal.busy_items++; was_busy++; - refcount_decr(&it->refcount); break; case MOVE_PASS: break; @@ -731,6 +736,8 @@ */ static void *slab_rebalance_thread(void *arg) { int was_busy = 0; + /* So we first pass into cond_wait with the mutex held */ + mutex_lock(&slabs_rebalance_lock); while (do_run_slab_rebalance_thread) { if (slab_rebalance_signal == 1) { @@ -819,6 +826,15 @@ return ret; } +/* If we hold this lock, rebalancer can't wake up or move */ +void slabs_rebalancer_pause(void) { + pthread_mutex_lock(&slabs_rebalance_lock); +} + +void slabs_rebalancer_resume(void) { + pthread_mutex_unlock(&slabs_rebalance_lock); +} + static pthread_t maintenance_tid; static pthread_t rebalance_tid; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/memcached-1.4.14/slabs.h new/memcached-1.4.15/slabs.h --- old/memcached-1.4.14/slabs.h 2012-07-29 10:30:59.000000000 +0200 +++ new/memcached-1.4.15/slabs.h 2012-09-03 20:23:23.000000000 +0200 @@ -43,4 +43,7 @@ enum reassign_result_type slabs_reassign(int src, int dst); +void slabs_rebalancer_pause(void); +void slabs_rebalancer_resume(void); + #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/memcached-1.4.14/thread.c new/memcached-1.4.15/thread.c --- old/memcached-1.4.14/thread.c 2012-07-30 22:28:21.000000000 +0200 +++ new/memcached-1.4.15/thread.c 2012-09-03 20:23:23.000000000 +0200 @@ -57,8 +57,12 @@ static pthread_mutex_t *item_locks; /* size of the item lock hash table */ static uint32_t item_lock_count; -/* size - 1 for lookup masking */ -static uint32_t item_lock_mask; +#define hashsize(n) ((unsigned long int)1<<(n)) +#define hashmask(n) (hashsize(n)-1) +/* this lock is temporarily engaged during a hash table expansion */ +static pthread_mutex_t item_global_lock; +/* thread-specific variable for deeply finding the item lock type */ +static pthread_key_t item_lock_type_key; static LIBEVENT_DISPATCHER_THREAD dispatcher_thread; @@ -108,12 +112,92 @@ #endif } +/* Convenience functions for calling *only* when in ITEM_LOCK_GLOBAL mode */ +void item_lock_global(void) { + mutex_lock(&item_global_lock); +} + +void item_unlock_global(void) { + mutex_unlock(&item_global_lock); +} + void item_lock(uint32_t hv) { - mutex_lock(&item_locks[hv & item_lock_mask]); + uint8_t *lock_type = pthread_getspecific(item_lock_type_key); + if (likely(*lock_type == ITEM_LOCK_GRANULAR)) { + mutex_lock(&item_locks[(hv & hashmask(hashpower)) % item_lock_count]); + } else { + mutex_lock(&item_global_lock); + } +} + +/* Special case. When ITEM_LOCK_GLOBAL mode is enabled, this should become a + * no-op, as it's only called from within the item lock if necessary. + * However, we can't mix a no-op and threads which are still synchronizing to + * GLOBAL. So instead we just always try to lock. When in GLOBAL mode this + * turns into an effective no-op. Threads re-synchronize after the power level + * switch so it should stay safe. + */ +void *item_trylock(uint32_t hv) { + pthread_mutex_t *lock = &item_locks[(hv & hashmask(hashpower)) % item_lock_count]; + if (pthread_mutex_trylock(lock) == 0) { + return lock; + } + return NULL; +} + +void item_trylock_unlock(void *lock) { + mutex_unlock((pthread_mutex_t *) lock); } void item_unlock(uint32_t hv) { - mutex_unlock(&item_locks[hv & item_lock_mask]); + uint8_t *lock_type = pthread_getspecific(item_lock_type_key); + if (likely(*lock_type == ITEM_LOCK_GRANULAR)) { + mutex_unlock(&item_locks[(hv & hashmask(hashpower)) % item_lock_count]); + } else { + mutex_unlock(&item_global_lock); + } +} + +static void wait_for_thread_registration(int nthreads) { + while (init_count < nthreads) { + pthread_cond_wait(&init_cond, &init_lock); + } +} + +static void register_thread_initialized(void) { + pthread_mutex_lock(&init_lock); + init_count++; + pthread_cond_signal(&init_cond); + pthread_mutex_unlock(&init_lock); +} + +void switch_item_lock_type(enum item_lock_types type) { + char buf[1]; + int i; + + switch (type) { + case ITEM_LOCK_GRANULAR: + buf[0] = 'l'; + break; + case ITEM_LOCK_GLOBAL: + buf[0] = 'g'; + break; + default: + fprintf(stderr, "Unknown lock type: %d\n", type); + assert(1 == 0); + break; + } + + pthread_mutex_lock(&init_lock); + init_count = 0; + for (i = 0; i < settings.num_threads; i++) { + if (write(threads[i].notify_send_fd, buf, 1) != 1) { + perror("Failed writing to notify pipe"); + /* TODO: This is a fatal problem. Can it ever happen temporarily? */ + } + } + wait_for_thread_registration(settings.num_threads); + pthread_mutex_unlock(&init_lock); } /* @@ -278,7 +362,6 @@ } } - /* * Worker thread: main event loop */ @@ -289,10 +372,14 @@ * all threads have finished initializing. */ - pthread_mutex_lock(&init_lock); - init_count++; - pthread_cond_signal(&init_cond); - pthread_mutex_unlock(&init_lock); + /* set an indexable thread-specific memory item for the lock type. + * this could be unnecessary if we pass the conn *c struct through + * all item_lock calls... + */ + me->item_lock_type = ITEM_LOCK_GRANULAR; + pthread_setspecific(item_lock_type_key, &me->item_lock_type); + + register_thread_initialized(); event_base_loop(me->base, 0); return NULL; @@ -312,6 +399,8 @@ if (settings.verbose > 0) fprintf(stderr, "Can't read from libevent pipe\n"); + switch (buf[0]) { + case 'c': item = cq_pop(me->new_conn_queue); if (NULL != item) { @@ -333,6 +422,17 @@ } cqi_free(item); } + break; + /* we were told to flip the lock type and report in */ + case 'l': + me->item_lock_type = ITEM_LOCK_GRANULAR; + register_thread_initialized(); + break; + case 'g': + me->item_lock_type = ITEM_LOCK_GLOBAL; + register_thread_initialized(); + break; + } } /* Which thread we assigned a connection to most recently. */ @@ -346,6 +446,7 @@ void dispatch_conn_new(int sfd, enum conn_states init_state, int event_flags, int read_buffer_size, enum network_transport transport) { CQ_ITEM *item = cqi_new(); + char buf[1]; int tid = (last_thread + 1) % settings.num_threads; LIBEVENT_THREAD *thread = threads + tid; @@ -361,7 +462,8 @@ cq_push(thread->new_conn_queue, item); MEMCACHED_CONN_DISPATCH(sfd, thread->thread_id); - if (write(thread->notify_send_fd, "", 1) != 1) { + buf[0] = 'c'; + if (write(thread->notify_send_fd, buf, 1) != 1) { perror("Writing to thread notify pipe"); } } @@ -381,7 +483,7 @@ item *item_alloc(char *key, size_t nkey, int flags, rel_time_t exptime, int nbytes) { item *it; /* do_item_alloc handles its own locks */ - it = do_item_alloc(key, nkey, flags, exptime, nbytes); + it = do_item_alloc(key, nkey, flags, exptime, nbytes, 0); return it; } @@ -529,6 +631,12 @@ mutex_unlock(&cache_lock); } +void item_stats_totals(ADD_STAT add_stats, void *c) { + mutex_lock(&cache_lock); + do_item_stats_totals(add_stats, c); + mutex_unlock(&cache_lock); +} + /* * Dumps a list of objects of each size in 32-byte increments */ @@ -686,8 +794,7 @@ power = 13; } - item_lock_count = ((unsigned long int)1 << (power)); - item_lock_mask = item_lock_count - 1; + item_lock_count = hashsize(power); item_locks = calloc(item_lock_count, sizeof(pthread_mutex_t)); if (! item_locks) { @@ -697,6 +804,8 @@ for (i = 0; i < item_lock_count; i++) { pthread_mutex_init(&item_locks[i], NULL); } + pthread_key_create(&item_lock_type_key, NULL); + pthread_mutex_init(&item_global_lock, NULL); threads = calloc(nthreads, sizeof(LIBEVENT_THREAD)); if (! threads) { @@ -729,9 +838,7 @@ /* Wait for all the threads to set themselves up before returning. */ pthread_mutex_lock(&init_lock); - while (init_count < nthreads) { - pthread_cond_wait(&init_cond, &init_lock); - } + wait_for_thread_registration(nthreads); pthread_mutex_unlock(&init_lock); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/memcached-1.4.14/version.m4 new/memcached-1.4.15/version.m4 --- old/memcached-1.4.14/version.m4 2012-07-30 22:56:56.000000000 +0200 +++ new/memcached-1.4.15/version.m4 2012-09-04 02:12:59.000000000 +0200 @@ -1 +1 @@ -m4_define([VERSION_NUMBER], [1.4.14]) +m4_define([VERSION_NUMBER], [1.4.15]) ++++++ memcached-1.4.5.dif ++++++ --- /var/tmp/diff_new_pack.Eg19fT/_old 2012-11-12 07:04:20.000000000 +0100 +++ /var/tmp/diff_new_pack.Eg19fT/_new 2012-11-12 07:04:20.000000000 +0100 @@ -1,6 +1,8 @@ ---- memcached.c.orig 2012-04-02 20:24:27.715193171 -0400 -+++ memcached.c 2012-04-02 20:27:08.442183805 -0400 -@@ -2498,15 +2498,19 @@ +Index: memcached.c +=================================================================== +--- memcached.c.orig ++++ memcached.c +@@ -2498,15 +2498,19 @@ void append_stat(const char *name, ADD_S inline static void process_stats_detail(conn *c, const char *command) { assert(c != NULL); ++++++ memcached-autofoo.patch ++++++ --- /var/tmp/diff_new_pack.Eg19fT/_old 2012-11-12 07:04:20.000000000 +0100 +++ /var/tmp/diff_new_pack.Eg19fT/_new 2012-11-12 07:04:20.000000000 +0100 @@ -1,6 +1,8 @@ +Index: configure.ac +=================================================================== --- configure.ac.orig +++ configure.ac -@@ -1,59 +1,15 @@ +@@ -1,61 +1,15 @@ -AC_PREREQ(2.52) +AC_PREREQ([2.60]) m4_include([version.m4]) @@ -55,11 +57,13 @@ -]) - -DETECT_SUNCC([CFLAGS="-mt $CFLAGS"], []) +-AS_IF([test "$ICC" = "yes" -o "$GCC" = "yes"], +- [CFLAGS="$CFLAGS -pthread"]) - -if test "$ICC" = "no"; then - AC_PROG_CC_C99 -fi -+AM_INIT_AUTOMAKE([foreign -Wall -Wno-portability tar-pax no-dist-gzip dist-xz subdir-objects]) ++AM_INIT_AUTOMAKE([foreign -Wall -Wno-portability tar-pax subdir-objects]) +AC_CONFIG_HEADERS([config.h]) +AC_PROG_CC_STDC @@ -68,7 +72,7 @@ AM_PROG_CC_C_O AC_PROG_INSTALL -@@ -76,14 +32,11 @@ AC_DEFUN([AC_C_DETECT_SASL_CB_GETCONF], +@@ -78,14 +32,11 @@ AC_DEFUN([AC_C_DETECT_SASL_CB_GETCONF], [ AC_CACHE_CHECK([for SASL_CB_GETCONF], [ac_cv_c_sasl_cb_getconf], @@ -86,7 +90,7 @@ ]) AS_IF([test "$ac_cv_c_sasl_cb_getconf" = "yes"], [AC_DEFINE([HAVE_SASL_CB_GETCONF], 1, -@@ -170,23 +123,6 @@ fi +@@ -168,23 +119,6 @@ fi AC_SUBST(PROFILER_FLAGS) @@ -110,7 +114,7 @@ # Issue 213: Search for clock_gettime to help people linking # with a static version of libevent AC_SEARCH_LIBS(clock_gettime, rt) -@@ -195,91 +131,7 @@ AC_SEARCH_LIBS(clock_gettime, rt) +@@ -193,91 +127,7 @@ AC_SEARCH_LIBS(clock_gettime, rt) AC_SEARCH_LIBS(socket, socket) AC_SEARCH_LIBS(gethostbyname, nsl) @@ -203,7 +207,7 @@ dnl ---------------------------------------------------------------------------- -@@ -308,14 +160,14 @@ dnl ************************************ +@@ -306,14 +156,14 @@ dnl ************************************ AC_DEFUN([AC_HAVE_SASL_CALLBACK_FT], [AC_CACHE_CHECK(for sasl_callback_ft, ac_cv_has_sasl_callback_ft, [ @@ -221,7 +225,7 @@ ac_cv_has_sasl_callback_ft=yes ],[ ac_cv_has_sasl_callback_ft=no -@@ -337,18 +189,15 @@ AC_DEFUN([AC_C_DETECT_UINT64_SUPPORT], +@@ -335,18 +185,15 @@ AC_DEFUN([AC_C_DETECT_UINT64_SUPPORT], [ AC_CACHE_CHECK([for print macros for integers (C99 section 7.8.1)], [ac_cv_c_uint64_support], @@ -243,7 +247,7 @@ ]) ]) -@@ -367,12 +216,12 @@ dnl Check if the type socklen_t is defin +@@ -365,12 +212,12 @@ dnl Check if the type socklen_t is defin AC_DEFUN([AC_C_SOCKLEN_T], [AC_CACHE_CHECK(for socklen_t, ac_cv_c_socklen_t, [ @@ -259,7 +263,7 @@ ac_cv_c_socklen_t=yes ],[ ac_cv_c_socklen_t=no -@@ -411,35 +260,6 @@ fi +@@ -409,35 +256,6 @@ fi AC_C_ENDIAN @@ -295,7 +299,7 @@ AC_CHECK_FUNCS(mlockall) AC_CHECK_FUNCS(getpagesizes) -@@ -486,13 +306,13 @@ dnl These were added in 4.1.2, but 32bit +@@ -484,13 +302,13 @@ dnl These were added in 4.1.2, but 32bit dnl lacks testable defines. have_gcc_atomics=no AC_MSG_CHECKING(for GCC atomics) @@ -312,7 +316,7 @@ AC_MSG_RESULT($have_gcc_atomics) dnl Check for the requirements for running memcached with less privileges -@@ -529,29 +349,5 @@ AM_CONDITIONAL([BUILD_SPECIFICATIONS], +@@ -527,29 +345,5 @@ AM_CONDITIONAL([BUILD_SPECIFICATIONS], [test "x$enable_docs" != "xno" -a "x$XML2RFC" != "xno" -a "x$XSLTPROC" != "xno"]) @@ -342,6 +346,8 @@ - AC_CONFIG_FILES(Makefile doc/Makefile) AC_OUTPUT +Index: Makefile.am +=================================================================== --- Makefile.am.orig +++ Makefile.am @@ -1,3 +1,6 @@ ++++++ memcached-use-endian_h.patch ++++++ --- /var/tmp/diff_new_pack.Eg19fT/_old 2012-11-12 07:04:20.000000000 +0100 +++ /var/tmp/diff_new_pack.Eg19fT/_new 2012-11-12 07:04:20.000000000 +0100 @@ -1,3 +1,5 @@ +Index: util.c +=================================================================== --- util.c.orig +++ util.c @@ -115,30 +115,3 @@ void vperror(const char *fmt, ...) { @@ -31,6 +33,8 @@ -} -#endif - +Index: util.h +=================================================================== --- util.h.orig +++ util.h @@ -7,15 +7,16 @@ -- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
