Commit 0042a2d7 authored by antirez's avatar antirez
Browse files

jemalloc support backported in 2.4 using part of the Pieter Noordhuis and...

jemalloc support backported in 2.4 using part of the Pieter Noordhuis and Didier Spezia original implementations
parent 0811e89c
......@@ -12,6 +12,7 @@ clean:
cd src && $(MAKE) $@
cd deps/hiredis && $(MAKE) $@
cd deps/linenoise && $(MAKE) $@
cd deps/jemalloc && $(MAKE) distclean
$(TARGETS):
cd src && $(MAKE) $@
......
......@@ -24,23 +24,6 @@ After building Redis is a good idea to test it, using:
% make test
Buliding using tcmalloc
-----------------------
tcmalloc is a fast and space efficient implementation (for little objects)
of malloc(). Compiling Redis with it can improve performances and memeory
usage. You can read more about it here:
http://goog-perftools.sourceforge.net/doc/tcmalloc.html
In order to compile Redis with tcmalloc support install tcmalloc on your system
and then use:
% make USE_TCMALLOC=yes
Note that you can pass any other target to make, as long as you append
USE_TCMALLOC=yes at the end.
Running Redis
-------------
......
......@@ -5,35 +5,42 @@
release_hdr := $(shell sh -c './mkreleasehdr.sh')
uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
OPTIMIZATION?=-O2
ifeq ($(uname_S),Linux)
ifneq ($(FORCE_LIBC_MALLOC),yes)
USE_JEMALLOC=yes
endif
endif
ifeq ($(uname_S),SunOS)
CFLAGS?= -std=c99 -pedantic $(OPTIMIZATION) -Wall -W -D__EXTENSIONS__ -D_XPG6
CCLINK?= -ldl -lnsl -lsocket -lm -lpthread
DEBUG?= -g -ggdb
CFLAGS?=-std=c99 -pedantic $(OPTIMIZATION) -Wall -W -D__EXTENSIONS__ -D_XPG6
CCLINK?=-ldl -lnsl -lsocket -lm -lpthread
DEBUG?=-g -ggdb
else
CFLAGS?= -std=c99 -pedantic $(OPTIMIZATION) -Wall -W $(ARCH) $(PROF)
CCLINK?= -lm -pthread
DEBUG?= -g -rdynamic -ggdb
CFLAGS?=-std=c99 -pedantic $(OPTIMIZATION) -Wall -W $(ARCH) $(PROF)
CCLINK?=-lm -pthread
DEBUG?=-g -rdynamic -ggdb
endif
ifeq ($(USE_TCMALLOC),yes)
ALLOC_DEP=
ALLOC_LINK=-ltcmalloc
ALLOC_FLAGS=-DUSE_TCMALLOC
endif
ifeq ($(USE_TCMALLOC_MINIMAL),yes)
ALLOC_DEP=
ALLOC_LINK=-ltcmalloc_minimal
ALLOC_FLAGS=-DUSE_TCMALLOC
endif
ifeq ($(USE_JEMALLOC),yes)
ALLOC_LINK=-ljemalloc
ALLOC_FLAGS=-DUSE_JEMALLOC
ALLOC_DEP=../deps/jemalloc/lib/libjemalloc.a
ALLOC_LINK=$(ALLOC_DEP)
ALLOC_FLAGS=-DUSE_JEMALLOC -I../deps/jemalloc/include
endif
CCLINK+= $(ALLOC_LINK)
CFLAGS+= $(ALLOC_FLAGS)
CCOPT= $(CFLAGS) $(CCLINK) $(ARCH) $(PROF)
CCOPT= $(CFLAGS) $(ARCH) $(PROF)
PREFIX= /usr/local
INSTALL_BIN= $(PREFIX)/bin
......@@ -58,7 +65,7 @@ all: redis-benchmark redis-cli redis-check-dump redis-check-aof redis-server
# Deps (use make dep to generate this)
adlist.o: adlist.c adlist.h zmalloc.h
ae.o: ae.c ae.h zmalloc.h config.h ae_kqueue.c
ae.o: ae.c ae.h config.h zmalloc.h ae_epoll.c ae_kqueue.c ae_select.c
ae_epoll.o: ae_epoll.c
ae_kqueue.o: ae_kqueue.c
ae_select.o: ae_select.c
......@@ -72,8 +79,8 @@ db.o: db.c redis.h fmacros.h config.h ae.h sds.h dict.h adlist.h \
debug.o: debug.c redis.h fmacros.h config.h ae.h sds.h dict.h adlist.h \
zmalloc.h anet.h zipmap.h ziplist.h intset.h version.h sha1.h
dict.o: dict.c fmacros.h dict.h zmalloc.h
endian.o: endian.c
intset.o: intset.c intset.h zmalloc.h
endian.o: endian.c
lzf_c.o: lzf_c.c lzfP.h
lzf_d.o: lzf_d.c lzfP.h
multi.o: multi.c redis.h fmacros.h config.h ae.h sds.h dict.h adlist.h \
......@@ -87,12 +94,12 @@ pubsub.o: pubsub.c redis.h fmacros.h config.h ae.h sds.h dict.h adlist.h \
zmalloc.h anet.h zipmap.h ziplist.h intset.h version.h
rdb.o: rdb.c redis.h fmacros.h config.h ae.h sds.h dict.h adlist.h \
zmalloc.h anet.h zipmap.h ziplist.h intset.h version.h lzf.h
redis-benchmark.o: redis-benchmark.c fmacros.h ae.h \
../deps/hiredis/hiredis.h sds.h adlist.h zmalloc.h
redis-benchmark.o: redis-benchmark.c fmacros.h ae.c ae.h ae_epoll.c \
ae_kqueue.c ae_select.c config.h zmalloc.h ae_kqueue.c adlist.c adlist.h \
sds.c sds.h
redis-check-aof.o: redis-check-aof.c fmacros.h config.h
redis-check-dump.o: redis-check-dump.c lzf.h
redis-cli.o: redis-cli.c fmacros.h version.h ../deps/hiredis/hiredis.h \
sds.h zmalloc.h ../deps/linenoise/linenoise.h help.h
redis-cli.o: redis-cli.c fmacros.h version.h help.h sds.c sds.h
redis.o: redis.c redis.h fmacros.h config.h ae.h sds.h dict.h adlist.h \
zmalloc.h anet.h zipmap.h ziplist.h intset.h version.h
release.o: release.c release.h
......@@ -114,47 +121,61 @@ t_string.o: t_string.c redis.h fmacros.h config.h ae.h sds.h dict.h \
adlist.h zmalloc.h anet.h zipmap.h ziplist.h intset.h version.h
t_zset.o: t_zset.c redis.h fmacros.h config.h ae.h sds.h dict.h adlist.h \
zmalloc.h anet.h zipmap.h ziplist.h intset.h version.h
util.o: util.c util.h
util.o: util.c redis.h fmacros.h config.h ae.h sds.h dict.h adlist.h \
zmalloc.h anet.h zipmap.h ziplist.h intset.h version.h
vm.o: vm.c redis.h fmacros.h config.h ae.h sds.h dict.h adlist.h \
zmalloc.h anet.h zipmap.h ziplist.h intset.h version.h
ziplist.o: ziplist.c zmalloc.h ziplist.h
zipmap.o: zipmap.c zmalloc.h endian.h
zipmap.o: zipmap.c zmalloc.h
zmalloc.o: zmalloc.c config.h zmalloc.h
.PHONY: dependencies
dependencies:
cd ../deps/hiredis && $(MAKE) static ARCH="$(ARCH)"
cd ../deps/linenoise && $(MAKE) ARCH="$(ARCH)"
redis-server: $(OBJ)
$(CC) -o $(PRGNAME) $(CCOPT) $(DEBUG) $(OBJ)
redis-benchmark: dependencies $(BENCHOBJ)
cd ../deps/hiredis && $(MAKE) static
$(CC) -o $(BENCHPRGNAME) $(CCOPT) $(DEBUG) $(BENCHOBJ) ../deps/hiredis/libhiredis.a
../deps/jemalloc/lib/libjemalloc.a:
cd ../deps/jemalloc && ./configure --with-jemalloc-prefix=je_ --enable-cc-silence && $(MAKE) lib/libjemalloc.a
redis-benchmark.o:
$(CC) -c $(CFLAGS) -I../deps/hiredis $(DEBUG) $(COMPILE_TIME) $<
redis-cli: dependencies $(CLIOBJ)
$(CC) -o $(CLIPRGNAME) $(CCOPT) $(DEBUG) $(CLIOBJ) ../deps/hiredis/libhiredis.a ../deps/linenoise/linenoise.o
redis-benchmark: dependencies $(BENCHOBJ)
cd ../deps/hiredis && $(MAKE) static
$(CC) -o $(BENCHPRGNAME) $(CCOPT) $(DEBUG) $(BENCHOBJ) ../deps/hiredis/libhiredis.a $(CCLINK) $(ALLOC_LINK)
redis-cli.o:
$(CC) -c $(CFLAGS) -I../deps/hiredis -I../deps/linenoise $(DEBUG) $(COMPILE_TIME) $<
redis-cli: dependencies $(CLIOBJ)
$(CC) -o $(CLIPRGNAME) $(CCOPT) $(DEBUG) $(CLIOBJ) ../deps/hiredis/libhiredis.a ../deps/linenoise/linenoise.o $(CCLINK) $(ALLOC_LINK)
redis-check-dump.o:
$(CC) -c $(CFLAGS) $(DEBUG) $(COMPILE_TIME) $<
redis-check-dump: $(CHECKDUMPOBJ)
$(CC) -o $(CHECKDUMPPRGNAME) $(CCOPT) $(DEBUG) $(CHECKDUMPOBJ)
$(CC) -o $(CHECKDUMPPRGNAME) $(CCOPT) $(DEBUG) $(CHECKDUMPOBJ) $(CCLINK)
redis-check-aof.o:
$(CC) -c $(CFLAGS) $(DEBUG) $(COMPILE_TIME) $<
redis-check-aof: $(CHECKAOFOBJ)
$(CC) -o $(CHECKAOFPRGNAME) $(CCOPT) $(DEBUG) $(CHECKAOFOBJ)
$(CC) -o $(CHECKAOFPRGNAME) $(CCOPT) $(DEBUG) $(CHECKAOFOBJ) $(CCLINK)
.c.o:
$(CC) -c $(CFLAGS) $(DEBUG) $(COMPILE_TIME) $<
redis-server: $(OBJ)
$(CC) -o $(PRGNAME) $(CCOPT) $(DEBUG) $(OBJ) $(CCLINK) $(ALLOC_LINK)
# Because the jemalloc.h header is generated as a part of the jemalloc build
# process, building it should complete before building any other object.
%.o: %.c $(ALLOC_DEP)
$(CC) -c $(CFLAGS) $(ALLOC_FLAGS) $(DEBUG) $(COMPILE_TIME) $<
clean:
rm -rf $(PRGNAME) $(BENCHPRGNAME) $(CLIPRGNAME) $(CHECKDUMPPRGNAME) $(CHECKAOFPRGNAME) *.o *.gcda *.gcno *.gcov
dep:
$(CC) -I../deps/hiredis -I../deps/linenoise -MM *.c
$(CC) -MM *.c
test: redis-server
(cd ..; tclsh8.5 tests/test_helper.tcl --tags "${TAGS}" --file "${FILE}")
......
......@@ -1232,7 +1232,7 @@ sds genRedisInfoString(void) {
server.stat_peak_memory,
peak_hmem,
zmalloc_get_fragmentation_ratio(),
REDIS_MALLOC,
ZMALLOC_LIB,
server.loading,
server.appendonly,
server.dirty,
......
......@@ -51,6 +51,11 @@
#define calloc(count,size) tc_calloc(count,size)
#define realloc(ptr,size) tc_realloc(ptr,size)
#define free(ptr) tc_free(ptr)
#elif defined(USE_JEMALLOC)
#define malloc(size) je_malloc(size)
#define calloc(count,size) je_calloc(count,size)
#define realloc(ptr,size) je_realloc(ptr,size)
#define free(ptr) je_free(ptr)
#endif
#define update_zmalloc_stat_alloc(__n,__size) do { \
......@@ -98,7 +103,7 @@ void *zmalloc(size_t size) {
if (!ptr) zmalloc_oom(size);
#ifdef HAVE_MALLOC_SIZE
update_zmalloc_stat_alloc(redis_malloc_size(ptr),size);
update_zmalloc_stat_alloc(zmalloc_size(ptr),size);
return ptr;
#else
*((size_t*)ptr) = size;
......@@ -112,7 +117,7 @@ void *zcalloc(size_t size) {
if (!ptr) zmalloc_oom(size);
#ifdef HAVE_MALLOC_SIZE
update_zmalloc_stat_alloc(redis_malloc_size(ptr),size);
update_zmalloc_stat_alloc(zmalloc_size(ptr),size);
return ptr;
#else
*((size_t*)ptr) = size;
......@@ -130,12 +135,12 @@ void *zrealloc(void *ptr, size_t size) {
if (ptr == NULL) return zmalloc(size);
#ifdef HAVE_MALLOC_SIZE
oldsize = redis_malloc_size(ptr);
oldsize = zmalloc_size(ptr);
newptr = realloc(ptr,size);
if (!newptr) zmalloc_oom(size);
update_zmalloc_stat_free(oldsize);
update_zmalloc_stat_alloc(redis_malloc_size(newptr),size);
update_zmalloc_stat_alloc(zmalloc_size(newptr),size);
return newptr;
#else
realptr = (char*)ptr-PREFIX_SIZE;
......@@ -158,7 +163,7 @@ void zfree(void *ptr) {
if (ptr == NULL) return;
#ifdef HAVE_MALLOC_SIZE
update_zmalloc_stat_free(redis_malloc_size(ptr));
update_zmalloc_stat_free(zmalloc_size(ptr));
free(ptr);
#else
realptr = (char*)ptr-PREFIX_SIZE;
......
......@@ -28,8 +28,43 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _ZMALLOC_H
#define _ZMALLOC_H
#ifndef __ZMALLOC_H
#define __ZMALLOC_H
/* Double expansion needed for stringification of macro values. */
#define __xstr(s) __str(s)
#define __str(s) #s
#if defined(USE_TCMALLOC)
#define ZMALLOC_LIB ("tcmalloc-" __xstr(TC_VERSION_MAJOR) "." __xstr(TC_VERSION_MINOR))
#include <google/tcmalloc.h>
#if TC_VERSION_MAJOR >= 1 && TC_VERSION_MINOR >= 6
#define HAVE_MALLOC_SIZE 1
#define zmalloc_size(p) tc_malloc_size(p)
#else
#error "Newer version of tcmalloc required"
#endif
#elif defined(USE_JEMALLOC)
#define ZMALLOC_LIB ("jemalloc-" __xstr(JEMALLOC_VERSION_MAJOR) "." __xstr(JEMALLOC_VERSION_MINOR) "." __xstr(JEMALLOC_VERSION_BUGFIX))
#define JEMALLOC_MANGLE
#include <jemalloc/jemalloc.h>
#if JEMALLOC_VERSION_MAJOR >= 2 && JEMALLOC_VERSION_MINOR >= 1
#define HAVE_MALLOC_SIZE 1
#define zmalloc_size(p) JEMALLOC_P(malloc_usable_size)(p)
#else
#error "Newer version of jemalloc required"
#endif
#elif defined(__APPLE__)
#include <malloc/malloc.h>
#define HAVE_MALLOC_SIZE 1
#define zmalloc_size(p) malloc_size(p)
#endif
#ifndef ZMALLOC_LIB
#define ZMALLOC_LIB "libc"
#endif
void *zmalloc(size_t size);
void *zcalloc(size_t size);
......@@ -44,4 +79,4 @@ size_t zmalloc_allocations_for_size(size_t size);
#define ZMALLOC_MAX_ALLOC_STAT 256
#endif /* _ZMALLOC_H */
#endif /* __ZMALLOC_H */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment