├── .gitignore ├── 00-RELEASENOTES ├── BUGS ├── CONTRIBUTING ├── COPYING ├── INSTALL ├── Makefile ├── README ├── TODO ├── deps ├── hiredis │ ├── .gitignore │ ├── COPYING │ ├── Makefile │ ├── README.md │ ├── TODO │ ├── adapters │ │ ├── ae.h │ │ ├── libev.h │ │ └── libevent.h │ ├── async.c │ ├── async.h │ ├── dict.c │ ├── dict.h │ ├── example-ae.c │ ├── example-libev.c │ ├── example-libevent.c │ ├── example.c │ ├── fmacros.h │ ├── hiredis.c │ ├── hiredis.h │ ├── net.c │ ├── net.h │ ├── sds.c │ ├── sds.h │ ├── test.c │ └── util.h ├── jemalloc │ ├── .gitignore │ ├── COPYING │ ├── ChangeLog │ ├── INSTALL │ ├── Makefile.in │ ├── README │ ├── VERSION │ ├── autogen.sh │ ├── bin │ │ └── pprof │ ├── config.guess │ ├── config.stamp.in │ ├── config.sub │ ├── configure │ ├── configure.ac │ ├── doc │ │ ├── html.xsl.in │ │ ├── jemalloc.3 │ │ ├── jemalloc.html │ │ ├── jemalloc.xml.in │ │ ├── manpages.xsl.in │ │ └── stylesheet.xsl │ ├── include │ │ └── jemalloc │ │ │ ├── internal │ │ │ ├── arena.h │ │ │ ├── atomic.h │ │ │ ├── base.h │ │ │ ├── bitmap.h │ │ │ ├── chunk.h │ │ │ ├── chunk_dss.h │ │ │ ├── chunk_mmap.h │ │ │ ├── chunk_swap.h │ │ │ ├── ckh.h │ │ │ ├── ctl.h │ │ │ ├── extent.h │ │ │ ├── hash.h │ │ │ ├── huge.h │ │ │ ├── jemalloc_internal.h.in │ │ │ ├── mb.h │ │ │ ├── mutex.h │ │ │ ├── private_namespace.h │ │ │ ├── prof.h │ │ │ ├── ql.h │ │ │ ├── qr.h │ │ │ ├── rb.h │ │ │ ├── rtree.h │ │ │ ├── stats.h │ │ │ ├── tcache.h │ │ │ └── zone.h │ │ │ ├── jemalloc.h.in │ │ │ └── jemalloc_defs.h.in │ ├── install-sh │ ├── src │ │ ├── arena.c │ │ ├── atomic.c │ │ ├── base.c │ │ ├── bitmap.c │ │ ├── chunk.c │ │ ├── chunk_dss.c │ │ ├── chunk_mmap.c │ │ ├── chunk_swap.c │ │ ├── ckh.c │ │ ├── ctl.c │ │ ├── extent.c │ │ ├── hash.c │ │ ├── huge.c │ │ ├── jemalloc.c │ │ ├── mb.c │ │ ├── mutex.c │ │ ├── prof.c │ │ ├── rtree.c │ │ ├── stats.c │ │ ├── tcache.c │ │ └── zone.c │ └── test │ │ ├── allocated.c │ │ ├── allocated.exp │ │ ├── allocm.c │ │ ├── allocm.exp │ │ ├── bitmap.c │ │ ├── bitmap.exp │ │ ├── jemalloc_test.h.in │ │ ├── mremap.c │ │ ├── mremap.exp │ │ ├── posix_memalign.c │ │ ├── posix_memalign.exp │ │ ├── rallocm.c │ │ ├── rallocm.exp │ │ ├── thread_arena.c │ │ └── thread_arena.exp └── linenoise │ ├── .gitignore │ ├── Makefile │ ├── README.markdown │ ├── example.c │ ├── linenoise.c │ └── linenoise.h ├── redis.conf ├── runtest ├── setup ├── COPYING.txt ├── Makefile ├── README.txt ├── Redis Documentation.url ├── Redis Home.url ├── Redis Windows Port Home.url ├── Redis Windows Service and Setup Home.url ├── SetACL.exe ├── redis-setup-wizard-small.bmp ├── redis-setup-wizard.bmp ├── redis.ico ├── redis.iss ├── service-account.pas └── service.pas ├── src ├── Makefile ├── adlist.c ├── adlist.h ├── ae.c ├── ae.h ├── ae_epoll.c ├── ae_kqueue.c ├── ae_select.c ├── ae_ws2.c ├── anet.c ├── anet.h ├── aof.c ├── bio.c ├── bio.h ├── config.c ├── config.h ├── db.c ├── debug.c ├── dict.c ├── dict.h ├── endian.c ├── endian.h ├── fmacros.h ├── help.h ├── intset.c ├── intset.h ├── lzf.h ├── lzfP.h ├── lzf_c.c ├── lzf_d.c ├── mkreleasehdr.sh ├── multi.c ├── networking.c ├── object.c ├── pqsort.c ├── pqsort.h ├── pubsub.c ├── rdb.c ├── redis-benchmark.c ├── redis-check-aof.c ├── redis-check-dump.c ├── redis-cli.c ├── redis.c ├── redis.h ├── release.c ├── replication.c ├── sds.c ├── sds.h ├── service-setup-helper.c ├── service.c ├── service.rc ├── sha1.c ├── sha1.h ├── slowlog.c ├── slowlog.h ├── solarisfixes.h ├── sort.c ├── syncio.c ├── t_hash.c ├── t_list.c ├── t_set.c ├── t_string.c ├── t_zset.c ├── testhelp.h ├── util.c ├── util.h ├── valgrind.sup ├── version.h ├── vm.c ├── win32err.h ├── win32fixes.c ├── win32fixes.h ├── ziplist.c ├── ziplist.h ├── zipmap.c ├── zipmap.h ├── zmalloc.c └── zmalloc.h ├── tests ├── assets │ └── default.conf ├── helpers │ └── gen_write_load.tcl ├── integration │ ├── aof-race.tcl │ ├── aof.tcl │ ├── redis-cli.tcl │ ├── replication-2.tcl │ ├── replication-3.tcl │ └── replication.tcl ├── support │ ├── redis.tcl │ ├── server.tcl │ ├── test.tcl │ ├── tmpfile.tcl │ └── util.tcl ├── test_helper.tcl ├── tmp │ └── .gitignore └── unit │ ├── auth.tcl │ ├── basic.tcl │ ├── cas.tcl │ ├── expire.tcl │ ├── introspection.tcl │ ├── maxmemory.tcl │ ├── other.tcl │ ├── printver.tcl │ ├── protocol.tcl │ ├── pubsub.tcl │ ├── quit.tcl │ ├── slowlog.tcl │ ├── sort.tcl │ └── type │ ├── hash.tcl │ ├── list-2.tcl │ ├── list-3.tcl │ ├── list-common.tcl │ ├── list.tcl │ ├── set.tcl │ └── zset.tcl └── utils ├── generate-command-help.rb ├── install_server.sh ├── mkrelease.sh ├── mktarball.sh ├── redis.conf.tpl ├── redis_init_script └── redis_init_script.tpl /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.rdb 3 | *.log 4 | redis-cli 5 | redis-server 6 | redis-benchmark 7 | redis-check-dump 8 | redis-check-aof 9 | doc-tools 10 | release 11 | misc/* 12 | src/release.h 13 | appendonly.aof 14 | SHORT_TERM_TODO 15 | SciTE.session 16 | vars.bat 17 | *.exe 18 | *.dll 19 | release.h 20 | src/transfer.sh 21 | src/configs 22 | src/redis-server.dSYM 23 | *.depend 24 | *.layout 25 | *.cbp 26 | *.script 27 | *.cbTemp 28 | bin/* 29 | *.sublime-project 30 | *.sublime-workspace 31 | -------------------------------------------------------------------------------- /BUGS: -------------------------------------------------------------------------------- 1 | Plese check http://code.google.com/p/redis/issues/list 2 | -------------------------------------------------------------------------------- /CONTRIBUTING: -------------------------------------------------------------------------------- 1 | 1. Enter irc.freenode.org #redis and start talking with 'antirez' and/or 'pietern' to check if there is interest for such a feature and to understand the probability of it being merged. We'll try hard to keep Redis simple... so you'll likely encounter an high resistence. 2 | 3 | 2. Drop a message to the Redis Google Group with a proposal of semantics/API. 4 | 5 | 3. If steps 1 and 2 are ok, use the following procedure to submit a patch: 6 | 7 | a. Fork Redis on github 8 | b. Create a topic branch (git checkout -b my_branch) 9 | c. Push to your branch (git push origin my_branch) 10 | d. Create an issue in the Redis google code site with a link to your patch 11 | e. Done :) 12 | 13 | Thanks! 14 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | Copyright (c) 2006-2009, Salvatore Sanfilippo 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 5 | 6 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 7 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | * Neither the name of Redis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 9 | 10 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 11 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | Please check the README file. 2 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Top level makefile, the real shit is at src/Makefile 2 | 3 | TARGETS=32bit noopt test 4 | 5 | all: 6 | cd src && $(MAKE) $@ 7 | 8 | install: dummy 9 | cd src && $(MAKE) $@ 10 | 11 | clean: 12 | cd src && $(MAKE) $@ 13 | cd deps/hiredis && $(MAKE) $@ 14 | cd deps/linenoise && $(MAKE) $@ 15 | -(cd deps/jemalloc && $(MAKE) distclean) 16 | cd setup && $(MAKE) $@ 17 | 18 | $(TARGETS): 19 | cd src && $(MAKE) $@ 20 | 21 | setup: all 22 | cd setup && $(MAKE) $@ 23 | 24 | src/help.h: 25 | @./utils/generate-command-help.rb > $@ 26 | 27 | dummy: 28 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | This is a stable release! No TODO file here. 2 | Please check the TODO file in the master branch on github. 3 | 4 | https://github.com/antirez/redis/raw/master/TODO 5 | -------------------------------------------------------------------------------- /deps/hiredis/.gitignore: -------------------------------------------------------------------------------- 1 | /hiredis-test 2 | /hiredis-example* 3 | /*.o 4 | /*.so 5 | /*.dylib 6 | /*.a 7 | -------------------------------------------------------------------------------- /deps/hiredis/COPYING: -------------------------------------------------------------------------------- 1 | Copyright (c) 2006-2009, Salvatore Sanfilippo 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 5 | 6 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 7 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | * Neither the name of Redis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 9 | 10 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 11 | -------------------------------------------------------------------------------- /deps/hiredis/Makefile: -------------------------------------------------------------------------------- 1 | # Hiredis Makefile 2 | # Copyright (C) 2010 Salvatore Sanfilippo 3 | # This file is released under the BSD license, see the COPYING file 4 | 5 | OBJ = net.o hiredis.o sds.o async.o 6 | BINS = hiredis-example hiredis-test 7 | 8 | uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') 9 | osname := $(shell uname -rs | cut -f 1-2 -d "." | cut -f 1 -d "-") 10 | OPTIMIZATION?=-O3 11 | ifeq ($(uname_S),SunOS) 12 | CFLAGS?=-std=c99 -pedantic $(OPTIMIZATION) -fPIC -Wall -W -D__EXTENSIONS__ -D_XPG6 $(ARCH) $(PROF) 13 | CCLINK?=-ldl -lnsl -lsocket -lm -lpthread 14 | LDFLAGS?=-L. -Wl,-R,. 15 | DYLIBNAME?=libhiredis.so 16 | DYLIB_MAKE_CMD?=$(CC) -G -o ${DYLIBNAME} ${OBJ} 17 | STLIBNAME?=libhiredis.a 18 | STLIB_MAKE_CMD?=ar rcs ${STLIBNAME} ${OBJ} 19 | else 20 | ifeq ($(uname_S),Darwin) 21 | CFLAGS?=-std=c99 -pedantic $(OPTIMIZATION) -fPIC -Wall -W -Wstrict-prototypes -Wwrite-strings $(ARCH) $(PROF) 22 | CCLINK?=-lm -pthread 23 | LDFLAGS?=-L. -Wl,-rpath,. 24 | OBJARCH?=-arch i386 -arch x86_64 25 | DYLIBNAME?=libhiredis.dylib 26 | DYLIB_MAKE_CMD?=libtool -dynamic -o ${DYLIBNAME} -lm ${DEBUG} - ${OBJ} 27 | STLIBNAME?=libhiredis.a 28 | STLIB_MAKE_CMD?=libtool -static -o ${STLIBNAME} - ${OBJ} 29 | else ifeq ($(osname),MINGW32_NT) 30 | CFLAGS?= -std=gnu99 -pedantic $(OPTIMIZATION) -Wall -W -D_ISOC99_SOURCE -D__USE_MINGW_ANSI_STDIO=1 -Wwrite-strings $(ARCH) $(PROF) 31 | CCLINK?= -mthreads 32 | LIBS?= -lws2_32 33 | LDFLAGS?=-L. 34 | DYLIBNAME?=hiredis.dll 35 | DYLIB_MAKE_CMD?=gcc -shared -Wl,-soname,${DYLIBNAME} -o ${DYLIBNAME} ${OBJ} ${LIBS} 36 | STLIBNAME?=libhiredis.a 37 | STLIB_MAKE_CMD?=ar rcs ${STLIBNAME} ${OBJ} 38 | CC=gcc 39 | else 40 | CFLAGS?=-std=c99 -pedantic $(OPTIMIZATION) -fPIC -Wall -W -Wstrict-prototypes -Wwrite-strings $(ARCH) $(PROF) 41 | CCLINK?=-lm -pthread 42 | LDFLAGS?=-L. -Wl,-rpath,. 43 | DYLIBNAME?=libhiredis.so 44 | DYLIB_MAKE_CMD?=gcc -shared -Wl,-soname,${DYLIBNAME} -o ${DYLIBNAME} ${OBJ} 45 | STLIBNAME?=libhiredis.a 46 | STLIB_MAKE_CMD?=ar rcs ${STLIBNAME} ${OBJ} 47 | endif 48 | endif 49 | 50 | CCOPT= $(CFLAGS) $(CCLINK) 51 | DEBUG?= -g -ggdb 52 | 53 | PREFIX?= /usr/local 54 | INSTALL_INC= $(PREFIX)/include/hiredis 55 | INSTALL_LIB= $(PREFIX)/lib 56 | INSTALL= cp -a 57 | 58 | all: ${DYLIBNAME} ${BINS} 59 | 60 | # Deps (use make dep to generate this) 61 | net.o: net.c fmacros.h net.h 62 | async.o: async.c async.h hiredis.h sds.h util.h dict.c dict.h 63 | example.o: example.c hiredis.h 64 | hiredis.o: hiredis.c hiredis.h net.h sds.h util.h 65 | sds.o: sds.c sds.h 66 | test.o: test.c hiredis.h 67 | 68 | ${DYLIBNAME}: ${OBJ} 69 | ${DYLIB_MAKE_CMD} 70 | 71 | ${STLIBNAME}: ${OBJ} 72 | ${STLIB_MAKE_CMD} 73 | 74 | dynamic: ${DYLIBNAME} 75 | static: ${STLIBNAME} 76 | 77 | # Binaries: 78 | hiredis-example-libevent: example-libevent.c adapters/libevent.h ${DYLIBNAME} 79 | $(CC) -o $@ $(CCOPT) $(DEBUG) $(LDFLAGS) -lhiredis -levent example-libevent.c ${LIBS} 80 | 81 | hiredis-example-libev: example-libev.c adapters/libev.h ${DYLIBNAME} 82 | $(CC) -o $@ $(CCOPT) $(DEBUG) $(LDFLAGS) -lhiredis -lev example-libev.c ${LIBS} 83 | 84 | ifndef AE_DIR 85 | hiredis-example-ae: 86 | @echo "Please specify AE_DIR (e.g. /src)" 87 | @false 88 | else 89 | hiredis-example-ae: example-ae.c adapters/ae.h ${DYLIBNAME} 90 | $(CC) -o $@ $(CCOPT) $(DEBUG) -I$(AE_DIR) $(LDFLAGS) -lhiredis example-ae.c $(AE_DIR)/ae.o $(AE_DIR)/zmalloc.o 91 | endif 92 | 93 | hiredis-%: %.o ${DYLIBNAME} 94 | $(CC) -o $@ $(CCOPT) $(DEBUG) $(LDFLAGS) -lhiredis $< ${LIBS} 95 | 96 | test: hiredis-test 97 | ./hiredis-test 98 | 99 | .c.o: 100 | $(CC) -c $(CFLAGS) $(OBJARCH) $(DEBUG) $(COMPILE_TIME) $< 101 | 102 | clean: 103 | rm -rf ${DYLIBNAME} ${STLIBNAME} $(BINS) hiredis-example* *.o *.gcda *.gcno *.gcov *.dll *.exe 104 | 105 | dep: 106 | $(CC) -MM *.c 107 | 108 | install: ${DYLIBNAME} ${STLIBNAME} 109 | mkdir -p $(INSTALL_INC) $(INSTALL_LIB) 110 | $(INSTALL) hiredis.h async.h adapters $(INSTALL_INC) 111 | $(INSTALL) ${DYLIBNAME} ${STLIBNAME} $(INSTALL_LIB) 112 | 113 | 32bit: 114 | @echo "" 115 | @echo "WARNING: if it fails under Linux you probably need to install libc6-dev-i386" 116 | @echo "" 117 | $(MAKE) ARCH="-m32" 118 | 119 | gprof: 120 | $(MAKE) PROF="-pg" 121 | 122 | gcov: 123 | $(MAKE) PROF="-fprofile-arcs -ftest-coverage" 124 | 125 | noopt: 126 | $(MAKE) OPTIMIZATION="" 127 | -------------------------------------------------------------------------------- /deps/hiredis/TODO: -------------------------------------------------------------------------------- 1 | - add redisCommandVector() 2 | - add support for pipelining 3 | -------------------------------------------------------------------------------- /deps/hiredis/adapters/ae.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../hiredis.h" 4 | #include "../async.h" 5 | 6 | typedef struct redisAeEvents { 7 | redisAsyncContext *context; 8 | aeEventLoop *loop; 9 | int fd; 10 | int reading, writing; 11 | } redisAeEvents; 12 | 13 | void redisAeReadEvent(aeEventLoop *el, int fd, void *privdata, int mask) { 14 | ((void)el); ((void)fd); ((void)mask); 15 | 16 | redisAeEvents *e = (redisAeEvents*)privdata; 17 | redisAsyncHandleRead(e->context); 18 | } 19 | 20 | void redisAeWriteEvent(aeEventLoop *el, int fd, void *privdata, int mask) { 21 | ((void)el); ((void)fd); ((void)mask); 22 | 23 | redisAeEvents *e = (redisAeEvents*)privdata; 24 | redisAsyncHandleWrite(e->context); 25 | } 26 | 27 | void redisAeAddRead(void *privdata) { 28 | redisAeEvents *e = (redisAeEvents*)privdata; 29 | aeEventLoop *loop = e->loop; 30 | if (!e->reading) { 31 | e->reading = 1; 32 | aeCreateFileEvent(loop,e->fd,AE_READABLE,redisAeReadEvent,e); 33 | } 34 | } 35 | 36 | void redisAeDelRead(void *privdata) { 37 | redisAeEvents *e = (redisAeEvents*)privdata; 38 | aeEventLoop *loop = e->loop; 39 | if (e->reading) { 40 | e->reading = 0; 41 | aeDeleteFileEvent(loop,e->fd,AE_READABLE); 42 | } 43 | } 44 | 45 | void redisAeAddWrite(void *privdata) { 46 | redisAeEvents *e = (redisAeEvents*)privdata; 47 | aeEventLoop *loop = e->loop; 48 | if (!e->writing) { 49 | e->writing = 1; 50 | aeCreateFileEvent(loop,e->fd,AE_WRITABLE,redisAeWriteEvent,e); 51 | } 52 | } 53 | 54 | void redisAeDelWrite(void *privdata) { 55 | redisAeEvents *e = (redisAeEvents*)privdata; 56 | aeEventLoop *loop = e->loop; 57 | if (e->writing) { 58 | e->writing = 0; 59 | aeDeleteFileEvent(loop,e->fd,AE_WRITABLE); 60 | } 61 | } 62 | 63 | void redisAeCleanup(void *privdata) { 64 | redisAeEvents *e = (redisAeEvents*)privdata; 65 | redisAeDelRead(privdata); 66 | redisAeDelWrite(privdata); 67 | free(e); 68 | } 69 | 70 | int redisAeAttach(aeEventLoop *loop, redisAsyncContext *ac) { 71 | redisContext *c = &(ac->c); 72 | redisAeEvents *e; 73 | 74 | /* Nothing should be attached when something is already attached */ 75 | if (ac->_adapter_data != NULL) 76 | return REDIS_ERR; 77 | 78 | /* Create container for context and r/w events */ 79 | e = (redisAeEvents*)malloc(sizeof(*e)); 80 | e->context = ac; 81 | e->loop = loop; 82 | e->fd = c->fd; 83 | e->reading = e->writing = 0; 84 | 85 | /* Register functions to start/stop listening for events */ 86 | ac->evAddRead = redisAeAddRead; 87 | ac->evDelRead = redisAeDelRead; 88 | ac->evAddWrite = redisAeAddWrite; 89 | ac->evDelWrite = redisAeDelWrite; 90 | ac->evCleanup = redisAeCleanup; 91 | ac->_adapter_data = e; 92 | 93 | return REDIS_OK; 94 | } 95 | 96 | -------------------------------------------------------------------------------- /deps/hiredis/adapters/libev.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../hiredis.h" 4 | #include "../async.h" 5 | 6 | typedef struct redisLibevEvents { 7 | redisAsyncContext *context; 8 | struct ev_loop *loop; 9 | int reading, writing; 10 | ev_io rev, wev; 11 | } redisLibevEvents; 12 | 13 | void redisLibevReadEvent(EV_P_ ev_io *watcher, int revents) { 14 | #if EV_MULTIPLICITY 15 | ((void)loop); 16 | #endif 17 | ((void)revents); 18 | 19 | redisLibevEvents *e = (redisLibevEvents*)watcher->data; 20 | redisAsyncHandleRead(e->context); 21 | } 22 | 23 | void redisLibevWriteEvent(EV_P_ ev_io *watcher, int revents) { 24 | #if EV_MULTIPLICITY 25 | ((void)loop); 26 | #endif 27 | ((void)revents); 28 | 29 | redisLibevEvents *e = (redisLibevEvents*)watcher->data; 30 | redisAsyncHandleWrite(e->context); 31 | } 32 | 33 | void redisLibevAddRead(void *privdata) { 34 | redisLibevEvents *e = (redisLibevEvents*)privdata; 35 | struct ev_loop *loop = e->loop; 36 | ((void)loop); 37 | if (!e->reading) { 38 | e->reading = 1; 39 | ev_io_start(EV_A_ &e->rev); 40 | } 41 | } 42 | 43 | void redisLibevDelRead(void *privdata) { 44 | redisLibevEvents *e = (redisLibevEvents*)privdata; 45 | struct ev_loop *loop = e->loop; 46 | ((void)loop); 47 | if (e->reading) { 48 | e->reading = 0; 49 | ev_io_stop(EV_A_ &e->rev); 50 | } 51 | } 52 | 53 | void redisLibevAddWrite(void *privdata) { 54 | redisLibevEvents *e = (redisLibevEvents*)privdata; 55 | struct ev_loop *loop = e->loop; 56 | ((void)loop); 57 | if (!e->writing) { 58 | e->writing = 1; 59 | ev_io_start(EV_A_ &e->wev); 60 | } 61 | } 62 | 63 | void redisLibevDelWrite(void *privdata) { 64 | redisLibevEvents *e = (redisLibevEvents*)privdata; 65 | struct ev_loop *loop = e->loop; 66 | ((void)loop); 67 | if (e->writing) { 68 | e->writing = 0; 69 | ev_io_stop(EV_A_ &e->wev); 70 | } 71 | } 72 | 73 | void redisLibevCleanup(void *privdata) { 74 | redisLibevEvents *e = (redisLibevEvents*)privdata; 75 | redisLibevDelRead(privdata); 76 | redisLibevDelWrite(privdata); 77 | free(e); 78 | } 79 | 80 | int redisLibevAttach(EV_P_ redisAsyncContext *ac) { 81 | redisContext *c = &(ac->c); 82 | redisLibevEvents *e; 83 | 84 | /* Nothing should be attached when something is already attached */ 85 | if (ac->_adapter_data != NULL) 86 | return REDIS_ERR; 87 | 88 | /* Create container for context and r/w events */ 89 | e = (redisLibevEvents*)malloc(sizeof(*e)); 90 | e->context = ac; 91 | #if EV_MULTIPLICITY 92 | e->loop = loop; 93 | #else 94 | e->loop = NULL; 95 | #endif 96 | e->reading = e->writing = 0; 97 | e->rev.data = e; 98 | e->wev.data = e; 99 | 100 | /* Register functions to start/stop listening for events */ 101 | ac->evAddRead = redisLibevAddRead; 102 | ac->evDelRead = redisLibevDelRead; 103 | ac->evAddWrite = redisLibevAddWrite; 104 | ac->evDelWrite = redisLibevDelWrite; 105 | ac->evCleanup = redisLibevCleanup; 106 | ac->_adapter_data = e; 107 | 108 | /* Initialize read/write events */ 109 | ev_io_init(&e->rev,redisLibevReadEvent,c->fd,EV_READ); 110 | ev_io_init(&e->wev,redisLibevWriteEvent,c->fd,EV_WRITE); 111 | return REDIS_OK; 112 | } 113 | 114 | -------------------------------------------------------------------------------- /deps/hiredis/adapters/libevent.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "../hiredis.h" 4 | #include "../async.h" 5 | 6 | typedef struct redisLibeventEvents { 7 | redisAsyncContext *context; 8 | struct event rev, wev; 9 | } redisLibeventEvents; 10 | 11 | void redisLibeventReadEvent(int fd, short event, void *arg) { 12 | ((void)fd); ((void)event); 13 | redisLibeventEvents *e = (redisLibeventEvents*)arg; 14 | redisAsyncHandleRead(e->context); 15 | } 16 | 17 | void redisLibeventWriteEvent(int fd, short event, void *arg) { 18 | ((void)fd); ((void)event); 19 | redisLibeventEvents *e = (redisLibeventEvents*)arg; 20 | redisAsyncHandleWrite(e->context); 21 | } 22 | 23 | void redisLibeventAddRead(void *privdata) { 24 | redisLibeventEvents *e = (redisLibeventEvents*)privdata; 25 | event_add(&e->rev,NULL); 26 | } 27 | 28 | void redisLibeventDelRead(void *privdata) { 29 | redisLibeventEvents *e = (redisLibeventEvents*)privdata; 30 | event_del(&e->rev); 31 | } 32 | 33 | void redisLibeventAddWrite(void *privdata) { 34 | redisLibeventEvents *e = (redisLibeventEvents*)privdata; 35 | event_add(&e->wev,NULL); 36 | } 37 | 38 | void redisLibeventDelWrite(void *privdata) { 39 | redisLibeventEvents *e = (redisLibeventEvents*)privdata; 40 | event_del(&e->wev); 41 | } 42 | 43 | void redisLibeventCleanup(void *privdata) { 44 | redisLibeventEvents *e = (redisLibeventEvents*)privdata; 45 | event_del(&e->rev); 46 | event_del(&e->wev); 47 | free(e); 48 | } 49 | 50 | int redisLibeventAttach(redisAsyncContext *ac, struct event_base *base) { 51 | redisContext *c = &(ac->c); 52 | redisLibeventEvents *e; 53 | 54 | /* Nothing should be attached when something is already attached */ 55 | if (ac->_adapter_data != NULL) 56 | return REDIS_ERR; 57 | 58 | /* Create container for context and r/w events */ 59 | e = (redisLibeventEvents*)malloc(sizeof(*e)); 60 | e->context = ac; 61 | 62 | /* Register functions to start/stop listening for events */ 63 | ac->evAddRead = redisLibeventAddRead; 64 | ac->evDelRead = redisLibeventDelRead; 65 | ac->evAddWrite = redisLibeventAddWrite; 66 | ac->evDelWrite = redisLibeventDelWrite; 67 | ac->evCleanup = redisLibeventCleanup; 68 | ac->_adapter_data = e; 69 | 70 | /* Initialize and install read/write events */ 71 | event_set(&e->rev,c->fd,EV_READ,redisLibeventReadEvent,e); 72 | event_set(&e->wev,c->fd,EV_WRITE,redisLibeventWriteEvent,e); 73 | event_base_set(base,&e->rev); 74 | event_base_set(base,&e->wev); 75 | return REDIS_OK; 76 | } 77 | -------------------------------------------------------------------------------- /deps/hiredis/example-ae.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "hiredis.h" 6 | #include "async.h" 7 | #include "adapters/ae.h" 8 | 9 | /* Put event loop in the global scope, so it can be explicitly stopped */ 10 | static aeEventLoop *loop; 11 | 12 | void getCallback(redisAsyncContext *c, void *r, void *privdata) { 13 | redisReply *reply = r; 14 | if (reply == NULL) return; 15 | printf("argv[%s]: %s\n", (char*)privdata, reply->str); 16 | 17 | /* Disconnect after receiving the reply to GET */ 18 | redisAsyncDisconnect(c); 19 | } 20 | 21 | void connectCallback(const redisAsyncContext *c) { 22 | ((void)c); 23 | printf("connected...\n"); 24 | } 25 | 26 | void disconnectCallback(const redisAsyncContext *c, int status) { 27 | if (status != REDIS_OK) { 28 | printf("Error: %s\n", c->errstr); 29 | } 30 | printf("disconnected...\n"); 31 | aeStop(loop); 32 | } 33 | 34 | int main (int argc, char **argv) { 35 | signal(SIGPIPE, SIG_IGN); 36 | 37 | redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); 38 | if (c->err) { 39 | /* Let *c leak for now... */ 40 | printf("Error: %s\n", c->errstr); 41 | return 1; 42 | } 43 | 44 | loop = aeCreateEventLoop(); 45 | redisAeAttach(loop, c); 46 | redisAsyncSetConnectCallback(c,connectCallback); 47 | redisAsyncSetDisconnectCallback(c,disconnectCallback); 48 | redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); 49 | redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); 50 | aeMain(loop); 51 | return 0; 52 | } 53 | 54 | -------------------------------------------------------------------------------- /deps/hiredis/example-libev.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "hiredis.h" 6 | #include "async.h" 7 | #include "adapters/libev.h" 8 | 9 | void getCallback(redisAsyncContext *c, void *r, void *privdata) { 10 | redisReply *reply = r; 11 | if (reply == NULL) return; 12 | printf("argv[%s]: %s\n", (char*)privdata, reply->str); 13 | 14 | /* Disconnect after receiving the reply to GET */ 15 | redisAsyncDisconnect(c); 16 | } 17 | 18 | void connectCallback(const redisAsyncContext *c) { 19 | ((void)c); 20 | printf("connected...\n"); 21 | } 22 | 23 | void disconnectCallback(const redisAsyncContext *c, int status) { 24 | if (status != REDIS_OK) { 25 | printf("Error: %s\n", c->errstr); 26 | } 27 | printf("disconnected...\n"); 28 | } 29 | 30 | int main (int argc, char **argv) { 31 | signal(SIGPIPE, SIG_IGN); 32 | 33 | redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); 34 | if (c->err) { 35 | /* Let *c leak for now... */ 36 | printf("Error: %s\n", c->errstr); 37 | return 1; 38 | } 39 | 40 | redisLibevAttach(EV_DEFAULT_ c); 41 | redisAsyncSetConnectCallback(c,connectCallback); 42 | redisAsyncSetDisconnectCallback(c,disconnectCallback); 43 | redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); 44 | redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); 45 | ev_loop(EV_DEFAULT_ 0); 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /deps/hiredis/example-libevent.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "hiredis.h" 6 | #include "async.h" 7 | #include "adapters/libevent.h" 8 | 9 | void getCallback(redisAsyncContext *c, void *r, void *privdata) { 10 | redisReply *reply = r; 11 | if (reply == NULL) return; 12 | printf("argv[%s]: %s\n", (char*)privdata, reply->str); 13 | 14 | /* Disconnect after receiving the reply to GET */ 15 | redisAsyncDisconnect(c); 16 | } 17 | 18 | void connectCallback(const redisAsyncContext *c) { 19 | ((void)c); 20 | printf("connected...\n"); 21 | } 22 | 23 | void disconnectCallback(const redisAsyncContext *c, int status) { 24 | if (status != REDIS_OK) { 25 | printf("Error: %s\n", c->errstr); 26 | } 27 | printf("disconnected...\n"); 28 | } 29 | 30 | int main (int argc, char **argv) { 31 | signal(SIGPIPE, SIG_IGN); 32 | struct event_base *base = event_base_new(); 33 | 34 | redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); 35 | if (c->err) { 36 | /* Let *c leak for now... */ 37 | printf("Error: %s\n", c->errstr); 38 | return 1; 39 | } 40 | 41 | redisLibeventAttach(c,base); 42 | redisAsyncSetConnectCallback(c,connectCallback); 43 | redisAsyncSetDisconnectCallback(c,disconnectCallback); 44 | redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); 45 | redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); 46 | event_base_dispatch(base); 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /deps/hiredis/example.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #ifdef _WIN32 6 | #include 7 | #include 8 | #endif 9 | 10 | #include "hiredis.h" 11 | 12 | int main(void) { 13 | unsigned int j; 14 | redisContext *c; 15 | redisReply *reply; 16 | #ifdef _WIN32 17 | WSADATA t_wsa; 18 | WORD wVers = MAKEWORD(2, 2); // Set the version number to 2.2 19 | int iError = WSAStartup(wVers, &t_wsa); 20 | 21 | if(iError != NO_ERROR || LOBYTE(t_wsa.wVersion) != 2 || HIBYTE(t_wsa.wVersion) != 2 ) { 22 | printf("Winsock2 init error: %d\n", iError); 23 | exit(1); 24 | } 25 | 26 | atexit((void(*)(void)) WSACleanup); 27 | #endif 28 | 29 | struct timeval timeout = { 1, 500000 }; // 1.5 seconds 30 | c = redisConnectWithTimeout((char*)"127.0.0.2", 6379, timeout); 31 | if (c->err) { 32 | printf("Connection error: %s\n", c->errstr); 33 | exit(1); 34 | } 35 | 36 | /* PING server */ 37 | reply = redisCommand(c,"PING"); 38 | printf("PING: %s\n", reply->str); 39 | freeReplyObject(reply); 40 | 41 | /* Set a key */ 42 | reply = redisCommand(c,"SET %s %s", "foo", "hello world"); 43 | printf("SET: %s\n", reply->str); 44 | freeReplyObject(reply); 45 | 46 | /* Set a key using binary safe API */ 47 | reply = redisCommand(c,"SET %b %b", "bar", 3, "hello", 5); 48 | printf("SET (binary API): %s\n", reply->str); 49 | freeReplyObject(reply); 50 | 51 | /* Try a GET and two INCR */ 52 | reply = redisCommand(c,"GET foo"); 53 | printf("GET foo: %s\n", reply->str); 54 | freeReplyObject(reply); 55 | 56 | reply = redisCommand(c,"INCR counter"); 57 | printf("INCR counter: %lld\n", reply->integer); 58 | freeReplyObject(reply); 59 | /* again ... */ 60 | reply = redisCommand(c,"INCR counter"); 61 | printf("INCR counter: %lld\n", reply->integer); 62 | freeReplyObject(reply); 63 | 64 | /* Create a list of numbers, from 0 to 9 */ 65 | reply = redisCommand(c,"DEL mylist"); 66 | freeReplyObject(reply); 67 | for (j = 0; j < 10; j++) { 68 | char buf[64]; 69 | 70 | snprintf(buf,64,"%d",j); 71 | reply = redisCommand(c,"LPUSH mylist element-%s", buf); 72 | freeReplyObject(reply); 73 | } 74 | 75 | /* Let's check what we have inside the list */ 76 | reply = redisCommand(c,"LRANGE mylist 0 -1"); 77 | if (reply->type == REDIS_REPLY_ARRAY) { 78 | for (j = 0; j < reply->elements; j++) { 79 | printf("%u) %s\n", j, reply->element[j]->str); 80 | } 81 | } 82 | freeReplyObject(reply); 83 | 84 | return 0; 85 | } 86 | -------------------------------------------------------------------------------- /deps/hiredis/fmacros.h: -------------------------------------------------------------------------------- 1 | #ifndef __HIREDIS_FMACRO_H 2 | #define __HIREDIS_FMACRO_H 3 | 4 | #ifndef _BSD_SOURCE 5 | #define _BSD_SOURCE 6 | #endif 7 | 8 | #ifdef __linux__ 9 | #define _XOPEN_SOURCE 700 10 | #else 11 | #define _XOPEN_SOURCE 12 | #endif 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /deps/hiredis/net.h: -------------------------------------------------------------------------------- 1 | /* Extracted from anet.c to work properly with Hiredis error reporting. 2 | * 3 | * Copyright (c) 2006-2010, Salvatore Sanfilippo 4 | * Copyright (c) 2010, Pieter Noordhuis 5 | * 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions are met: 10 | * 11 | * * Redistributions of source code must retain the above copyright notice, 12 | * this list of conditions and the following disclaimer. 13 | * * Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * * Neither the name of Redis nor the names of its contributors may be used 17 | * to endorse or promote products derived from this software without 18 | * specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 24 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 | * POSSIBILITY OF SUCH DAMAGE. 31 | */ 32 | 33 | #ifndef __NET_H 34 | #define __NET_H 35 | 36 | #include "hiredis.h" 37 | 38 | #if defined(__sun) 39 | #define AF_LOCAL AF_UNIX 40 | #endif 41 | 42 | int redisContextSetTimeout(redisContext *c, struct timeval tv); 43 | int redisContextConnectTcp(redisContext *c, const char *addr, int port, struct timeval *timeout); 44 | int redisContextConnectUnix(redisContext *c, const char *path, struct timeval *timeout); 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /deps/hiredis/sds.h: -------------------------------------------------------------------------------- 1 | /* SDSLib, A C dynamic strings library 2 | * 3 | * Copyright (c) 2006-2010, Salvatore Sanfilippo 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * * Neither the name of Redis nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without 16 | * specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef __SDS_H 32 | #define __SDS_H 33 | 34 | #include 35 | #include 36 | 37 | typedef char *sds; 38 | 39 | struct sdshdr { 40 | int len; 41 | int free; 42 | char buf[]; 43 | }; 44 | 45 | static inline size_t sdslen(const sds s) { 46 | struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr))); 47 | return sh->len; 48 | } 49 | 50 | static inline size_t sdsavail(const sds s) { 51 | struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr))); 52 | return sh->free; 53 | } 54 | 55 | sds sdsnewlen(const void *init, size_t initlen); 56 | sds sdsnew(const char *init); 57 | sds sdsempty(void); 58 | size_t sdslen(const sds s); 59 | sds sdsdup(const sds s); 60 | void sdsfree(sds s); 61 | size_t sdsavail(sds s); 62 | sds sdsgrowzero(sds s, size_t len); 63 | sds sdscatlen(sds s, const void *t, size_t len); 64 | sds sdscat(sds s, const char *t); 65 | sds sdscpylen(sds s, char *t, size_t len); 66 | sds sdscpy(sds s, char *t); 67 | sds sdscatvprintf(sds s, const char *fmt, va_list ap); 68 | 69 | #ifdef _WIN32 70 | sds sdscatprintf(sds s, const char *fmt, ...); 71 | #else 72 | #ifdef __GNUC__ 73 | sds sdscatprintf(sds s, const char *fmt, ...) 74 | __attribute__((format(printf, 2, 3))); 75 | #else 76 | sds sdscatprintf(sds s, const char *fmt, ...); 77 | #endif 78 | #endif /* _WIN32 */ 79 | 80 | sds sdstrim(sds s, const char *cset); 81 | sds sdsrange(sds s, int start, int end); 82 | void sdsupdatelen(sds s); 83 | int sdscmp(sds s1, sds s2); 84 | sds *sdssplitlen(char *s, int len, char *sep, int seplen, int *count); 85 | void sdsfreesplitres(sds *tokens, int count); 86 | void sdstolower(sds s); 87 | void sdstoupper(sds s); 88 | sds sdsfromlonglong(long long value); 89 | sds sdscatrepr(sds s, char *p, size_t len); 90 | sds *sdssplitargs(char *line, int *argc); 91 | 92 | #endif 93 | -------------------------------------------------------------------------------- /deps/hiredis/util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2010, Salvatore Sanfilippo 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, 9 | * this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * * Neither the name of Redis nor the names of its contributors may be used 14 | * to endorse or promote products derived from this software without 15 | * specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #ifndef __UTIL_H 31 | #define __UTIL_H 32 | #include 33 | 34 | /* Abort on out of memory */ 35 | static void redisOOM(void) { 36 | fprintf(stderr,"Out of memory in hiredis"); 37 | exit(1); 38 | } 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /deps/jemalloc/.gitignore: -------------------------------------------------------------------------------- 1 | /autom4te.cache/ 2 | /config.stamp 3 | /config.log 4 | /config.status 5 | /configure 6 | /doc/html.xsl 7 | /doc/manpages.xsl 8 | /doc/jemalloc.xml 9 | /doc/jemalloc.html 10 | /doc/jemalloc.3 11 | /lib/ 12 | /Makefile 13 | /include/jemalloc/internal/jemalloc_internal\.h 14 | /include/jemalloc/jemalloc\.h 15 | /include/jemalloc/jemalloc_defs\.h 16 | /test/jemalloc_test\.h 17 | /src/*.[od] 18 | /test/*.[od] 19 | /test/*.out 20 | /test/[a-z]* 21 | !test/*.c 22 | !test/*.exp 23 | /VERSION 24 | -------------------------------------------------------------------------------- /deps/jemalloc/COPYING: -------------------------------------------------------------------------------- 1 | Unless otherwise specified, files in the jemalloc source distribution are 2 | subject to the following licenses: 3 | -------------------------------------------------------------------------------- 4 | Copyright (C) 2002-2010 Jason Evans . 5 | All rights reserved. 6 | Copyright (C) 2007-2010 Mozilla Foundation. All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 1. Redistributions of source code must retain the above copyright notice(s), 11 | this list of conditions and the following disclaimer. 12 | 2. Redistributions in binary form must reproduce the above copyright notice(s), 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY EXPRESS 17 | OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 | EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 20 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 22 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 23 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 24 | OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- 27 | Copyright (C) 2009-2010 Facebook, Inc. 28 | All rights reserved. 29 | 30 | Redistribution and use in source and binary forms, with or without modification, 31 | are permitted provided that the following conditions are met: 32 | * Redistributions of source code must retain the above copyright notice, this 33 | list of conditions and the following disclaimer. 34 | * Redistributions in binary form must reproduce the above copyright notice, this 35 | list of conditions and the following disclaimer in the documentation and/or 36 | other materials provided with the distribution. 37 | * Neither the name of Facebook, Inc. nor the names of its contributors may be 38 | used to endorse or promote products derived from this software without 39 | specific prior written permission. 40 | 41 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 42 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 43 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 44 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 45 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 46 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 48 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 49 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 50 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 51 | -------------------------------------------------------------------------------- 52 | -------------------------------------------------------------------------------- /deps/jemalloc/README: -------------------------------------------------------------------------------- 1 | jemalloc is a general-purpose scalable concurrent malloc(3) implementation. 2 | This distribution is a stand-alone "portable" implementation that currently 3 | targets Linux and Apple OS X. jemalloc is included as the default allocator in 4 | the FreeBSD and NetBSD operating systems, and it is used by the Mozilla Firefox 5 | web browser on Microsoft Windows-related platforms. Depending on your needs, 6 | one of the other divergent versions may suit your needs better than this 7 | distribution. 8 | 9 | The COPYING file contains copyright and licensing information. 10 | 11 | The INSTALL file contains information on how to configure, build, and install 12 | jemalloc. 13 | 14 | The ChangeLog file contains a brief summary of changes for each release. 15 | 16 | URL: http://www.canonware.com/jemalloc/ 17 | -------------------------------------------------------------------------------- /deps/jemalloc/VERSION: -------------------------------------------------------------------------------- 1 | 2.2.5-0-gfc1bb70e5f0d9a58b39efa39cc549b5af5104760 2 | -------------------------------------------------------------------------------- /deps/jemalloc/autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for i in autoconf; do 4 | echo "$i" 5 | $i 6 | if [ $? -ne 0 ]; then 7 | echo "Error $? in $i" 8 | exit 1 9 | fi 10 | done 11 | 12 | echo "./configure --enable-autogen $@" 13 | ./configure --enable-autogen $@ 14 | if [ $? -ne 0 ]; then 15 | echo "Error $? in ./configure" 16 | exit 1 17 | fi 18 | -------------------------------------------------------------------------------- /deps/jemalloc/config.stamp.in: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rgl/redis/de23721acac1d2df6e30c55e4fb902bba39c956a/deps/jemalloc/config.stamp.in -------------------------------------------------------------------------------- /deps/jemalloc/doc/html.xsl.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /deps/jemalloc/doc/jemalloc.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rgl/redis/de23721acac1d2df6e30c55e4fb902bba39c956a/deps/jemalloc/doc/jemalloc.html -------------------------------------------------------------------------------- /deps/jemalloc/doc/manpages.xsl.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /deps/jemalloc/doc/stylesheet.xsl: -------------------------------------------------------------------------------- 1 | 2 | ansi 3 | 4 | 5 | "" 6 | 7 | 8 | -------------------------------------------------------------------------------- /deps/jemalloc/include/jemalloc/internal/base.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | #ifdef JEMALLOC_H_TYPES 3 | 4 | #endif /* JEMALLOC_H_TYPES */ 5 | /******************************************************************************/ 6 | #ifdef JEMALLOC_H_STRUCTS 7 | 8 | #endif /* JEMALLOC_H_STRUCTS */ 9 | /******************************************************************************/ 10 | #ifdef JEMALLOC_H_EXTERNS 11 | 12 | extern malloc_mutex_t base_mtx; 13 | 14 | void *base_alloc(size_t size); 15 | extent_node_t *base_node_alloc(void); 16 | void base_node_dealloc(extent_node_t *node); 17 | bool base_boot(void); 18 | 19 | #endif /* JEMALLOC_H_EXTERNS */ 20 | /******************************************************************************/ 21 | #ifdef JEMALLOC_H_INLINES 22 | 23 | #endif /* JEMALLOC_H_INLINES */ 24 | /******************************************************************************/ 25 | -------------------------------------------------------------------------------- /deps/jemalloc/include/jemalloc/internal/chunk.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | #ifdef JEMALLOC_H_TYPES 3 | 4 | /* 5 | * Size and alignment of memory chunks that are allocated by the OS's virtual 6 | * memory system. 7 | */ 8 | #define LG_CHUNK_DEFAULT 22 9 | 10 | /* Return the chunk address for allocation address a. */ 11 | #define CHUNK_ADDR2BASE(a) \ 12 | ((void *)((uintptr_t)(a) & ~chunksize_mask)) 13 | 14 | /* Return the chunk offset of address a. */ 15 | #define CHUNK_ADDR2OFFSET(a) \ 16 | ((size_t)((uintptr_t)(a) & chunksize_mask)) 17 | 18 | /* Return the smallest chunk multiple that is >= s. */ 19 | #define CHUNK_CEILING(s) \ 20 | (((s) + chunksize_mask) & ~chunksize_mask) 21 | 22 | #endif /* JEMALLOC_H_TYPES */ 23 | /******************************************************************************/ 24 | #ifdef JEMALLOC_H_STRUCTS 25 | 26 | #endif /* JEMALLOC_H_STRUCTS */ 27 | /******************************************************************************/ 28 | #ifdef JEMALLOC_H_EXTERNS 29 | 30 | extern size_t opt_lg_chunk; 31 | #ifdef JEMALLOC_SWAP 32 | extern bool opt_overcommit; 33 | #endif 34 | 35 | #if (defined(JEMALLOC_STATS) || defined(JEMALLOC_PROF)) 36 | /* Protects stats_chunks; currently not used for any other purpose. */ 37 | extern malloc_mutex_t chunks_mtx; 38 | /* Chunk statistics. */ 39 | extern chunk_stats_t stats_chunks; 40 | #endif 41 | 42 | #ifdef JEMALLOC_IVSALLOC 43 | extern rtree_t *chunks_rtree; 44 | #endif 45 | 46 | extern size_t chunksize; 47 | extern size_t chunksize_mask; /* (chunksize - 1). */ 48 | extern size_t chunk_npages; 49 | extern size_t map_bias; /* Number of arena chunk header pages. */ 50 | extern size_t arena_maxclass; /* Max size class for arenas. */ 51 | 52 | void *chunk_alloc(size_t size, bool base, bool *zero); 53 | void chunk_dealloc(void *chunk, size_t size, bool unmap); 54 | bool chunk_boot(void); 55 | 56 | #endif /* JEMALLOC_H_EXTERNS */ 57 | /******************************************************************************/ 58 | #ifdef JEMALLOC_H_INLINES 59 | 60 | #endif /* JEMALLOC_H_INLINES */ 61 | /******************************************************************************/ 62 | 63 | #include "jemalloc/internal/chunk_swap.h" 64 | #include "jemalloc/internal/chunk_dss.h" 65 | #include "jemalloc/internal/chunk_mmap.h" 66 | -------------------------------------------------------------------------------- /deps/jemalloc/include/jemalloc/internal/chunk_dss.h: -------------------------------------------------------------------------------- 1 | #ifdef JEMALLOC_DSS 2 | /******************************************************************************/ 3 | #ifdef JEMALLOC_H_TYPES 4 | 5 | #endif /* JEMALLOC_H_TYPES */ 6 | /******************************************************************************/ 7 | #ifdef JEMALLOC_H_STRUCTS 8 | 9 | #endif /* JEMALLOC_H_STRUCTS */ 10 | /******************************************************************************/ 11 | #ifdef JEMALLOC_H_EXTERNS 12 | 13 | /* 14 | * Protects sbrk() calls. This avoids malloc races among threads, though it 15 | * does not protect against races with threads that call sbrk() directly. 16 | */ 17 | extern malloc_mutex_t dss_mtx; 18 | 19 | void *chunk_alloc_dss(size_t size, bool *zero); 20 | bool chunk_in_dss(void *chunk); 21 | bool chunk_dealloc_dss(void *chunk, size_t size); 22 | bool chunk_dss_boot(void); 23 | 24 | #endif /* JEMALLOC_H_EXTERNS */ 25 | /******************************************************************************/ 26 | #ifdef JEMALLOC_H_INLINES 27 | 28 | #endif /* JEMALLOC_H_INLINES */ 29 | /******************************************************************************/ 30 | #endif /* JEMALLOC_DSS */ 31 | -------------------------------------------------------------------------------- /deps/jemalloc/include/jemalloc/internal/chunk_mmap.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | #ifdef JEMALLOC_H_TYPES 3 | 4 | #endif /* JEMALLOC_H_TYPES */ 5 | /******************************************************************************/ 6 | #ifdef JEMALLOC_H_STRUCTS 7 | 8 | #endif /* JEMALLOC_H_STRUCTS */ 9 | /******************************************************************************/ 10 | #ifdef JEMALLOC_H_EXTERNS 11 | 12 | void *chunk_alloc_mmap(size_t size); 13 | void *chunk_alloc_mmap_noreserve(size_t size); 14 | void chunk_dealloc_mmap(void *chunk, size_t size); 15 | 16 | bool chunk_mmap_boot(void); 17 | 18 | #endif /* JEMALLOC_H_EXTERNS */ 19 | /******************************************************************************/ 20 | #ifdef JEMALLOC_H_INLINES 21 | 22 | #endif /* JEMALLOC_H_INLINES */ 23 | /******************************************************************************/ 24 | -------------------------------------------------------------------------------- /deps/jemalloc/include/jemalloc/internal/chunk_swap.h: -------------------------------------------------------------------------------- 1 | #ifdef JEMALLOC_SWAP 2 | /******************************************************************************/ 3 | #ifdef JEMALLOC_H_TYPES 4 | 5 | #endif /* JEMALLOC_H_TYPES */ 6 | /******************************************************************************/ 7 | #ifdef JEMALLOC_H_STRUCTS 8 | 9 | #endif /* JEMALLOC_H_STRUCTS */ 10 | /******************************************************************************/ 11 | #ifdef JEMALLOC_H_EXTERNS 12 | 13 | extern malloc_mutex_t swap_mtx; 14 | extern bool swap_enabled; 15 | extern bool swap_prezeroed; 16 | extern size_t swap_nfds; 17 | extern int *swap_fds; 18 | #ifdef JEMALLOC_STATS 19 | extern size_t swap_avail; 20 | #endif 21 | 22 | void *chunk_alloc_swap(size_t size, bool *zero); 23 | bool chunk_in_swap(void *chunk); 24 | bool chunk_dealloc_swap(void *chunk, size_t size); 25 | bool chunk_swap_enable(const int *fds, unsigned nfds, bool prezeroed); 26 | bool chunk_swap_boot(void); 27 | 28 | #endif /* JEMALLOC_H_EXTERNS */ 29 | /******************************************************************************/ 30 | #ifdef JEMALLOC_H_INLINES 31 | 32 | #endif /* JEMALLOC_H_INLINES */ 33 | /******************************************************************************/ 34 | #endif /* JEMALLOC_SWAP */ 35 | -------------------------------------------------------------------------------- /deps/jemalloc/include/jemalloc/internal/ckh.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | #ifdef JEMALLOC_H_TYPES 3 | 4 | typedef struct ckh_s ckh_t; 5 | typedef struct ckhc_s ckhc_t; 6 | 7 | /* Typedefs to allow easy function pointer passing. */ 8 | typedef void ckh_hash_t (const void *, unsigned, size_t *, size_t *); 9 | typedef bool ckh_keycomp_t (const void *, const void *); 10 | 11 | /* Maintain counters used to get an idea of performance. */ 12 | /* #define CKH_COUNT */ 13 | /* Print counter values in ckh_delete() (requires CKH_COUNT). */ 14 | /* #define CKH_VERBOSE */ 15 | 16 | /* 17 | * There are 2^LG_CKH_BUCKET_CELLS cells in each hash table bucket. Try to fit 18 | * one bucket per L1 cache line. 19 | */ 20 | #define LG_CKH_BUCKET_CELLS (LG_CACHELINE - LG_SIZEOF_PTR - 1) 21 | 22 | #endif /* JEMALLOC_H_TYPES */ 23 | /******************************************************************************/ 24 | #ifdef JEMALLOC_H_STRUCTS 25 | 26 | /* Hash table cell. */ 27 | struct ckhc_s { 28 | const void *key; 29 | const void *data; 30 | }; 31 | 32 | struct ckh_s { 33 | #ifdef JEMALLOC_DEBUG 34 | #define CKH_MAGIC 0x3af2489d 35 | uint32_t magic; 36 | #endif 37 | 38 | #ifdef CKH_COUNT 39 | /* Counters used to get an idea of performance. */ 40 | uint64_t ngrows; 41 | uint64_t nshrinks; 42 | uint64_t nshrinkfails; 43 | uint64_t ninserts; 44 | uint64_t nrelocs; 45 | #endif 46 | 47 | /* Used for pseudo-random number generation. */ 48 | #define CKH_A 1103515241 49 | #define CKH_C 12347 50 | uint32_t prn_state; 51 | 52 | /* Total number of items. */ 53 | size_t count; 54 | 55 | /* 56 | * Minimum and current number of hash table buckets. There are 57 | * 2^LG_CKH_BUCKET_CELLS cells per bucket. 58 | */ 59 | unsigned lg_minbuckets; 60 | unsigned lg_curbuckets; 61 | 62 | /* Hash and comparison functions. */ 63 | ckh_hash_t *hash; 64 | ckh_keycomp_t *keycomp; 65 | 66 | /* Hash table with 2^lg_curbuckets buckets. */ 67 | ckhc_t *tab; 68 | }; 69 | 70 | #endif /* JEMALLOC_H_STRUCTS */ 71 | /******************************************************************************/ 72 | #ifdef JEMALLOC_H_EXTERNS 73 | 74 | bool ckh_new(ckh_t *ckh, size_t minitems, ckh_hash_t *hash, 75 | ckh_keycomp_t *keycomp); 76 | void ckh_delete(ckh_t *ckh); 77 | size_t ckh_count(ckh_t *ckh); 78 | bool ckh_iter(ckh_t *ckh, size_t *tabind, void **key, void **data); 79 | bool ckh_insert(ckh_t *ckh, const void *key, const void *data); 80 | bool ckh_remove(ckh_t *ckh, const void *searchkey, void **key, 81 | void **data); 82 | bool ckh_search(ckh_t *ckh, const void *seachkey, void **key, void **data); 83 | void ckh_string_hash(const void *key, unsigned minbits, size_t *hash1, 84 | size_t *hash2); 85 | bool ckh_string_keycomp(const void *k1, const void *k2); 86 | void ckh_pointer_hash(const void *key, unsigned minbits, size_t *hash1, 87 | size_t *hash2); 88 | bool ckh_pointer_keycomp(const void *k1, const void *k2); 89 | 90 | #endif /* JEMALLOC_H_EXTERNS */ 91 | /******************************************************************************/ 92 | #ifdef JEMALLOC_H_INLINES 93 | 94 | #endif /* JEMALLOC_H_INLINES */ 95 | /******************************************************************************/ 96 | -------------------------------------------------------------------------------- /deps/jemalloc/include/jemalloc/internal/ctl.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | #ifdef JEMALLOC_H_TYPES 3 | 4 | typedef struct ctl_node_s ctl_node_t; 5 | typedef struct ctl_arena_stats_s ctl_arena_stats_t; 6 | typedef struct ctl_stats_s ctl_stats_t; 7 | 8 | #endif /* JEMALLOC_H_TYPES */ 9 | /******************************************************************************/ 10 | #ifdef JEMALLOC_H_STRUCTS 11 | 12 | struct ctl_node_s { 13 | bool named; 14 | union { 15 | struct { 16 | const char *name; 17 | /* If (nchildren == 0), this is a terminal node. */ 18 | unsigned nchildren; 19 | const ctl_node_t *children; 20 | } named; 21 | struct { 22 | const ctl_node_t *(*index)(const size_t *, size_t, 23 | size_t); 24 | } indexed; 25 | } u; 26 | int (*ctl)(const size_t *, size_t, void *, size_t *, void *, 27 | size_t); 28 | }; 29 | 30 | struct ctl_arena_stats_s { 31 | bool initialized; 32 | unsigned nthreads; 33 | size_t pactive; 34 | size_t pdirty; 35 | #ifdef JEMALLOC_STATS 36 | arena_stats_t astats; 37 | 38 | /* Aggregate stats for small size classes, based on bin stats. */ 39 | size_t allocated_small; 40 | uint64_t nmalloc_small; 41 | uint64_t ndalloc_small; 42 | uint64_t nrequests_small; 43 | 44 | malloc_bin_stats_t *bstats; /* nbins elements. */ 45 | malloc_large_stats_t *lstats; /* nlclasses elements. */ 46 | #endif 47 | }; 48 | 49 | struct ctl_stats_s { 50 | #ifdef JEMALLOC_STATS 51 | size_t allocated; 52 | size_t active; 53 | size_t mapped; 54 | struct { 55 | size_t current; /* stats_chunks.curchunks */ 56 | uint64_t total; /* stats_chunks.nchunks */ 57 | size_t high; /* stats_chunks.highchunks */ 58 | } chunks; 59 | struct { 60 | size_t allocated; /* huge_allocated */ 61 | uint64_t nmalloc; /* huge_nmalloc */ 62 | uint64_t ndalloc; /* huge_ndalloc */ 63 | } huge; 64 | #endif 65 | ctl_arena_stats_t *arenas; /* (narenas + 1) elements. */ 66 | #ifdef JEMALLOC_SWAP 67 | size_t swap_avail; 68 | #endif 69 | }; 70 | 71 | #endif /* JEMALLOC_H_STRUCTS */ 72 | /******************************************************************************/ 73 | #ifdef JEMALLOC_H_EXTERNS 74 | 75 | int ctl_byname(const char *name, void *oldp, size_t *oldlenp, void *newp, 76 | size_t newlen); 77 | int ctl_nametomib(const char *name, size_t *mibp, size_t *miblenp); 78 | 79 | int ctl_bymib(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, 80 | void *newp, size_t newlen); 81 | bool ctl_boot(void); 82 | 83 | #define xmallctl(name, oldp, oldlenp, newp, newlen) do { \ 84 | if (JEMALLOC_P(mallctl)(name, oldp, oldlenp, newp, newlen) \ 85 | != 0) { \ 86 | malloc_write(": Failure in xmallctl(\""); \ 87 | malloc_write(name); \ 88 | malloc_write("\", ...)\n"); \ 89 | abort(); \ 90 | } \ 91 | } while (0) 92 | 93 | #define xmallctlnametomib(name, mibp, miblenp) do { \ 94 | if (JEMALLOC_P(mallctlnametomib)(name, mibp, miblenp) != 0) { \ 95 | malloc_write( \ 96 | ": Failure in xmallctlnametomib(\""); \ 97 | malloc_write(name); \ 98 | malloc_write("\", ...)\n"); \ 99 | abort(); \ 100 | } \ 101 | } while (0) 102 | 103 | #define xmallctlbymib(mib, miblen, oldp, oldlenp, newp, newlen) do { \ 104 | if (JEMALLOC_P(mallctlbymib)(mib, miblen, oldp, oldlenp, newp, \ 105 | newlen) != 0) { \ 106 | malloc_write( \ 107 | ": Failure in xmallctlbymib()\n"); \ 108 | abort(); \ 109 | } \ 110 | } while (0) 111 | 112 | #endif /* JEMALLOC_H_EXTERNS */ 113 | /******************************************************************************/ 114 | #ifdef JEMALLOC_H_INLINES 115 | 116 | #endif /* JEMALLOC_H_INLINES */ 117 | /******************************************************************************/ 118 | 119 | -------------------------------------------------------------------------------- /deps/jemalloc/include/jemalloc/internal/extent.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | #ifdef JEMALLOC_H_TYPES 3 | 4 | typedef struct extent_node_s extent_node_t; 5 | 6 | #endif /* JEMALLOC_H_TYPES */ 7 | /******************************************************************************/ 8 | #ifdef JEMALLOC_H_STRUCTS 9 | 10 | /* Tree of extents. */ 11 | struct extent_node_s { 12 | #if (defined(JEMALLOC_SWAP) || defined(JEMALLOC_DSS)) 13 | /* Linkage for the size/address-ordered tree. */ 14 | rb_node(extent_node_t) link_szad; 15 | #endif 16 | 17 | /* Linkage for the address-ordered tree. */ 18 | rb_node(extent_node_t) link_ad; 19 | 20 | #ifdef JEMALLOC_PROF 21 | /* Profile counters, used for huge objects. */ 22 | prof_ctx_t *prof_ctx; 23 | #endif 24 | 25 | /* Pointer to the extent that this tree node is responsible for. */ 26 | void *addr; 27 | 28 | /* Total region size. */ 29 | size_t size; 30 | }; 31 | typedef rb_tree(extent_node_t) extent_tree_t; 32 | 33 | #endif /* JEMALLOC_H_STRUCTS */ 34 | /******************************************************************************/ 35 | #ifdef JEMALLOC_H_EXTERNS 36 | 37 | #if (defined(JEMALLOC_SWAP) || defined(JEMALLOC_DSS)) 38 | rb_proto(, extent_tree_szad_, extent_tree_t, extent_node_t) 39 | #endif 40 | 41 | rb_proto(, extent_tree_ad_, extent_tree_t, extent_node_t) 42 | 43 | #endif /* JEMALLOC_H_EXTERNS */ 44 | /******************************************************************************/ 45 | #ifdef JEMALLOC_H_INLINES 46 | 47 | #endif /* JEMALLOC_H_INLINES */ 48 | /******************************************************************************/ 49 | 50 | -------------------------------------------------------------------------------- /deps/jemalloc/include/jemalloc/internal/hash.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | #ifdef JEMALLOC_H_TYPES 3 | 4 | #endif /* JEMALLOC_H_TYPES */ 5 | /******************************************************************************/ 6 | #ifdef JEMALLOC_H_STRUCTS 7 | 8 | #endif /* JEMALLOC_H_STRUCTS */ 9 | /******************************************************************************/ 10 | #ifdef JEMALLOC_H_EXTERNS 11 | 12 | #endif /* JEMALLOC_H_EXTERNS */ 13 | /******************************************************************************/ 14 | #ifdef JEMALLOC_H_INLINES 15 | 16 | #ifndef JEMALLOC_ENABLE_INLINE 17 | uint64_t hash(const void *key, size_t len, uint64_t seed); 18 | #endif 19 | 20 | #if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_HASH_C_)) 21 | /* 22 | * The following hash function is based on MurmurHash64A(), placed into the 23 | * public domain by Austin Appleby. See http://murmurhash.googlepages.com/ for 24 | * details. 25 | */ 26 | JEMALLOC_INLINE uint64_t 27 | hash(const void *key, size_t len, uint64_t seed) 28 | { 29 | const uint64_t m = 0xc6a4a7935bd1e995LLU; 30 | const int r = 47; 31 | uint64_t h = seed ^ (len * m); 32 | const uint64_t *data = (const uint64_t *)key; 33 | const uint64_t *end = data + (len/8); 34 | const unsigned char *data2; 35 | 36 | assert(((uintptr_t)key & 0x7) == 0); 37 | 38 | while(data != end) { 39 | uint64_t k = *data++; 40 | 41 | k *= m; 42 | k ^= k >> r; 43 | k *= m; 44 | 45 | h ^= k; 46 | h *= m; 47 | } 48 | 49 | data2 = (const unsigned char *)data; 50 | switch(len & 7) { 51 | case 7: h ^= ((uint64_t)(data2[6])) << 48; 52 | case 6: h ^= ((uint64_t)(data2[5])) << 40; 53 | case 5: h ^= ((uint64_t)(data2[4])) << 32; 54 | case 4: h ^= ((uint64_t)(data2[3])) << 24; 55 | case 3: h ^= ((uint64_t)(data2[2])) << 16; 56 | case 2: h ^= ((uint64_t)(data2[1])) << 8; 57 | case 1: h ^= ((uint64_t)(data2[0])); 58 | h *= m; 59 | } 60 | 61 | h ^= h >> r; 62 | h *= m; 63 | h ^= h >> r; 64 | 65 | return (h); 66 | } 67 | #endif 68 | 69 | #endif /* JEMALLOC_H_INLINES */ 70 | /******************************************************************************/ 71 | -------------------------------------------------------------------------------- /deps/jemalloc/include/jemalloc/internal/huge.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | #ifdef JEMALLOC_H_TYPES 3 | 4 | #endif /* JEMALLOC_H_TYPES */ 5 | /******************************************************************************/ 6 | #ifdef JEMALLOC_H_STRUCTS 7 | 8 | #endif /* JEMALLOC_H_STRUCTS */ 9 | /******************************************************************************/ 10 | #ifdef JEMALLOC_H_EXTERNS 11 | 12 | #ifdef JEMALLOC_STATS 13 | /* Huge allocation statistics. */ 14 | extern uint64_t huge_nmalloc; 15 | extern uint64_t huge_ndalloc; 16 | extern size_t huge_allocated; 17 | #endif 18 | 19 | /* Protects chunk-related data structures. */ 20 | extern malloc_mutex_t huge_mtx; 21 | 22 | void *huge_malloc(size_t size, bool zero); 23 | void *huge_palloc(size_t size, size_t alignment, bool zero); 24 | void *huge_ralloc_no_move(void *ptr, size_t oldsize, size_t size, 25 | size_t extra); 26 | void *huge_ralloc(void *ptr, size_t oldsize, size_t size, size_t extra, 27 | size_t alignment, bool zero); 28 | void huge_dalloc(void *ptr, bool unmap); 29 | size_t huge_salloc(const void *ptr); 30 | #ifdef JEMALLOC_PROF 31 | prof_ctx_t *huge_prof_ctx_get(const void *ptr); 32 | void huge_prof_ctx_set(const void *ptr, prof_ctx_t *ctx); 33 | #endif 34 | bool huge_boot(void); 35 | 36 | #endif /* JEMALLOC_H_EXTERNS */ 37 | /******************************************************************************/ 38 | #ifdef JEMALLOC_H_INLINES 39 | 40 | #endif /* JEMALLOC_H_INLINES */ 41 | /******************************************************************************/ 42 | -------------------------------------------------------------------------------- /deps/jemalloc/include/jemalloc/internal/mb.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | #ifdef JEMALLOC_H_TYPES 3 | 4 | #endif /* JEMALLOC_H_TYPES */ 5 | /******************************************************************************/ 6 | #ifdef JEMALLOC_H_STRUCTS 7 | 8 | #endif /* JEMALLOC_H_STRUCTS */ 9 | /******************************************************************************/ 10 | #ifdef JEMALLOC_H_EXTERNS 11 | 12 | #endif /* JEMALLOC_H_EXTERNS */ 13 | /******************************************************************************/ 14 | #ifdef JEMALLOC_H_INLINES 15 | 16 | #ifndef JEMALLOC_ENABLE_INLINE 17 | void mb_write(void); 18 | #endif 19 | 20 | #if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_MB_C_)) 21 | #ifdef __i386__ 22 | /* 23 | * According to the Intel Architecture Software Developer's Manual, current 24 | * processors execute instructions in order from the perspective of other 25 | * processors in a multiprocessor system, but 1) Intel reserves the right to 26 | * change that, and 2) the compiler's optimizer could re-order instructions if 27 | * there weren't some form of barrier. Therefore, even if running on an 28 | * architecture that does not need memory barriers (everything through at least 29 | * i686), an "optimizer barrier" is necessary. 30 | */ 31 | JEMALLOC_INLINE void 32 | mb_write(void) 33 | { 34 | 35 | # if 0 36 | /* This is a true memory barrier. */ 37 | asm volatile ("pusha;" 38 | "xor %%eax,%%eax;" 39 | "cpuid;" 40 | "popa;" 41 | : /* Outputs. */ 42 | : /* Inputs. */ 43 | : "memory" /* Clobbers. */ 44 | ); 45 | #else 46 | /* 47 | * This is hopefully enough to keep the compiler from reordering 48 | * instructions around this one. 49 | */ 50 | asm volatile ("nop;" 51 | : /* Outputs. */ 52 | : /* Inputs. */ 53 | : "memory" /* Clobbers. */ 54 | ); 55 | #endif 56 | } 57 | #elif (defined(__amd64_) || defined(__x86_64__)) 58 | JEMALLOC_INLINE void 59 | mb_write(void) 60 | { 61 | 62 | asm volatile ("sfence" 63 | : /* Outputs. */ 64 | : /* Inputs. */ 65 | : "memory" /* Clobbers. */ 66 | ); 67 | } 68 | #elif defined(__powerpc__) 69 | JEMALLOC_INLINE void 70 | mb_write(void) 71 | { 72 | 73 | asm volatile ("eieio" 74 | : /* Outputs. */ 75 | : /* Inputs. */ 76 | : "memory" /* Clobbers. */ 77 | ); 78 | } 79 | #elif defined(__sparc64__) 80 | JEMALLOC_INLINE void 81 | mb_write(void) 82 | { 83 | 84 | asm volatile ("membar #StoreStore" 85 | : /* Outputs. */ 86 | : /* Inputs. */ 87 | : "memory" /* Clobbers. */ 88 | ); 89 | } 90 | #else 91 | /* 92 | * This is much slower than a simple memory barrier, but the semantics of mutex 93 | * unlock make this work. 94 | */ 95 | JEMALLOC_INLINE void 96 | mb_write(void) 97 | { 98 | malloc_mutex_t mtx; 99 | 100 | malloc_mutex_init(&mtx); 101 | malloc_mutex_lock(&mtx); 102 | malloc_mutex_unlock(&mtx); 103 | } 104 | #endif 105 | #endif 106 | 107 | #endif /* JEMALLOC_H_INLINES */ 108 | /******************************************************************************/ 109 | -------------------------------------------------------------------------------- /deps/jemalloc/include/jemalloc/internal/mutex.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | #ifdef JEMALLOC_H_TYPES 3 | 4 | #ifdef JEMALLOC_OSSPIN 5 | typedef OSSpinLock malloc_mutex_t; 6 | #else 7 | typedef pthread_mutex_t malloc_mutex_t; 8 | #endif 9 | 10 | #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP 11 | # define MALLOC_MUTEX_INITIALIZER PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP 12 | #else 13 | # define MALLOC_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER 14 | #endif 15 | 16 | #endif /* JEMALLOC_H_TYPES */ 17 | /******************************************************************************/ 18 | #ifdef JEMALLOC_H_STRUCTS 19 | 20 | #endif /* JEMALLOC_H_STRUCTS */ 21 | /******************************************************************************/ 22 | #ifdef JEMALLOC_H_EXTERNS 23 | 24 | #ifdef JEMALLOC_LAZY_LOCK 25 | extern bool isthreaded; 26 | #else 27 | # define isthreaded true 28 | #endif 29 | 30 | bool malloc_mutex_init(malloc_mutex_t *mutex); 31 | void malloc_mutex_destroy(malloc_mutex_t *mutex); 32 | 33 | #endif /* JEMALLOC_H_EXTERNS */ 34 | /******************************************************************************/ 35 | #ifdef JEMALLOC_H_INLINES 36 | 37 | #ifndef JEMALLOC_ENABLE_INLINE 38 | void malloc_mutex_lock(malloc_mutex_t *mutex); 39 | bool malloc_mutex_trylock(malloc_mutex_t *mutex); 40 | void malloc_mutex_unlock(malloc_mutex_t *mutex); 41 | #endif 42 | 43 | #if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_MUTEX_C_)) 44 | JEMALLOC_INLINE void 45 | malloc_mutex_lock(malloc_mutex_t *mutex) 46 | { 47 | 48 | if (isthreaded) { 49 | #ifdef JEMALLOC_OSSPIN 50 | OSSpinLockLock(mutex); 51 | #else 52 | pthread_mutex_lock(mutex); 53 | #endif 54 | } 55 | } 56 | 57 | JEMALLOC_INLINE bool 58 | malloc_mutex_trylock(malloc_mutex_t *mutex) 59 | { 60 | 61 | if (isthreaded) { 62 | #ifdef JEMALLOC_OSSPIN 63 | return (OSSpinLockTry(mutex) == false); 64 | #else 65 | return (pthread_mutex_trylock(mutex) != 0); 66 | #endif 67 | } else 68 | return (false); 69 | } 70 | 71 | JEMALLOC_INLINE void 72 | malloc_mutex_unlock(malloc_mutex_t *mutex) 73 | { 74 | 75 | if (isthreaded) { 76 | #ifdef JEMALLOC_OSSPIN 77 | OSSpinLockUnlock(mutex); 78 | #else 79 | pthread_mutex_unlock(mutex); 80 | #endif 81 | } 82 | } 83 | #endif 84 | 85 | #endif /* JEMALLOC_H_INLINES */ 86 | /******************************************************************************/ 87 | -------------------------------------------------------------------------------- /deps/jemalloc/include/jemalloc/internal/ql.h: -------------------------------------------------------------------------------- 1 | /* 2 | * List definitions. 3 | */ 4 | #define ql_head(a_type) \ 5 | struct { \ 6 | a_type *qlh_first; \ 7 | } 8 | 9 | #define ql_head_initializer(a_head) {NULL} 10 | 11 | #define ql_elm(a_type) qr(a_type) 12 | 13 | /* List functions. */ 14 | #define ql_new(a_head) do { \ 15 | (a_head)->qlh_first = NULL; \ 16 | } while (0) 17 | 18 | #define ql_elm_new(a_elm, a_field) qr_new((a_elm), a_field) 19 | 20 | #define ql_first(a_head) ((a_head)->qlh_first) 21 | 22 | #define ql_last(a_head, a_field) \ 23 | ((ql_first(a_head) != NULL) \ 24 | ? qr_prev(ql_first(a_head), a_field) : NULL) 25 | 26 | #define ql_next(a_head, a_elm, a_field) \ 27 | ((ql_last(a_head, a_field) != (a_elm)) \ 28 | ? qr_next((a_elm), a_field) : NULL) 29 | 30 | #define ql_prev(a_head, a_elm, a_field) \ 31 | ((ql_first(a_head) != (a_elm)) ? qr_prev((a_elm), a_field) \ 32 | : NULL) 33 | 34 | #define ql_before_insert(a_head, a_qlelm, a_elm, a_field) do { \ 35 | qr_before_insert((a_qlelm), (a_elm), a_field); \ 36 | if (ql_first(a_head) == (a_qlelm)) { \ 37 | ql_first(a_head) = (a_elm); \ 38 | } \ 39 | } while (0) 40 | 41 | #define ql_after_insert(a_qlelm, a_elm, a_field) \ 42 | qr_after_insert((a_qlelm), (a_elm), a_field) 43 | 44 | #define ql_head_insert(a_head, a_elm, a_field) do { \ 45 | if (ql_first(a_head) != NULL) { \ 46 | qr_before_insert(ql_first(a_head), (a_elm), a_field); \ 47 | } \ 48 | ql_first(a_head) = (a_elm); \ 49 | } while (0) 50 | 51 | #define ql_tail_insert(a_head, a_elm, a_field) do { \ 52 | if (ql_first(a_head) != NULL) { \ 53 | qr_before_insert(ql_first(a_head), (a_elm), a_field); \ 54 | } \ 55 | ql_first(a_head) = qr_next((a_elm), a_field); \ 56 | } while (0) 57 | 58 | #define ql_remove(a_head, a_elm, a_field) do { \ 59 | if (ql_first(a_head) == (a_elm)) { \ 60 | ql_first(a_head) = qr_next(ql_first(a_head), a_field); \ 61 | } \ 62 | if (ql_first(a_head) != (a_elm)) { \ 63 | qr_remove((a_elm), a_field); \ 64 | } else { \ 65 | ql_first(a_head) = NULL; \ 66 | } \ 67 | } while (0) 68 | 69 | #define ql_head_remove(a_head, a_type, a_field) do { \ 70 | a_type *t = ql_first(a_head); \ 71 | ql_remove((a_head), t, a_field); \ 72 | } while (0) 73 | 74 | #define ql_tail_remove(a_head, a_type, a_field) do { \ 75 | a_type *t = ql_last(a_head, a_field); \ 76 | ql_remove((a_head), t, a_field); \ 77 | } while (0) 78 | 79 | #define ql_foreach(a_var, a_head, a_field) \ 80 | qr_foreach((a_var), ql_first(a_head), a_field) 81 | 82 | #define ql_reverse_foreach(a_var, a_head, a_field) \ 83 | qr_reverse_foreach((a_var), ql_first(a_head), a_field) 84 | -------------------------------------------------------------------------------- /deps/jemalloc/include/jemalloc/internal/qr.h: -------------------------------------------------------------------------------- 1 | /* Ring definitions. */ 2 | #define qr(a_type) \ 3 | struct { \ 4 | a_type *qre_next; \ 5 | a_type *qre_prev; \ 6 | } 7 | 8 | /* Ring functions. */ 9 | #define qr_new(a_qr, a_field) do { \ 10 | (a_qr)->a_field.qre_next = (a_qr); \ 11 | (a_qr)->a_field.qre_prev = (a_qr); \ 12 | } while (0) 13 | 14 | #define qr_next(a_qr, a_field) ((a_qr)->a_field.qre_next) 15 | 16 | #define qr_prev(a_qr, a_field) ((a_qr)->a_field.qre_prev) 17 | 18 | #define qr_before_insert(a_qrelm, a_qr, a_field) do { \ 19 | (a_qr)->a_field.qre_prev = (a_qrelm)->a_field.qre_prev; \ 20 | (a_qr)->a_field.qre_next = (a_qrelm); \ 21 | (a_qr)->a_field.qre_prev->a_field.qre_next = (a_qr); \ 22 | (a_qrelm)->a_field.qre_prev = (a_qr); \ 23 | } while (0) 24 | 25 | #define qr_after_insert(a_qrelm, a_qr, a_field) \ 26 | do \ 27 | { \ 28 | (a_qr)->a_field.qre_next = (a_qrelm)->a_field.qre_next; \ 29 | (a_qr)->a_field.qre_prev = (a_qrelm); \ 30 | (a_qr)->a_field.qre_next->a_field.qre_prev = (a_qr); \ 31 | (a_qrelm)->a_field.qre_next = (a_qr); \ 32 | } while (0) 33 | 34 | #define qr_meld(a_qr_a, a_qr_b, a_field) do { \ 35 | void *t; \ 36 | (a_qr_a)->a_field.qre_prev->a_field.qre_next = (a_qr_b); \ 37 | (a_qr_b)->a_field.qre_prev->a_field.qre_next = (a_qr_a); \ 38 | t = (a_qr_a)->a_field.qre_prev; \ 39 | (a_qr_a)->a_field.qre_prev = (a_qr_b)->a_field.qre_prev; \ 40 | (a_qr_b)->a_field.qre_prev = t; \ 41 | } while (0) 42 | 43 | /* qr_meld() and qr_split() are functionally equivalent, so there's no need to 44 | * have two copies of the code. */ 45 | #define qr_split(a_qr_a, a_qr_b, a_field) \ 46 | qr_meld((a_qr_a), (a_qr_b), a_field) 47 | 48 | #define qr_remove(a_qr, a_field) do { \ 49 | (a_qr)->a_field.qre_prev->a_field.qre_next \ 50 | = (a_qr)->a_field.qre_next; \ 51 | (a_qr)->a_field.qre_next->a_field.qre_prev \ 52 | = (a_qr)->a_field.qre_prev; \ 53 | (a_qr)->a_field.qre_next = (a_qr); \ 54 | (a_qr)->a_field.qre_prev = (a_qr); \ 55 | } while (0) 56 | 57 | #define qr_foreach(var, a_qr, a_field) \ 58 | for ((var) = (a_qr); \ 59 | (var) != NULL; \ 60 | (var) = (((var)->a_field.qre_next != (a_qr)) \ 61 | ? (var)->a_field.qre_next : NULL)) 62 | 63 | #define qr_reverse_foreach(var, a_qr, a_field) \ 64 | for ((var) = ((a_qr) != NULL) ? qr_prev(a_qr, a_field) : NULL; \ 65 | (var) != NULL; \ 66 | (var) = (((var) != (a_qr)) \ 67 | ? (var)->a_field.qre_prev : NULL)) 68 | -------------------------------------------------------------------------------- /deps/jemalloc/include/jemalloc/internal/zone.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_ZONE 2 | # error "This source file is for zones on Darwin (OS X)." 3 | #endif 4 | /******************************************************************************/ 5 | #ifdef JEMALLOC_H_TYPES 6 | 7 | #endif /* JEMALLOC_H_TYPES */ 8 | /******************************************************************************/ 9 | #ifdef JEMALLOC_H_STRUCTS 10 | 11 | #endif /* JEMALLOC_H_STRUCTS */ 12 | /******************************************************************************/ 13 | #ifdef JEMALLOC_H_EXTERNS 14 | 15 | malloc_zone_t *create_zone(void); 16 | void szone2ozone(malloc_zone_t *zone); 17 | 18 | #endif /* JEMALLOC_H_EXTERNS */ 19 | /******************************************************************************/ 20 | #ifdef JEMALLOC_H_INLINES 21 | 22 | #endif /* JEMALLOC_H_INLINES */ 23 | /******************************************************************************/ 24 | -------------------------------------------------------------------------------- /deps/jemalloc/include/jemalloc/jemalloc.h.in: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_H_ 2 | #define JEMALLOC_H_ 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif 6 | 7 | #include 8 | #include 9 | 10 | #define JEMALLOC_VERSION "@jemalloc_version@" 11 | #define JEMALLOC_VERSION_MAJOR @jemalloc_version_major@ 12 | #define JEMALLOC_VERSION_MINOR @jemalloc_version_minor@ 13 | #define JEMALLOC_VERSION_BUGFIX @jemalloc_version_bugfix@ 14 | #define JEMALLOC_VERSION_NREV @jemalloc_version_nrev@ 15 | #define JEMALLOC_VERSION_GID "@jemalloc_version_gid@" 16 | 17 | #include "jemalloc_defs@install_suffix@.h" 18 | #ifndef JEMALLOC_P 19 | # define JEMALLOC_P(s) s 20 | #endif 21 | 22 | #define ALLOCM_LG_ALIGN(la) (la) 23 | #if LG_SIZEOF_PTR == 2 24 | #define ALLOCM_ALIGN(a) (ffs(a)-1) 25 | #else 26 | #define ALLOCM_ALIGN(a) ((a < (size_t)INT_MAX) ? ffs(a)-1 : ffs(a>>32)+31) 27 | #endif 28 | #define ALLOCM_ZERO ((int)0x40) 29 | #define ALLOCM_NO_MOVE ((int)0x80) 30 | 31 | #define ALLOCM_SUCCESS 0 32 | #define ALLOCM_ERR_OOM 1 33 | #define ALLOCM_ERR_NOT_MOVED 2 34 | 35 | extern const char *JEMALLOC_P(malloc_conf); 36 | extern void (*JEMALLOC_P(malloc_message))(void *, const char *); 37 | 38 | void *JEMALLOC_P(malloc)(size_t size) JEMALLOC_ATTR(malloc); 39 | void *JEMALLOC_P(calloc)(size_t num, size_t size) JEMALLOC_ATTR(malloc); 40 | int JEMALLOC_P(posix_memalign)(void **memptr, size_t alignment, size_t size) 41 | JEMALLOC_ATTR(nonnull(1)); 42 | void *JEMALLOC_P(realloc)(void *ptr, size_t size); 43 | void JEMALLOC_P(free)(void *ptr); 44 | 45 | size_t JEMALLOC_P(malloc_usable_size)(const void *ptr); 46 | void JEMALLOC_P(malloc_stats_print)(void (*write_cb)(void *, const char *), 47 | void *cbopaque, const char *opts); 48 | int JEMALLOC_P(mallctl)(const char *name, void *oldp, size_t *oldlenp, 49 | void *newp, size_t newlen); 50 | int JEMALLOC_P(mallctlnametomib)(const char *name, size_t *mibp, 51 | size_t *miblenp); 52 | int JEMALLOC_P(mallctlbymib)(const size_t *mib, size_t miblen, void *oldp, 53 | size_t *oldlenp, void *newp, size_t newlen); 54 | 55 | int JEMALLOC_P(allocm)(void **ptr, size_t *rsize, size_t size, int flags) 56 | JEMALLOC_ATTR(nonnull(1)); 57 | int JEMALLOC_P(rallocm)(void **ptr, size_t *rsize, size_t size, 58 | size_t extra, int flags) JEMALLOC_ATTR(nonnull(1)); 59 | int JEMALLOC_P(sallocm)(const void *ptr, size_t *rsize, int flags) 60 | JEMALLOC_ATTR(nonnull(1)); 61 | int JEMALLOC_P(dallocm)(void *ptr, int flags) JEMALLOC_ATTR(nonnull(1)); 62 | 63 | #ifdef __cplusplus 64 | }; 65 | #endif 66 | #endif /* JEMALLOC_H_ */ 67 | -------------------------------------------------------------------------------- /deps/jemalloc/src/atomic.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_ATOMIC_C_ 2 | #include "jemalloc/internal/jemalloc_internal.h" 3 | -------------------------------------------------------------------------------- /deps/jemalloc/src/base.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_BASE_C_ 2 | #include "jemalloc/internal/jemalloc_internal.h" 3 | 4 | /******************************************************************************/ 5 | /* Data. */ 6 | 7 | malloc_mutex_t base_mtx; 8 | 9 | /* 10 | * Current pages that are being used for internal memory allocations. These 11 | * pages are carved up in cacheline-size quanta, so that there is no chance of 12 | * false cache line sharing. 13 | */ 14 | static void *base_pages; 15 | static void *base_next_addr; 16 | static void *base_past_addr; /* Addr immediately past base_pages. */ 17 | static extent_node_t *base_nodes; 18 | 19 | /******************************************************************************/ 20 | /* Function prototypes for non-inline static functions. */ 21 | 22 | static bool base_pages_alloc(size_t minsize); 23 | 24 | /******************************************************************************/ 25 | 26 | static bool 27 | base_pages_alloc(size_t minsize) 28 | { 29 | size_t csize; 30 | bool zero; 31 | 32 | assert(minsize != 0); 33 | csize = CHUNK_CEILING(minsize); 34 | zero = false; 35 | base_pages = chunk_alloc(csize, true, &zero); 36 | if (base_pages == NULL) 37 | return (true); 38 | base_next_addr = base_pages; 39 | base_past_addr = (void *)((uintptr_t)base_pages + csize); 40 | 41 | return (false); 42 | } 43 | 44 | void * 45 | base_alloc(size_t size) 46 | { 47 | void *ret; 48 | size_t csize; 49 | 50 | /* Round size up to nearest multiple of the cacheline size. */ 51 | csize = CACHELINE_CEILING(size); 52 | 53 | malloc_mutex_lock(&base_mtx); 54 | /* Make sure there's enough space for the allocation. */ 55 | if ((uintptr_t)base_next_addr + csize > (uintptr_t)base_past_addr) { 56 | if (base_pages_alloc(csize)) { 57 | malloc_mutex_unlock(&base_mtx); 58 | return (NULL); 59 | } 60 | } 61 | /* Allocate. */ 62 | ret = base_next_addr; 63 | base_next_addr = (void *)((uintptr_t)base_next_addr + csize); 64 | malloc_mutex_unlock(&base_mtx); 65 | 66 | return (ret); 67 | } 68 | 69 | extent_node_t * 70 | base_node_alloc(void) 71 | { 72 | extent_node_t *ret; 73 | 74 | malloc_mutex_lock(&base_mtx); 75 | if (base_nodes != NULL) { 76 | ret = base_nodes; 77 | base_nodes = *(extent_node_t **)ret; 78 | malloc_mutex_unlock(&base_mtx); 79 | } else { 80 | malloc_mutex_unlock(&base_mtx); 81 | ret = (extent_node_t *)base_alloc(sizeof(extent_node_t)); 82 | } 83 | 84 | return (ret); 85 | } 86 | 87 | void 88 | base_node_dealloc(extent_node_t *node) 89 | { 90 | 91 | malloc_mutex_lock(&base_mtx); 92 | *(extent_node_t **)node = base_nodes; 93 | base_nodes = node; 94 | malloc_mutex_unlock(&base_mtx); 95 | } 96 | 97 | bool 98 | base_boot(void) 99 | { 100 | 101 | base_nodes = NULL; 102 | if (malloc_mutex_init(&base_mtx)) 103 | return (true); 104 | 105 | return (false); 106 | } 107 | -------------------------------------------------------------------------------- /deps/jemalloc/src/bitmap.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_BITMAP_C_ 2 | #include "jemalloc/internal/jemalloc_internal.h" 3 | 4 | /******************************************************************************/ 5 | /* Function prototypes for non-inline static functions. */ 6 | 7 | static size_t bits2groups(size_t nbits); 8 | 9 | /******************************************************************************/ 10 | 11 | static size_t 12 | bits2groups(size_t nbits) 13 | { 14 | 15 | return ((nbits >> LG_BITMAP_GROUP_NBITS) + 16 | !!(nbits & BITMAP_GROUP_NBITS_MASK)); 17 | } 18 | 19 | void 20 | bitmap_info_init(bitmap_info_t *binfo, size_t nbits) 21 | { 22 | unsigned i; 23 | size_t group_count; 24 | 25 | assert(nbits > 0); 26 | assert(nbits <= (ZU(1) << LG_BITMAP_MAXBITS)); 27 | 28 | /* 29 | * Compute the number of groups necessary to store nbits bits, and 30 | * progressively work upward through the levels until reaching a level 31 | * that requires only one group. 32 | */ 33 | binfo->levels[0].group_offset = 0; 34 | group_count = bits2groups(nbits); 35 | for (i = 1; group_count > 1; i++) { 36 | assert(i < BITMAP_MAX_LEVELS); 37 | binfo->levels[i].group_offset = binfo->levels[i-1].group_offset 38 | + group_count; 39 | group_count = bits2groups(group_count); 40 | } 41 | binfo->levels[i].group_offset = binfo->levels[i-1].group_offset 42 | + group_count; 43 | binfo->nlevels = i; 44 | binfo->nbits = nbits; 45 | } 46 | 47 | size_t 48 | bitmap_info_ngroups(const bitmap_info_t *binfo) 49 | { 50 | 51 | return (binfo->levels[binfo->nlevels].group_offset << LG_SIZEOF_BITMAP); 52 | } 53 | 54 | size_t 55 | bitmap_size(size_t nbits) 56 | { 57 | bitmap_info_t binfo; 58 | 59 | bitmap_info_init(&binfo, nbits); 60 | return (bitmap_info_ngroups(&binfo)); 61 | } 62 | 63 | void 64 | bitmap_init(bitmap_t *bitmap, const bitmap_info_t *binfo) 65 | { 66 | size_t extra; 67 | unsigned i; 68 | 69 | /* 70 | * Bits are actually inverted with regard to the external bitmap 71 | * interface, so the bitmap starts out with all 1 bits, except for 72 | * trailing unused bits (if any). Note that each group uses bit 0 to 73 | * correspond to the first logical bit in the group, so extra bits 74 | * are the most significant bits of the last group. 75 | */ 76 | memset(bitmap, 0xffU, binfo->levels[binfo->nlevels].group_offset << 77 | LG_SIZEOF_BITMAP); 78 | extra = (BITMAP_GROUP_NBITS - (binfo->nbits & BITMAP_GROUP_NBITS_MASK)) 79 | & BITMAP_GROUP_NBITS_MASK; 80 | if (extra != 0) 81 | bitmap[binfo->levels[1].group_offset - 1] >>= extra; 82 | for (i = 1; i < binfo->nlevels; i++) { 83 | size_t group_count = binfo->levels[i].group_offset - 84 | binfo->levels[i-1].group_offset; 85 | extra = (BITMAP_GROUP_NBITS - (group_count & 86 | BITMAP_GROUP_NBITS_MASK)) & BITMAP_GROUP_NBITS_MASK; 87 | if (extra != 0) 88 | bitmap[binfo->levels[i+1].group_offset - 1] >>= extra; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /deps/jemalloc/src/chunk.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_CHUNK_C_ 2 | #include "jemalloc/internal/jemalloc_internal.h" 3 | 4 | /******************************************************************************/ 5 | /* Data. */ 6 | 7 | size_t opt_lg_chunk = LG_CHUNK_DEFAULT; 8 | #ifdef JEMALLOC_SWAP 9 | bool opt_overcommit = true; 10 | #endif 11 | 12 | #if (defined(JEMALLOC_STATS) || defined(JEMALLOC_PROF)) 13 | malloc_mutex_t chunks_mtx; 14 | chunk_stats_t stats_chunks; 15 | #endif 16 | 17 | #ifdef JEMALLOC_IVSALLOC 18 | rtree_t *chunks_rtree; 19 | #endif 20 | 21 | /* Various chunk-related settings. */ 22 | size_t chunksize; 23 | size_t chunksize_mask; /* (chunksize - 1). */ 24 | size_t chunk_npages; 25 | size_t map_bias; 26 | size_t arena_maxclass; /* Max size class for arenas. */ 27 | 28 | /******************************************************************************/ 29 | 30 | /* 31 | * If the caller specifies (*zero == false), it is still possible to receive 32 | * zeroed memory, in which case *zero is toggled to true. arena_chunk_alloc() 33 | * takes advantage of this to avoid demanding zeroed chunks, but taking 34 | * advantage of them if they are returned. 35 | */ 36 | void * 37 | chunk_alloc(size_t size, bool base, bool *zero) 38 | { 39 | void *ret; 40 | 41 | assert(size != 0); 42 | assert((size & chunksize_mask) == 0); 43 | 44 | #ifdef JEMALLOC_SWAP 45 | if (swap_enabled) { 46 | ret = chunk_alloc_swap(size, zero); 47 | if (ret != NULL) 48 | goto RETURN; 49 | } 50 | 51 | if (swap_enabled == false || opt_overcommit) { 52 | #endif 53 | #ifdef JEMALLOC_DSS 54 | ret = chunk_alloc_dss(size, zero); 55 | if (ret != NULL) 56 | goto RETURN; 57 | #endif 58 | ret = chunk_alloc_mmap(size); 59 | if (ret != NULL) { 60 | *zero = true; 61 | goto RETURN; 62 | } 63 | #ifdef JEMALLOC_SWAP 64 | } 65 | #endif 66 | 67 | /* All strategies for allocation failed. */ 68 | ret = NULL; 69 | RETURN: 70 | #ifdef JEMALLOC_IVSALLOC 71 | if (base == false && ret != NULL) { 72 | if (rtree_set(chunks_rtree, (uintptr_t)ret, ret)) { 73 | chunk_dealloc(ret, size, true); 74 | return (NULL); 75 | } 76 | } 77 | #endif 78 | #if (defined(JEMALLOC_STATS) || defined(JEMALLOC_PROF)) 79 | if (ret != NULL) { 80 | # ifdef JEMALLOC_PROF 81 | bool gdump; 82 | # endif 83 | malloc_mutex_lock(&chunks_mtx); 84 | # ifdef JEMALLOC_STATS 85 | stats_chunks.nchunks += (size / chunksize); 86 | # endif 87 | stats_chunks.curchunks += (size / chunksize); 88 | if (stats_chunks.curchunks > stats_chunks.highchunks) { 89 | stats_chunks.highchunks = stats_chunks.curchunks; 90 | # ifdef JEMALLOC_PROF 91 | gdump = true; 92 | # endif 93 | } 94 | # ifdef JEMALLOC_PROF 95 | else 96 | gdump = false; 97 | # endif 98 | malloc_mutex_unlock(&chunks_mtx); 99 | # ifdef JEMALLOC_PROF 100 | if (opt_prof && opt_prof_gdump && gdump) 101 | prof_gdump(); 102 | # endif 103 | } 104 | #endif 105 | 106 | assert(CHUNK_ADDR2BASE(ret) == ret); 107 | return (ret); 108 | } 109 | 110 | void 111 | chunk_dealloc(void *chunk, size_t size, bool unmap) 112 | { 113 | 114 | assert(chunk != NULL); 115 | assert(CHUNK_ADDR2BASE(chunk) == chunk); 116 | assert(size != 0); 117 | assert((size & chunksize_mask) == 0); 118 | 119 | #ifdef JEMALLOC_IVSALLOC 120 | rtree_set(chunks_rtree, (uintptr_t)chunk, NULL); 121 | #endif 122 | #if (defined(JEMALLOC_STATS) || defined(JEMALLOC_PROF)) 123 | malloc_mutex_lock(&chunks_mtx); 124 | stats_chunks.curchunks -= (size / chunksize); 125 | malloc_mutex_unlock(&chunks_mtx); 126 | #endif 127 | 128 | if (unmap) { 129 | #ifdef JEMALLOC_SWAP 130 | if (swap_enabled && chunk_dealloc_swap(chunk, size) == false) 131 | return; 132 | #endif 133 | #ifdef JEMALLOC_DSS 134 | if (chunk_dealloc_dss(chunk, size) == false) 135 | return; 136 | #endif 137 | chunk_dealloc_mmap(chunk, size); 138 | } 139 | } 140 | 141 | bool 142 | chunk_boot(void) 143 | { 144 | 145 | /* Set variables according to the value of opt_lg_chunk. */ 146 | chunksize = (ZU(1) << opt_lg_chunk); 147 | assert(chunksize >= PAGE_SIZE); 148 | chunksize_mask = chunksize - 1; 149 | chunk_npages = (chunksize >> PAGE_SHIFT); 150 | 151 | #if (defined(JEMALLOC_STATS) || defined(JEMALLOC_PROF)) 152 | if (malloc_mutex_init(&chunks_mtx)) 153 | return (true); 154 | memset(&stats_chunks, 0, sizeof(chunk_stats_t)); 155 | #endif 156 | #ifdef JEMALLOC_SWAP 157 | if (chunk_swap_boot()) 158 | return (true); 159 | #endif 160 | if (chunk_mmap_boot()) 161 | return (true); 162 | #ifdef JEMALLOC_DSS 163 | if (chunk_dss_boot()) 164 | return (true); 165 | #endif 166 | #ifdef JEMALLOC_IVSALLOC 167 | chunks_rtree = rtree_new((ZU(1) << (LG_SIZEOF_PTR+3)) - opt_lg_chunk); 168 | if (chunks_rtree == NULL) 169 | return (true); 170 | #endif 171 | 172 | return (false); 173 | } 174 | -------------------------------------------------------------------------------- /deps/jemalloc/src/extent.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_EXTENT_C_ 2 | #include "jemalloc/internal/jemalloc_internal.h" 3 | 4 | /******************************************************************************/ 5 | 6 | #if (defined(JEMALLOC_SWAP) || defined(JEMALLOC_DSS)) 7 | static inline int 8 | extent_szad_comp(extent_node_t *a, extent_node_t *b) 9 | { 10 | int ret; 11 | size_t a_size = a->size; 12 | size_t b_size = b->size; 13 | 14 | ret = (a_size > b_size) - (a_size < b_size); 15 | if (ret == 0) { 16 | uintptr_t a_addr = (uintptr_t)a->addr; 17 | uintptr_t b_addr = (uintptr_t)b->addr; 18 | 19 | ret = (a_addr > b_addr) - (a_addr < b_addr); 20 | } 21 | 22 | return (ret); 23 | } 24 | 25 | /* Generate red-black tree functions. */ 26 | rb_gen(, extent_tree_szad_, extent_tree_t, extent_node_t, link_szad, 27 | extent_szad_comp) 28 | #endif 29 | 30 | static inline int 31 | extent_ad_comp(extent_node_t *a, extent_node_t *b) 32 | { 33 | uintptr_t a_addr = (uintptr_t)a->addr; 34 | uintptr_t b_addr = (uintptr_t)b->addr; 35 | 36 | return ((a_addr > b_addr) - (a_addr < b_addr)); 37 | } 38 | 39 | /* Generate red-black tree functions. */ 40 | rb_gen(, extent_tree_ad_, extent_tree_t, extent_node_t, link_ad, 41 | extent_ad_comp) 42 | -------------------------------------------------------------------------------- /deps/jemalloc/src/hash.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_HASH_C_ 2 | #include "jemalloc/internal/jemalloc_internal.h" 3 | -------------------------------------------------------------------------------- /deps/jemalloc/src/mb.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_MB_C_ 2 | #include "jemalloc/internal/jemalloc_internal.h" 3 | -------------------------------------------------------------------------------- /deps/jemalloc/src/mutex.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_MUTEX_C_ 2 | #include "jemalloc/internal/jemalloc_internal.h" 3 | 4 | /******************************************************************************/ 5 | /* Data. */ 6 | 7 | #ifdef JEMALLOC_LAZY_LOCK 8 | bool isthreaded = false; 9 | #endif 10 | 11 | #ifdef JEMALLOC_LAZY_LOCK 12 | static void pthread_create_once(void); 13 | #endif 14 | 15 | /******************************************************************************/ 16 | /* 17 | * We intercept pthread_create() calls in order to toggle isthreaded if the 18 | * process goes multi-threaded. 19 | */ 20 | 21 | #ifdef JEMALLOC_LAZY_LOCK 22 | static int (*pthread_create_fptr)(pthread_t *__restrict, const pthread_attr_t *, 23 | void *(*)(void *), void *__restrict); 24 | 25 | static void 26 | pthread_create_once(void) 27 | { 28 | 29 | pthread_create_fptr = dlsym(RTLD_NEXT, "pthread_create"); 30 | if (pthread_create_fptr == NULL) { 31 | malloc_write(": Error in dlsym(RTLD_NEXT, " 32 | "\"pthread_create\")\n"); 33 | abort(); 34 | } 35 | 36 | isthreaded = true; 37 | } 38 | 39 | JEMALLOC_ATTR(visibility("default")) 40 | int 41 | pthread_create(pthread_t *__restrict thread, 42 | const pthread_attr_t *__restrict attr, void *(*start_routine)(void *), 43 | void *__restrict arg) 44 | { 45 | static pthread_once_t once_control = PTHREAD_ONCE_INIT; 46 | 47 | pthread_once(&once_control, pthread_create_once); 48 | 49 | return (pthread_create_fptr(thread, attr, start_routine, arg)); 50 | } 51 | #endif 52 | 53 | /******************************************************************************/ 54 | 55 | bool 56 | malloc_mutex_init(malloc_mutex_t *mutex) 57 | { 58 | #ifdef JEMALLOC_OSSPIN 59 | *mutex = 0; 60 | #else 61 | pthread_mutexattr_t attr; 62 | 63 | if (pthread_mutexattr_init(&attr) != 0) 64 | return (true); 65 | #ifdef PTHREAD_MUTEX_ADAPTIVE_NP 66 | pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP); 67 | #else 68 | pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_DEFAULT); 69 | #endif 70 | if (pthread_mutex_init(mutex, &attr) != 0) { 71 | pthread_mutexattr_destroy(&attr); 72 | return (true); 73 | } 74 | pthread_mutexattr_destroy(&attr); 75 | 76 | #endif 77 | return (false); 78 | } 79 | 80 | void 81 | malloc_mutex_destroy(malloc_mutex_t *mutex) 82 | { 83 | 84 | #ifndef JEMALLOC_OSSPIN 85 | if (pthread_mutex_destroy(mutex) != 0) { 86 | malloc_write(": Error in pthread_mutex_destroy()\n"); 87 | abort(); 88 | } 89 | #endif 90 | } 91 | -------------------------------------------------------------------------------- /deps/jemalloc/src/rtree.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_RTREE_C_ 2 | #include "jemalloc/internal/jemalloc_internal.h" 3 | 4 | rtree_t * 5 | rtree_new(unsigned bits) 6 | { 7 | rtree_t *ret; 8 | unsigned bits_per_level, height, i; 9 | 10 | bits_per_level = ffs(pow2_ceil((RTREE_NODESIZE / sizeof(void *)))) - 1; 11 | height = bits / bits_per_level; 12 | if (height * bits_per_level != bits) 13 | height++; 14 | assert(height * bits_per_level >= bits); 15 | 16 | ret = (rtree_t*)base_alloc(offsetof(rtree_t, level2bits) + 17 | (sizeof(unsigned) * height)); 18 | if (ret == NULL) 19 | return (NULL); 20 | memset(ret, 0, offsetof(rtree_t, level2bits) + (sizeof(unsigned) * 21 | height)); 22 | 23 | if (malloc_mutex_init(&ret->mutex)) { 24 | /* Leak the rtree. */ 25 | return (NULL); 26 | } 27 | ret->height = height; 28 | if (bits_per_level * height > bits) 29 | ret->level2bits[0] = bits % bits_per_level; 30 | else 31 | ret->level2bits[0] = bits_per_level; 32 | for (i = 1; i < height; i++) 33 | ret->level2bits[i] = bits_per_level; 34 | 35 | ret->root = (void**)base_alloc(sizeof(void *) << ret->level2bits[0]); 36 | if (ret->root == NULL) { 37 | /* 38 | * We leak the rtree here, since there's no generic base 39 | * deallocation. 40 | */ 41 | return (NULL); 42 | } 43 | memset(ret->root, 0, sizeof(void *) << ret->level2bits[0]); 44 | 45 | return (ret); 46 | } 47 | -------------------------------------------------------------------------------- /deps/jemalloc/test/allocated.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define JEMALLOC_MANGLE 11 | #include "jemalloc_test.h" 12 | 13 | void * 14 | thread_start(void *arg) 15 | { 16 | int err; 17 | void *p; 18 | uint64_t a0, a1, d0, d1; 19 | uint64_t *ap0, *ap1, *dp0, *dp1; 20 | size_t sz, usize; 21 | 22 | sz = sizeof(a0); 23 | if ((err = JEMALLOC_P(mallctl)("thread.allocated", &a0, &sz, NULL, 24 | 0))) { 25 | if (err == ENOENT) { 26 | #ifdef JEMALLOC_STATS 27 | assert(false); 28 | #endif 29 | goto RETURN; 30 | } 31 | fprintf(stderr, "%s(): Error in mallctl(): %s\n", __func__, 32 | strerror(err)); 33 | exit(1); 34 | } 35 | sz = sizeof(ap0); 36 | if ((err = JEMALLOC_P(mallctl)("thread.allocatedp", &ap0, &sz, NULL, 37 | 0))) { 38 | if (err == ENOENT) { 39 | #ifdef JEMALLOC_STATS 40 | assert(false); 41 | #endif 42 | goto RETURN; 43 | } 44 | fprintf(stderr, "%s(): Error in mallctl(): %s\n", __func__, 45 | strerror(err)); 46 | exit(1); 47 | } 48 | assert(*ap0 == a0); 49 | 50 | sz = sizeof(d0); 51 | if ((err = JEMALLOC_P(mallctl)("thread.deallocated", &d0, &sz, NULL, 52 | 0))) { 53 | if (err == ENOENT) { 54 | #ifdef JEMALLOC_STATS 55 | assert(false); 56 | #endif 57 | goto RETURN; 58 | } 59 | fprintf(stderr, "%s(): Error in mallctl(): %s\n", __func__, 60 | strerror(err)); 61 | exit(1); 62 | } 63 | sz = sizeof(dp0); 64 | if ((err = JEMALLOC_P(mallctl)("thread.deallocatedp", &dp0, &sz, NULL, 65 | 0))) { 66 | if (err == ENOENT) { 67 | #ifdef JEMALLOC_STATS 68 | assert(false); 69 | #endif 70 | goto RETURN; 71 | } 72 | fprintf(stderr, "%s(): Error in mallctl(): %s\n", __func__, 73 | strerror(err)); 74 | exit(1); 75 | } 76 | assert(*dp0 == d0); 77 | 78 | p = JEMALLOC_P(malloc)(1); 79 | if (p == NULL) { 80 | fprintf(stderr, "%s(): Error in malloc()\n", __func__); 81 | exit(1); 82 | } 83 | 84 | sz = sizeof(a1); 85 | JEMALLOC_P(mallctl)("thread.allocated", &a1, &sz, NULL, 0); 86 | sz = sizeof(ap1); 87 | JEMALLOC_P(mallctl)("thread.allocatedp", &ap1, &sz, NULL, 0); 88 | assert(*ap1 == a1); 89 | assert(ap0 == ap1); 90 | 91 | usize = JEMALLOC_P(malloc_usable_size)(p); 92 | assert(a0 + usize <= a1); 93 | 94 | JEMALLOC_P(free)(p); 95 | 96 | sz = sizeof(d1); 97 | JEMALLOC_P(mallctl)("thread.deallocated", &d1, &sz, NULL, 0); 98 | sz = sizeof(dp1); 99 | JEMALLOC_P(mallctl)("thread.deallocatedp", &dp1, &sz, NULL, 0); 100 | assert(*dp1 == d1); 101 | assert(dp0 == dp1); 102 | 103 | assert(d0 + usize <= d1); 104 | 105 | RETURN: 106 | return (NULL); 107 | } 108 | 109 | int 110 | main(void) 111 | { 112 | int ret = 0; 113 | pthread_t thread; 114 | 115 | fprintf(stderr, "Test begin\n"); 116 | 117 | thread_start(NULL); 118 | 119 | if (pthread_create(&thread, NULL, thread_start, NULL) 120 | != 0) { 121 | fprintf(stderr, "%s(): Error in pthread_create()\n", __func__); 122 | ret = 1; 123 | goto RETURN; 124 | } 125 | pthread_join(thread, (void *)&ret); 126 | 127 | thread_start(NULL); 128 | 129 | if (pthread_create(&thread, NULL, thread_start, NULL) 130 | != 0) { 131 | fprintf(stderr, "%s(): Error in pthread_create()\n", __func__); 132 | ret = 1; 133 | goto RETURN; 134 | } 135 | pthread_join(thread, (void *)&ret); 136 | 137 | thread_start(NULL); 138 | 139 | RETURN: 140 | fprintf(stderr, "Test end\n"); 141 | return (ret); 142 | } 143 | -------------------------------------------------------------------------------- /deps/jemalloc/test/allocated.exp: -------------------------------------------------------------------------------- 1 | Test begin 2 | Test end 3 | -------------------------------------------------------------------------------- /deps/jemalloc/test/allocm.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define JEMALLOC_MANGLE 6 | #include "jemalloc_test.h" 7 | 8 | #define CHUNK 0x400000 9 | /* #define MAXALIGN ((size_t)0x80000000000LLU) */ 10 | #define MAXALIGN ((size_t)0x2000000LLU) 11 | #define NITER 4 12 | 13 | int 14 | main(void) 15 | { 16 | int r; 17 | void *p; 18 | size_t sz, alignment, total, tsz; 19 | unsigned i; 20 | void *ps[NITER]; 21 | 22 | fprintf(stderr, "Test begin\n"); 23 | 24 | sz = 0; 25 | r = JEMALLOC_P(allocm)(&p, &sz, 42, 0); 26 | if (r != ALLOCM_SUCCESS) { 27 | fprintf(stderr, "Unexpected allocm() error\n"); 28 | abort(); 29 | } 30 | if (sz < 42) 31 | fprintf(stderr, "Real size smaller than expected\n"); 32 | if (JEMALLOC_P(dallocm)(p, 0) != ALLOCM_SUCCESS) 33 | fprintf(stderr, "Unexpected dallocm() error\n"); 34 | 35 | r = JEMALLOC_P(allocm)(&p, NULL, 42, 0); 36 | if (r != ALLOCM_SUCCESS) { 37 | fprintf(stderr, "Unexpected allocm() error\n"); 38 | abort(); 39 | } 40 | if (JEMALLOC_P(dallocm)(p, 0) != ALLOCM_SUCCESS) 41 | fprintf(stderr, "Unexpected dallocm() error\n"); 42 | 43 | r = JEMALLOC_P(allocm)(&p, NULL, 42, ALLOCM_ZERO); 44 | if (r != ALLOCM_SUCCESS) { 45 | fprintf(stderr, "Unexpected allocm() error\n"); 46 | abort(); 47 | } 48 | if (JEMALLOC_P(dallocm)(p, 0) != ALLOCM_SUCCESS) 49 | fprintf(stderr, "Unexpected dallocm() error\n"); 50 | 51 | #if LG_SIZEOF_PTR == 3 52 | alignment = 0x8000000000000000LLU; 53 | sz = 0x8000000000000000LLU; 54 | #else 55 | alignment = 0x80000000LU; 56 | sz = 0x80000000LU; 57 | #endif 58 | r = JEMALLOC_P(allocm)(&p, NULL, sz, ALLOCM_ALIGN(alignment)); 59 | if (r == ALLOCM_SUCCESS) { 60 | fprintf(stderr, 61 | "Expected error for allocm(&p, %zu, 0x%x)\n", 62 | sz, ALLOCM_ALIGN(alignment)); 63 | } 64 | 65 | #if LG_SIZEOF_PTR == 3 66 | alignment = 0x4000000000000000LLU; 67 | sz = 0x8400000000000001LLU; 68 | #else 69 | alignment = 0x40000000LU; 70 | sz = 0x84000001LU; 71 | #endif 72 | r = JEMALLOC_P(allocm)(&p, NULL, sz, ALLOCM_ALIGN(alignment)); 73 | if (r == ALLOCM_SUCCESS) { 74 | fprintf(stderr, 75 | "Expected error for allocm(&p, %zu, 0x%x)\n", 76 | sz, ALLOCM_ALIGN(alignment)); 77 | } 78 | 79 | alignment = 0x10LLU; 80 | #if LG_SIZEOF_PTR == 3 81 | sz = 0xfffffffffffffff0LLU; 82 | #else 83 | sz = 0xfffffff0LU; 84 | #endif 85 | r = JEMALLOC_P(allocm)(&p, NULL, sz, ALLOCM_ALIGN(alignment)); 86 | if (r == ALLOCM_SUCCESS) { 87 | fprintf(stderr, 88 | "Expected error for allocm(&p, %zu, 0x%x)\n", 89 | sz, ALLOCM_ALIGN(alignment)); 90 | } 91 | 92 | for (i = 0; i < NITER; i++) 93 | ps[i] = NULL; 94 | 95 | for (alignment = 8; 96 | alignment <= MAXALIGN; 97 | alignment <<= 1) { 98 | total = 0; 99 | fprintf(stderr, "Alignment: %zu\n", alignment); 100 | for (sz = 1; 101 | sz < 3 * alignment && sz < (1U << 31); 102 | sz += (alignment >> (LG_SIZEOF_PTR-1)) - 1) { 103 | for (i = 0; i < NITER; i++) { 104 | r = JEMALLOC_P(allocm)(&ps[i], NULL, sz, 105 | ALLOCM_ALIGN(alignment) | ALLOCM_ZERO); 106 | if (r != ALLOCM_SUCCESS) { 107 | fprintf(stderr, 108 | "Error for size %zu (0x%zx): %d\n", 109 | sz, sz, r); 110 | exit(1); 111 | } 112 | if ((uintptr_t)p & (alignment-1)) { 113 | fprintf(stderr, 114 | "%p inadequately aligned for" 115 | " alignment: %zu\n", p, alignment); 116 | } 117 | JEMALLOC_P(sallocm)(ps[i], &tsz, 0); 118 | total += tsz; 119 | if (total >= (MAXALIGN << 1)) 120 | break; 121 | } 122 | for (i = 0; i < NITER; i++) { 123 | if (ps[i] != NULL) { 124 | JEMALLOC_P(dallocm)(ps[i], 0); 125 | ps[i] = NULL; 126 | } 127 | } 128 | } 129 | } 130 | 131 | fprintf(stderr, "Test end\n"); 132 | return (0); 133 | } 134 | -------------------------------------------------------------------------------- /deps/jemalloc/test/allocm.exp: -------------------------------------------------------------------------------- 1 | Test begin 2 | Alignment: 8 3 | Alignment: 16 4 | Alignment: 32 5 | Alignment: 64 6 | Alignment: 128 7 | Alignment: 256 8 | Alignment: 512 9 | Alignment: 1024 10 | Alignment: 2048 11 | Alignment: 4096 12 | Alignment: 8192 13 | Alignment: 16384 14 | Alignment: 32768 15 | Alignment: 65536 16 | Alignment: 131072 17 | Alignment: 262144 18 | Alignment: 524288 19 | Alignment: 1048576 20 | Alignment: 2097152 21 | Alignment: 4194304 22 | Alignment: 8388608 23 | Alignment: 16777216 24 | Alignment: 33554432 25 | Test end 26 | -------------------------------------------------------------------------------- /deps/jemalloc/test/bitmap.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_MANGLE 2 | #include "jemalloc_test.h" 3 | 4 | /* 5 | * Avoid using the assert() from jemalloc_internal.h, since it requires 6 | * internal libjemalloc functionality. 7 | * */ 8 | #include 9 | 10 | /* 11 | * Directly include the bitmap code, since it isn't exposed outside 12 | * libjemalloc. 13 | */ 14 | #include "../src/bitmap.c" 15 | 16 | #if (LG_BITMAP_MAXBITS > 12) 17 | # define MAXBITS 4500 18 | #else 19 | # define MAXBITS (1U << LG_BITMAP_MAXBITS) 20 | #endif 21 | 22 | static void 23 | test_bitmap_size(void) 24 | { 25 | size_t i, prev_size; 26 | 27 | prev_size = 0; 28 | for (i = 1; i <= MAXBITS; i++) { 29 | size_t size = bitmap_size(i); 30 | assert(size >= prev_size); 31 | prev_size = size; 32 | } 33 | } 34 | 35 | static void 36 | test_bitmap_init(void) 37 | { 38 | size_t i; 39 | 40 | for (i = 1; i <= MAXBITS; i++) { 41 | bitmap_info_t binfo; 42 | bitmap_info_init(&binfo, i); 43 | { 44 | size_t j; 45 | bitmap_t bitmap[bitmap_info_ngroups(&binfo)]; 46 | bitmap_init(bitmap, &binfo); 47 | 48 | for (j = 0; j < i; j++) 49 | assert(bitmap_get(bitmap, &binfo, j) == false); 50 | 51 | } 52 | } 53 | } 54 | 55 | static void 56 | test_bitmap_set(void) 57 | { 58 | size_t i; 59 | 60 | for (i = 1; i <= MAXBITS; i++) { 61 | bitmap_info_t binfo; 62 | bitmap_info_init(&binfo, i); 63 | { 64 | size_t j; 65 | bitmap_t bitmap[bitmap_info_ngroups(&binfo)]; 66 | bitmap_init(bitmap, &binfo); 67 | 68 | for (j = 0; j < i; j++) 69 | bitmap_set(bitmap, &binfo, j); 70 | assert(bitmap_full(bitmap, &binfo)); 71 | } 72 | } 73 | } 74 | 75 | static void 76 | test_bitmap_unset(void) 77 | { 78 | size_t i; 79 | 80 | for (i = 1; i <= MAXBITS; i++) { 81 | bitmap_info_t binfo; 82 | bitmap_info_init(&binfo, i); 83 | { 84 | size_t j; 85 | bitmap_t bitmap[bitmap_info_ngroups(&binfo)]; 86 | bitmap_init(bitmap, &binfo); 87 | 88 | for (j = 0; j < i; j++) 89 | bitmap_set(bitmap, &binfo, j); 90 | assert(bitmap_full(bitmap, &binfo)); 91 | for (j = 0; j < i; j++) 92 | bitmap_unset(bitmap, &binfo, j); 93 | for (j = 0; j < i; j++) 94 | bitmap_set(bitmap, &binfo, j); 95 | assert(bitmap_full(bitmap, &binfo)); 96 | } 97 | } 98 | } 99 | 100 | static void 101 | test_bitmap_sfu(void) 102 | { 103 | size_t i; 104 | 105 | for (i = 1; i <= MAXBITS; i++) { 106 | bitmap_info_t binfo; 107 | bitmap_info_init(&binfo, i); 108 | { 109 | ssize_t j; 110 | bitmap_t bitmap[bitmap_info_ngroups(&binfo)]; 111 | bitmap_init(bitmap, &binfo); 112 | 113 | /* Iteratively set bits starting at the beginning. */ 114 | for (j = 0; j < i; j++) 115 | assert(bitmap_sfu(bitmap, &binfo) == j); 116 | assert(bitmap_full(bitmap, &binfo)); 117 | 118 | /* 119 | * Iteratively unset bits starting at the end, and 120 | * verify that bitmap_sfu() reaches the unset bits. 121 | */ 122 | for (j = i - 1; j >= 0; j--) { 123 | bitmap_unset(bitmap, &binfo, j); 124 | assert(bitmap_sfu(bitmap, &binfo) == j); 125 | bitmap_unset(bitmap, &binfo, j); 126 | } 127 | assert(bitmap_get(bitmap, &binfo, 0) == false); 128 | 129 | /* 130 | * Iteratively set bits starting at the beginning, and 131 | * verify that bitmap_sfu() looks past them. 132 | */ 133 | for (j = 1; j < i; j++) { 134 | bitmap_set(bitmap, &binfo, j - 1); 135 | assert(bitmap_sfu(bitmap, &binfo) == j); 136 | bitmap_unset(bitmap, &binfo, j); 137 | } 138 | assert(bitmap_sfu(bitmap, &binfo) == i - 1); 139 | assert(bitmap_full(bitmap, &binfo)); 140 | } 141 | } 142 | } 143 | 144 | int 145 | main(void) 146 | { 147 | fprintf(stderr, "Test begin\n"); 148 | 149 | test_bitmap_size(); 150 | test_bitmap_init(); 151 | test_bitmap_set(); 152 | test_bitmap_unset(); 153 | test_bitmap_sfu(); 154 | 155 | fprintf(stderr, "Test end\n"); 156 | return (0); 157 | } 158 | -------------------------------------------------------------------------------- /deps/jemalloc/test/bitmap.exp: -------------------------------------------------------------------------------- 1 | Test begin 2 | Test end 3 | -------------------------------------------------------------------------------- /deps/jemalloc/test/jemalloc_test.h.in: -------------------------------------------------------------------------------- 1 | /* 2 | * This header should be included by tests, rather than directly including 3 | * jemalloc/jemalloc.h, because --with-install-suffix may cause the header to 4 | * have a different name. 5 | */ 6 | #include "jemalloc/jemalloc@install_suffix@.h" 7 | -------------------------------------------------------------------------------- /deps/jemalloc/test/mremap.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define JEMALLOC_MANGLE 8 | #include "jemalloc_test.h" 9 | 10 | int 11 | main(void) 12 | { 13 | int ret, err; 14 | size_t sz, lg_chunk, chunksize, i; 15 | char *p, *q; 16 | 17 | fprintf(stderr, "Test begin\n"); 18 | 19 | sz = sizeof(lg_chunk); 20 | if ((err = JEMALLOC_P(mallctl)("opt.lg_chunk", &lg_chunk, &sz, NULL, 21 | 0))) { 22 | assert(err != ENOENT); 23 | fprintf(stderr, "%s(): Error in mallctl(): %s\n", __func__, 24 | strerror(err)); 25 | ret = 1; 26 | goto RETURN; 27 | } 28 | chunksize = ((size_t)1U) << lg_chunk; 29 | 30 | p = (char *)malloc(chunksize); 31 | if (p == NULL) { 32 | fprintf(stderr, "malloc(%zu) --> %p\n", chunksize, p); 33 | ret = 1; 34 | goto RETURN; 35 | } 36 | memset(p, 'a', chunksize); 37 | 38 | q = (char *)realloc(p, chunksize * 2); 39 | if (q == NULL) { 40 | fprintf(stderr, "realloc(%p, %zu) --> %p\n", p, chunksize * 2, 41 | q); 42 | ret = 1; 43 | goto RETURN; 44 | } 45 | for (i = 0; i < chunksize; i++) { 46 | assert(q[i] == 'a'); 47 | } 48 | 49 | p = q; 50 | 51 | q = (char *)realloc(p, chunksize); 52 | if (q == NULL) { 53 | fprintf(stderr, "realloc(%p, %zu) --> %p\n", p, chunksize, q); 54 | ret = 1; 55 | goto RETURN; 56 | } 57 | for (i = 0; i < chunksize; i++) { 58 | assert(q[i] == 'a'); 59 | } 60 | 61 | free(q); 62 | 63 | ret = 0; 64 | RETURN: 65 | fprintf(stderr, "Test end\n"); 66 | return (ret); 67 | } 68 | -------------------------------------------------------------------------------- /deps/jemalloc/test/mremap.exp: -------------------------------------------------------------------------------- 1 | Test begin 2 | Test end 3 | -------------------------------------------------------------------------------- /deps/jemalloc/test/posix_memalign.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define JEMALLOC_MANGLE 8 | #include "jemalloc_test.h" 9 | 10 | #define CHUNK 0x400000 11 | /* #define MAXALIGN ((size_t)0x80000000000LLU) */ 12 | #define MAXALIGN ((size_t)0x2000000LLU) 13 | #define NITER 4 14 | 15 | int 16 | main(void) 17 | { 18 | size_t alignment, size, total; 19 | unsigned i; 20 | int err; 21 | void *p, *ps[NITER]; 22 | 23 | fprintf(stderr, "Test begin\n"); 24 | 25 | /* Test error conditions. */ 26 | for (alignment = 0; alignment < sizeof(void *); alignment++) { 27 | err = JEMALLOC_P(posix_memalign)(&p, alignment, 1); 28 | if (err != EINVAL) { 29 | fprintf(stderr, 30 | "Expected error for invalid alignment %zu\n", 31 | alignment); 32 | } 33 | } 34 | 35 | for (alignment = sizeof(size_t); alignment < MAXALIGN; 36 | alignment <<= 1) { 37 | err = JEMALLOC_P(posix_memalign)(&p, alignment + 1, 1); 38 | if (err == 0) { 39 | fprintf(stderr, 40 | "Expected error for invalid alignment %zu\n", 41 | alignment + 1); 42 | } 43 | } 44 | 45 | #if LG_SIZEOF_PTR == 3 46 | alignment = 0x8000000000000000LLU; 47 | size = 0x8000000000000000LLU; 48 | #else 49 | alignment = 0x80000000LU; 50 | size = 0x80000000LU; 51 | #endif 52 | err = JEMALLOC_P(posix_memalign)(&p, alignment, size); 53 | if (err == 0) { 54 | fprintf(stderr, 55 | "Expected error for posix_memalign(&p, %zu, %zu)\n", 56 | alignment, size); 57 | } 58 | 59 | #if LG_SIZEOF_PTR == 3 60 | alignment = 0x4000000000000000LLU; 61 | size = 0x8400000000000001LLU; 62 | #else 63 | alignment = 0x40000000LU; 64 | size = 0x84000001LU; 65 | #endif 66 | err = JEMALLOC_P(posix_memalign)(&p, alignment, size); 67 | if (err == 0) { 68 | fprintf(stderr, 69 | "Expected error for posix_memalign(&p, %zu, %zu)\n", 70 | alignment, size); 71 | } 72 | 73 | alignment = 0x10LLU; 74 | #if LG_SIZEOF_PTR == 3 75 | size = 0xfffffffffffffff0LLU; 76 | #else 77 | size = 0xfffffff0LU; 78 | #endif 79 | err = JEMALLOC_P(posix_memalign)(&p, alignment, size); 80 | if (err == 0) { 81 | fprintf(stderr, 82 | "Expected error for posix_memalign(&p, %zu, %zu)\n", 83 | alignment, size); 84 | } 85 | 86 | for (i = 0; i < NITER; i++) 87 | ps[i] = NULL; 88 | 89 | for (alignment = 8; 90 | alignment <= MAXALIGN; 91 | alignment <<= 1) { 92 | total = 0; 93 | fprintf(stderr, "Alignment: %zu\n", alignment); 94 | for (size = 1; 95 | size < 3 * alignment && size < (1U << 31); 96 | size += (alignment >> (LG_SIZEOF_PTR-1)) - 1) { 97 | for (i = 0; i < NITER; i++) { 98 | err = JEMALLOC_P(posix_memalign)(&ps[i], 99 | alignment, size); 100 | if (err) { 101 | fprintf(stderr, 102 | "Error for size %zu (0x%zx): %s\n", 103 | size, size, strerror(err)); 104 | exit(1); 105 | } 106 | total += JEMALLOC_P(malloc_usable_size)(ps[i]); 107 | if (total >= (MAXALIGN << 1)) 108 | break; 109 | } 110 | for (i = 0; i < NITER; i++) { 111 | if (ps[i] != NULL) { 112 | JEMALLOC_P(free)(ps[i]); 113 | ps[i] = NULL; 114 | } 115 | } 116 | } 117 | } 118 | 119 | fprintf(stderr, "Test end\n"); 120 | return (0); 121 | } 122 | -------------------------------------------------------------------------------- /deps/jemalloc/test/posix_memalign.exp: -------------------------------------------------------------------------------- 1 | Test begin 2 | Alignment: 8 3 | Alignment: 16 4 | Alignment: 32 5 | Alignment: 64 6 | Alignment: 128 7 | Alignment: 256 8 | Alignment: 512 9 | Alignment: 1024 10 | Alignment: 2048 11 | Alignment: 4096 12 | Alignment: 8192 13 | Alignment: 16384 14 | Alignment: 32768 15 | Alignment: 65536 16 | Alignment: 131072 17 | Alignment: 262144 18 | Alignment: 524288 19 | Alignment: 1048576 20 | Alignment: 2097152 21 | Alignment: 4194304 22 | Alignment: 8388608 23 | Alignment: 16777216 24 | Alignment: 33554432 25 | Test end 26 | -------------------------------------------------------------------------------- /deps/jemalloc/test/rallocm.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define JEMALLOC_MANGLE 8 | #include "jemalloc_test.h" 9 | 10 | int 11 | main(void) 12 | { 13 | size_t pagesize; 14 | void *p, *q; 15 | size_t sz, tsz; 16 | int r; 17 | 18 | fprintf(stderr, "Test begin\n"); 19 | 20 | /* Get page size. */ 21 | { 22 | long result = sysconf(_SC_PAGESIZE); 23 | assert(result != -1); 24 | pagesize = (size_t)result; 25 | } 26 | 27 | r = JEMALLOC_P(allocm)(&p, &sz, 42, 0); 28 | if (r != ALLOCM_SUCCESS) { 29 | fprintf(stderr, "Unexpected allocm() error\n"); 30 | abort(); 31 | } 32 | 33 | q = p; 34 | r = JEMALLOC_P(rallocm)(&q, &tsz, sz, 0, ALLOCM_NO_MOVE); 35 | if (r != ALLOCM_SUCCESS) 36 | fprintf(stderr, "Unexpected rallocm() error\n"); 37 | if (q != p) 38 | fprintf(stderr, "Unexpected object move\n"); 39 | if (tsz != sz) { 40 | fprintf(stderr, "Unexpected size change: %zu --> %zu\n", 41 | sz, tsz); 42 | } 43 | 44 | q = p; 45 | r = JEMALLOC_P(rallocm)(&q, &tsz, sz, 5, ALLOCM_NO_MOVE); 46 | if (r != ALLOCM_SUCCESS) 47 | fprintf(stderr, "Unexpected rallocm() error\n"); 48 | if (q != p) 49 | fprintf(stderr, "Unexpected object move\n"); 50 | if (tsz != sz) { 51 | fprintf(stderr, "Unexpected size change: %zu --> %zu\n", 52 | sz, tsz); 53 | } 54 | 55 | q = p; 56 | r = JEMALLOC_P(rallocm)(&q, &tsz, sz + 5, 0, ALLOCM_NO_MOVE); 57 | if (r != ALLOCM_ERR_NOT_MOVED) 58 | fprintf(stderr, "Unexpected rallocm() result\n"); 59 | if (q != p) 60 | fprintf(stderr, "Unexpected object move\n"); 61 | if (tsz != sz) { 62 | fprintf(stderr, "Unexpected size change: %zu --> %zu\n", 63 | sz, tsz); 64 | } 65 | 66 | q = p; 67 | r = JEMALLOC_P(rallocm)(&q, &tsz, sz + 5, 0, 0); 68 | if (r != ALLOCM_SUCCESS) 69 | fprintf(stderr, "Unexpected rallocm() error\n"); 70 | if (q == p) 71 | fprintf(stderr, "Expected object move\n"); 72 | if (tsz == sz) { 73 | fprintf(stderr, "Expected size change: %zu --> %zu\n", 74 | sz, tsz); 75 | } 76 | p = q; 77 | sz = tsz; 78 | 79 | r = JEMALLOC_P(rallocm)(&q, &tsz, pagesize*2, 0, 0); 80 | if (r != ALLOCM_SUCCESS) 81 | fprintf(stderr, "Unexpected rallocm() error\n"); 82 | if (q == p) 83 | fprintf(stderr, "Expected object move\n"); 84 | if (tsz == sz) { 85 | fprintf(stderr, "Expected size change: %zu --> %zu\n", 86 | sz, tsz); 87 | } 88 | p = q; 89 | sz = tsz; 90 | 91 | r = JEMALLOC_P(rallocm)(&q, &tsz, pagesize*4, 0, 0); 92 | if (r != ALLOCM_SUCCESS) 93 | fprintf(stderr, "Unexpected rallocm() error\n"); 94 | if (tsz == sz) { 95 | fprintf(stderr, "Expected size change: %zu --> %zu\n", 96 | sz, tsz); 97 | } 98 | p = q; 99 | sz = tsz; 100 | 101 | r = JEMALLOC_P(rallocm)(&q, &tsz, pagesize*2, 0, ALLOCM_NO_MOVE); 102 | if (r != ALLOCM_SUCCESS) 103 | fprintf(stderr, "Unexpected rallocm() error\n"); 104 | if (q != p) 105 | fprintf(stderr, "Unexpected object move\n"); 106 | if (tsz == sz) { 107 | fprintf(stderr, "Expected size change: %zu --> %zu\n", 108 | sz, tsz); 109 | } 110 | sz = tsz; 111 | 112 | r = JEMALLOC_P(rallocm)(&q, &tsz, pagesize*4, 0, ALLOCM_NO_MOVE); 113 | if (r != ALLOCM_SUCCESS) 114 | fprintf(stderr, "Unexpected rallocm() error\n"); 115 | if (q != p) 116 | fprintf(stderr, "Unexpected object move\n"); 117 | if (tsz == sz) { 118 | fprintf(stderr, "Expected size change: %zu --> %zu\n", 119 | sz, tsz); 120 | } 121 | sz = tsz; 122 | 123 | JEMALLOC_P(dallocm)(p, 0); 124 | 125 | fprintf(stderr, "Test end\n"); 126 | return (0); 127 | } 128 | -------------------------------------------------------------------------------- /deps/jemalloc/test/rallocm.exp: -------------------------------------------------------------------------------- 1 | Test begin 2 | Test end 3 | -------------------------------------------------------------------------------- /deps/jemalloc/test/thread_arena.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define JEMALLOC_MANGLE 8 | #include "jemalloc_test.h" 9 | 10 | #define NTHREADS 10 11 | 12 | void * 13 | thread_start(void *arg) 14 | { 15 | unsigned main_arena_ind = *(unsigned *)arg; 16 | void *p; 17 | unsigned arena_ind; 18 | size_t size; 19 | int err; 20 | 21 | p = JEMALLOC_P(malloc)(1); 22 | if (p == NULL) { 23 | fprintf(stderr, "%s(): Error in malloc()\n", __func__); 24 | return (void *)1; 25 | } 26 | 27 | size = sizeof(arena_ind); 28 | if ((err = JEMALLOC_P(mallctl)("thread.arena", &arena_ind, &size, 29 | &main_arena_ind, sizeof(main_arena_ind)))) { 30 | fprintf(stderr, "%s(): Error in mallctl(): %s\n", __func__, 31 | strerror(err)); 32 | return (void *)1; 33 | } 34 | 35 | size = sizeof(arena_ind); 36 | if ((err = JEMALLOC_P(mallctl)("thread.arena", &arena_ind, &size, NULL, 37 | 0))) { 38 | fprintf(stderr, "%s(): Error in mallctl(): %s\n", __func__, 39 | strerror(err)); 40 | return (void *)1; 41 | } 42 | assert(arena_ind == main_arena_ind); 43 | 44 | return (NULL); 45 | } 46 | 47 | int 48 | main(void) 49 | { 50 | int ret = 0; 51 | void *p; 52 | unsigned arena_ind; 53 | size_t size; 54 | int err; 55 | pthread_t threads[NTHREADS]; 56 | unsigned i; 57 | 58 | fprintf(stderr, "Test begin\n"); 59 | 60 | p = JEMALLOC_P(malloc)(1); 61 | if (p == NULL) { 62 | fprintf(stderr, "%s(): Error in malloc()\n", __func__); 63 | ret = 1; 64 | goto RETURN; 65 | } 66 | 67 | size = sizeof(arena_ind); 68 | if ((err = JEMALLOC_P(mallctl)("thread.arena", &arena_ind, &size, NULL, 69 | 0))) { 70 | fprintf(stderr, "%s(): Error in mallctl(): %s\n", __func__, 71 | strerror(err)); 72 | ret = 1; 73 | goto RETURN; 74 | } 75 | 76 | for (i = 0; i < NTHREADS; i++) { 77 | if (pthread_create(&threads[i], NULL, thread_start, 78 | (void *)&arena_ind) != 0) { 79 | fprintf(stderr, "%s(): Error in pthread_create()\n", 80 | __func__); 81 | ret = 1; 82 | goto RETURN; 83 | } 84 | } 85 | 86 | for (i = 0; i < NTHREADS; i++) 87 | pthread_join(threads[i], (void *)&ret); 88 | 89 | RETURN: 90 | fprintf(stderr, "Test end\n"); 91 | return (ret); 92 | } 93 | -------------------------------------------------------------------------------- /deps/jemalloc/test/thread_arena.exp: -------------------------------------------------------------------------------- 1 | Test begin 2 | Test end 3 | -------------------------------------------------------------------------------- /deps/linenoise/.gitignore: -------------------------------------------------------------------------------- 1 | linenoise_example* 2 | -------------------------------------------------------------------------------- /deps/linenoise/Makefile: -------------------------------------------------------------------------------- 1 | uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') 2 | osname := $(shell uname -rs | cut -f 1-2 -d "." | cut -f 1 -d "-") 3 | 4 | ifeq ($(osname),MINGW32_NT) 5 | CFLAGS?= -std=gnu99 -pedantic $(OPTIMIZATION) -Wall -W -D_ISOC99_SOURCE -D__USE_MINGW_ANSI_STDIO=1 -Wwrite-strings $(ARCH) $(PROF) 6 | CCLINK?= -mthreads 7 | CC=gcc 8 | endif 9 | 10 | linenoise_example: linenoise.h linenoise.c 11 | 12 | linenoise_example: linenoise.o example.o 13 | $(CC) $(ARCH) -Wall -W -Os -g -o linenoise_example linenoise.o example.o 14 | 15 | .c.o: 16 | $(CC) $(ARCH) -c -Wall -W -Os -g $< 17 | 18 | clean: 19 | rm -f linenoise_example *.o *.exe 20 | -------------------------------------------------------------------------------- /deps/linenoise/README.markdown: -------------------------------------------------------------------------------- 1 | # Linenoise 2 | 3 | A minimal, zero-config, BSD licensed, readline replacement. 4 | 5 | News: linenoise is now part of [Android](http://android.git.kernel.org/?p=platform/system/core.git;a=tree;f=liblinenoise;h=56450eaed7f783760e5e6a5993ef75cde2e29dea;hb=HEAD Android)! 6 | 7 | ## Can a line editing library be 20k lines of code? 8 | 9 | Line editing with some support for history is a really important feature for command line utilities. Instead of retyping almost the same stuff again and again it's just much better to hit the up arrow and edit on syntax errors, or in order to try a slightly different command. But apparently code dealing with terminals is some sort of Black Magic: readline is 30k lines of code, libedit 20k. Is it reasonable to link small utilities to huge libraries just to get a minimal support for line editing? 10 | 11 | So what usually happens is either: 12 | 13 | * Large programs with configure scripts disabling line editing if readline is not present in the system, or not supporting it at all since readline is GPL licensed and libedit (the BSD clone) is not as known and available as readline is (Readl world example of this problem: Tclsh). 14 | * Smaller programs not using a configure script not supporting line editing at all (A problem we had with Redis-cli for instance). 15 | 16 | The result is a pollution of binaries without line editing support. 17 | 18 | So I spent more or less two hours doing a reality check resulting in this little library: is it *really* needed for a line editing library to be 20k lines of code? Apparently not, it is possibe to get a very small, zero configuration, trivial to embed library, that solves the problem. Smaller programs will just include this, supporing line editing out of the box. Larger programs may use this little library or just checking with configure if readline/libedit is available and resorting to linenoise if not. 19 | 20 | ## Terminals, in 2010. 21 | 22 | Apparently almost every terminal you can happen to use today has some kind of support for VT100 alike escape sequences. So I tried to write a lib using just very basic VT100 features. The resulting library appears to work everywhere I tried to use it. 23 | 24 | Since it's so young I guess there are a few bugs, or the lib may not compile or work with some operating system, but it's a matter of a few weeks and eventually we'll get it right, and there will be no excuses for not shipping command line tools without built-in line editing support. 25 | 26 | The library is currently less than 400 lines of code. In order to use it in your project just look at the *example.c* file in the source distribution, it is trivial. Linenoise is BSD code, so you can use both in free software and commercial software. 27 | 28 | ## Tested with... 29 | 30 | * Linux text only console ($TERM = linux) 31 | * Linux KDE terminal application ($TERM = xterm) 32 | * Linux xterm ($TERM = xterm) 33 | * Mac OS X iTerm ($TERM = xterm) 34 | * Mac OS X default Terminal.app ($TERM = xterm) 35 | * OpenBSD 4.5 through an OSX Terminal.app ($TERM = screen) 36 | * IBM AIX 6.1 37 | * FreeBSD xterm ($TERM = xterm) 38 | 39 | Please test it everywhere you can and report back! 40 | 41 | ## Let's push this forward! 42 | 43 | Please fork it and add something interesting and send me a pull request. What's especially interesting are fixes, new key bindings, completion. 44 | 45 | Send feedbacks to antirez at gmail 46 | -------------------------------------------------------------------------------- /deps/linenoise/example.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "linenoise.h" 4 | 5 | 6 | void completion(const char *buf, linenoiseCompletions *lc) { 7 | if (buf[0] == 'h') { 8 | linenoiseAddCompletion(lc,"hello"); 9 | linenoiseAddCompletion(lc,"hello there"); 10 | } 11 | } 12 | 13 | int main(void) { 14 | char *line; 15 | 16 | linenoiseSetCompletionCallback(completion); 17 | linenoiseHistoryLoad("history.txt"); /* Load the history at startup */ 18 | while((line = linenoise("hello> ")) != NULL) { 19 | if (line[0] != '\0') { 20 | printf("echo: '%s'\n", line); 21 | linenoiseHistoryAdd(line); 22 | linenoiseHistorySave("history.txt"); /* Save every new entry */ 23 | } 24 | free(line); 25 | } 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /deps/linenoise/linenoise.h: -------------------------------------------------------------------------------- 1 | /* linenoise.h -- guerrilla line editing library against the idea that a 2 | * line editing lib needs to be 20,000 lines of C code. 3 | * 4 | * See linenoise.c for more information. 5 | * 6 | * Copyright (c) 2010, Salvatore Sanfilippo 7 | * Copyright (c) 2010, Pieter Noordhuis 8 | * 9 | * All rights reserved. 10 | * 11 | * Redistribution and use in source and binary forms, with or without 12 | * modification, are permitted provided that the following conditions are met: 13 | * 14 | * * Redistributions of source code must retain the above copyright notice, 15 | * this list of conditions and the following disclaimer. 16 | * * Redistributions in binary form must reproduce the above copyright 17 | * notice, this list of conditions and the following disclaimer in the 18 | * documentation and/or other materials provided with the distribution. 19 | * * Neither the name of Redis nor the names of its contributors may be used 20 | * to endorse or promote products derived from this software without 21 | * specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 27 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 | * POSSIBILITY OF SUCH DAMAGE. 34 | */ 35 | 36 | #ifndef __LINENOISE_H 37 | #define __LINENOISE_H 38 | 39 | typedef struct linenoiseCompletions { 40 | size_t len; 41 | char **cvec; 42 | } linenoiseCompletions; 43 | 44 | typedef void(linenoiseCompletionCallback)(const char *, linenoiseCompletions *); 45 | void linenoiseSetCompletionCallback(linenoiseCompletionCallback *); 46 | void linenoiseAddCompletion(linenoiseCompletions *, char *); 47 | 48 | char *linenoise(const char *prompt); 49 | int linenoiseHistoryAdd(const char *line); 50 | int linenoiseHistorySetMaxLen(int len); 51 | int linenoiseHistorySave(char *filename); 52 | int linenoiseHistoryLoad(char *filename); 53 | void linenoiseClearScreen(void); 54 | 55 | #endif /* __LINENOISE_H */ 56 | -------------------------------------------------------------------------------- /runtest: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | TCL=tclsh8.5 3 | which $TCL 4 | if [ "$?" != "0" ] 5 | then 6 | echo "You need '$TCL' in order to run the Redis test" 7 | exit 1 8 | fi 9 | $TCL tests/test_helper.tcl $* 10 | -------------------------------------------------------------------------------- /setup/COPYING.txt: -------------------------------------------------------------------------------- 1 | Redis Copyright (c) 2006-2012, Salvatore Sanfilippo 2 | Redis Windows Port Copyright (c) 2010-2012, Dusan Majkic 3 | Redis Windows Service and Setup Copyright (c) 2011-2012, Rui Lopes 4 | 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 11 | * Neither the name of Redis nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 14 | -------------------------------------------------------------------------------- /setup/Makefile: -------------------------------------------------------------------------------- 1 | ISCC?= 'c:/Program Files (x86)/Inno Setup 5/ISCC.exe' 2 | 3 | ifneq (,$(shell objdump -f ../src/redis-server.exe | grep x86-64)) 4 | ISCCOPT+= -d_WIN64 5 | endif 6 | 7 | all: setup 8 | 9 | setup: 10 | strip ../src/*.{exe,dll} 11 | $(ISCC) redis.iss $(ISCCOPT) 12 | 13 | clean: 14 | rm -f redis-setup-*.exe 15 | -------------------------------------------------------------------------------- /setup/README.txt: -------------------------------------------------------------------------------- 1 | This directory contains the files needed to create the Redis install 2 | program. 3 | 4 | You first need to install Unicode Inno Setup (the QuickStart Pack) from: 5 | 6 | http://www.jrsoftware.org/isdl.php#qsp 7 | 8 | NB Get the ispack-5.4.0-unicode.exe file. 9 | 10 | Then, open the redis.iss file with the InnoIDE application (normally, 11 | you can just double click the .iss file to open it) and click build. 12 | It should create a file named redis-setup-NN-bit.exe with the install 13 | program. 14 | 15 | NB NN is 32 or 64 depending whether you are using a 32 or 64 bit 16 | compiler. 17 | 18 | NB You first need to build redis binaries. This is normally done by 19 | running the following command in the top level directory: 20 | 21 | make DEBUG='' 22 | 23 | 24 | This install uses SetACL.exe to grant NTFS file permissions to the 25 | RedisServer account. SetACL can be download from: 26 | 27 | http://helgeklein.com/setacl/ 28 | -------------------------------------------------------------------------------- /setup/Redis Documentation.url: -------------------------------------------------------------------------------- 1 | [InternetShortcut] 2 | URL=http://redis.io/documentation 3 | -------------------------------------------------------------------------------- /setup/Redis Home.url: -------------------------------------------------------------------------------- 1 | [InternetShortcut] 2 | URL=http://redis.io 3 | -------------------------------------------------------------------------------- /setup/Redis Windows Port Home.url: -------------------------------------------------------------------------------- 1 | [InternetShortcut] 2 | URL=https://github.com/dmajkic/redis 3 | -------------------------------------------------------------------------------- /setup/Redis Windows Service and Setup Home.url: -------------------------------------------------------------------------------- 1 | [InternetShortcut] 2 | URL=https://github.com/rgl/redis 3 | -------------------------------------------------------------------------------- /setup/SetACL.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rgl/redis/de23721acac1d2df6e30c55e4fb902bba39c956a/setup/SetACL.exe -------------------------------------------------------------------------------- /setup/redis-setup-wizard-small.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rgl/redis/de23721acac1d2df6e30c55e4fb902bba39c956a/setup/redis-setup-wizard-small.bmp -------------------------------------------------------------------------------- /setup/redis-setup-wizard.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rgl/redis/de23721acac1d2df6e30c55e4fb902bba39c956a/setup/redis-setup-wizard.bmp -------------------------------------------------------------------------------- /setup/redis.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rgl/redis/de23721acac1d2df6e30c55e4fb902bba39c956a/setup/redis.ico -------------------------------------------------------------------------------- /setup/service-account.pas: -------------------------------------------------------------------------------- 1 | // Windows User Management access code by Rui Lopes (ruilopes.com). 2 | // 3 | // NB You MUST use the Unicode Inno Setup to use this unit; the 4 | // NetXXX functions (used by our helper dll) only accept wide 5 | // strings. 6 | // 7 | // NB setup-helper.dll is copied to the app directory because we 8 | // need to use it at uninstall time. 9 | 10 | function ServiceAccountExists(name: string): integer; 11 | external 'ServiceAccountExists@files:setup-helper.dll stdcall'; 12 | 13 | function CreateServiceAccount(name, password, comment: string): integer; 14 | external 'CreateServiceAccount@files:setup-helper.dll stdcall'; 15 | 16 | function DestroyServiceAccount(name: string): integer; 17 | external 'DestroyServiceAccount@{app}\setup-helper.dll stdcall uninstallonly'; 18 | -------------------------------------------------------------------------------- /src/adlist.h: -------------------------------------------------------------------------------- 1 | /* adlist.h - A generic doubly linked list implementation 2 | * 3 | * Copyright (c) 2006-2010, Salvatore Sanfilippo 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * * Neither the name of Redis nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without 16 | * specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef __ADLIST_H__ 32 | #define __ADLIST_H__ 33 | 34 | /* Node, List, and Iterator are the only data structures used currently. */ 35 | 36 | typedef struct listNode { 37 | struct listNode *prev; 38 | struct listNode *next; 39 | void *value; 40 | } listNode; 41 | 42 | typedef struct listIter { 43 | listNode *next; 44 | int direction; 45 | } listIter; 46 | 47 | typedef struct list { 48 | listNode *head; 49 | listNode *tail; 50 | void *(*dup)(void *ptr); 51 | void (*free)(void *ptr); 52 | int (*match)(void *ptr, void *key); 53 | unsigned int len; 54 | } list; 55 | 56 | /* Functions implemented as macros */ 57 | #define listLength(l) ((l)->len) 58 | #define listFirst(l) ((l)->head) 59 | #define listLast(l) ((l)->tail) 60 | #define listPrevNode(n) ((n)->prev) 61 | #define listNextNode(n) ((n)->next) 62 | #define listNodeValue(n) ((n)->value) 63 | 64 | #define listSetDupMethod(l,m) ((l)->dup = (m)) 65 | #define listSetFreeMethod(l,m) ((l)->free = (m)) 66 | #define listSetMatchMethod(l,m) ((l)->match = (m)) 67 | 68 | #define listGetDupMethod(l) ((l)->dup) 69 | #define listGetFree(l) ((l)->free) 70 | #define listGetMatchMethod(l) ((l)->match) 71 | 72 | /* Prototypes */ 73 | list *listCreate(void); 74 | void listRelease(list *list); 75 | list *listAddNodeHead(list *list, void *value); 76 | list *listAddNodeTail(list *list, void *value); 77 | list *listInsertNode(list *list, listNode *old_node, void *value, int after); 78 | void listDelNode(list *list, listNode *node); 79 | listIter *listGetIterator(list *list, int direction); 80 | listNode *listNext(listIter *iter); 81 | void listReleaseIterator(listIter *iter); 82 | list *listDup(list *orig); 83 | listNode *listSearchKey(list *list, void *key); 84 | listNode *listIndex(list *list, int index); 85 | void listRewind(list *list, listIter *li); 86 | void listRewindTail(list *list, listIter *li); 87 | 88 | /* Directions for iterators */ 89 | #define AL_START_HEAD 0 90 | #define AL_START_TAIL 1 91 | 92 | #endif /* __ADLIST_H__ */ 93 | -------------------------------------------------------------------------------- /src/ae_epoll.c: -------------------------------------------------------------------------------- 1 | /* Linux epoll(2) based ae.c module 2 | * Copyright (C) 2009-2010 Salvatore Sanfilippo - antirez@gmail.com 3 | * Released under the BSD license. See the COPYING file for more info. */ 4 | 5 | #include 6 | 7 | typedef struct aeApiState { 8 | int epfd; 9 | struct epoll_event events[AE_SETSIZE]; 10 | } aeApiState; 11 | 12 | static int aeApiCreate(aeEventLoop *eventLoop) { 13 | aeApiState *state = zmalloc(sizeof(aeApiState)); 14 | 15 | if (!state) return -1; 16 | state->epfd = epoll_create(1024); /* 1024 is just an hint for the kernel */ 17 | if (state->epfd == -1) return -1; 18 | eventLoop->apidata = state; 19 | return 0; 20 | } 21 | 22 | static void aeApiFree(aeEventLoop *eventLoop) { 23 | aeApiState *state = eventLoop->apidata; 24 | 25 | close(state->epfd); 26 | zfree(state); 27 | } 28 | 29 | static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) { 30 | aeApiState *state = eventLoop->apidata; 31 | struct epoll_event ee; 32 | /* If the fd was already monitored for some event, we need a MOD 33 | * operation. Otherwise we need an ADD operation. */ 34 | int op = eventLoop->events[fd].mask == AE_NONE ? 35 | EPOLL_CTL_ADD : EPOLL_CTL_MOD; 36 | 37 | ee.events = 0; 38 | mask |= eventLoop->events[fd].mask; /* Merge old events */ 39 | if (mask & AE_READABLE) ee.events |= EPOLLIN; 40 | if (mask & AE_WRITABLE) ee.events |= EPOLLOUT; 41 | ee.data.u64 = 0; /* avoid valgrind warning */ 42 | ee.data.fd = fd; 43 | if (epoll_ctl(state->epfd,op,fd,&ee) == -1) return -1; 44 | return 0; 45 | } 46 | 47 | static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int delmask) { 48 | aeApiState *state = eventLoop->apidata; 49 | struct epoll_event ee; 50 | int mask = eventLoop->events[fd].mask & (~delmask); 51 | 52 | ee.events = 0; 53 | if (mask & AE_READABLE) ee.events |= EPOLLIN; 54 | if (mask & AE_WRITABLE) ee.events |= EPOLLOUT; 55 | ee.data.u64 = 0; /* avoid valgrind warning */ 56 | ee.data.fd = fd; 57 | if (mask != AE_NONE) { 58 | epoll_ctl(state->epfd,EPOLL_CTL_MOD,fd,&ee); 59 | } else { 60 | /* Note, Kernel < 2.6.9 requires a non null event pointer even for 61 | * EPOLL_CTL_DEL. */ 62 | epoll_ctl(state->epfd,EPOLL_CTL_DEL,fd,&ee); 63 | } 64 | } 65 | 66 | static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) { 67 | aeApiState *state = eventLoop->apidata; 68 | int retval, numevents = 0; 69 | 70 | retval = epoll_wait(state->epfd,state->events,AE_SETSIZE, 71 | tvp ? (tvp->tv_sec*1000 + tvp->tv_usec/1000) : -1); 72 | if (retval > 0) { 73 | int j; 74 | 75 | numevents = retval; 76 | for (j = 0; j < numevents; j++) { 77 | int mask = 0; 78 | struct epoll_event *e = state->events+j; 79 | 80 | if (e->events & EPOLLIN) mask |= AE_READABLE; 81 | if (e->events & EPOLLOUT) mask |= AE_WRITABLE; 82 | eventLoop->fired[j].fd = e->data.fd; 83 | eventLoop->fired[j].mask = mask; 84 | } 85 | } 86 | return numevents; 87 | } 88 | 89 | static char *aeApiName(void) { 90 | return "epoll"; 91 | } 92 | -------------------------------------------------------------------------------- /src/ae_kqueue.c: -------------------------------------------------------------------------------- 1 | /* Kqueue(2)-based ae.c module 2 | * Copyright (C) 2009 Harish Mallipeddi - harish.mallipeddi@gmail.com 3 | * Released under the BSD license. See the COPYING file for more info. */ 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | typedef struct aeApiState { 10 | int kqfd; 11 | struct kevent events[AE_SETSIZE]; 12 | } aeApiState; 13 | 14 | static int aeApiCreate(aeEventLoop *eventLoop) { 15 | aeApiState *state = zmalloc(sizeof(aeApiState)); 16 | 17 | if (!state) return -1; 18 | state->kqfd = kqueue(); 19 | if (state->kqfd == -1) return -1; 20 | eventLoop->apidata = state; 21 | 22 | return 0; 23 | } 24 | 25 | static void aeApiFree(aeEventLoop *eventLoop) { 26 | aeApiState *state = eventLoop->apidata; 27 | 28 | close(state->kqfd); 29 | zfree(state); 30 | } 31 | 32 | static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) { 33 | aeApiState *state = eventLoop->apidata; 34 | struct kevent ke; 35 | 36 | if (mask & AE_READABLE) { 37 | EV_SET(&ke, fd, EVFILT_READ, EV_ADD, 0, 0, NULL); 38 | if (kevent(state->kqfd, &ke, 1, NULL, 0, NULL) == -1) return -1; 39 | } 40 | if (mask & AE_WRITABLE) { 41 | EV_SET(&ke, fd, EVFILT_WRITE, EV_ADD, 0, 0, NULL); 42 | if (kevent(state->kqfd, &ke, 1, NULL, 0, NULL) == -1) return -1; 43 | } 44 | return 0; 45 | } 46 | 47 | static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int mask) { 48 | aeApiState *state = eventLoop->apidata; 49 | struct kevent ke; 50 | 51 | if (mask & AE_READABLE) { 52 | EV_SET(&ke, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL); 53 | kevent(state->kqfd, &ke, 1, NULL, 0, NULL); 54 | } 55 | if (mask & AE_WRITABLE) { 56 | EV_SET(&ke, fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL); 57 | kevent(state->kqfd, &ke, 1, NULL, 0, NULL); 58 | } 59 | } 60 | 61 | static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) { 62 | aeApiState *state = eventLoop->apidata; 63 | int retval, numevents = 0; 64 | 65 | if (tvp != NULL) { 66 | struct timespec timeout; 67 | timeout.tv_sec = tvp->tv_sec; 68 | timeout.tv_nsec = tvp->tv_usec * 1000; 69 | retval = kevent(state->kqfd, NULL, 0, state->events, AE_SETSIZE, &timeout); 70 | } else { 71 | retval = kevent(state->kqfd, NULL, 0, state->events, AE_SETSIZE, NULL); 72 | } 73 | 74 | if (retval > 0) { 75 | int j; 76 | 77 | numevents = retval; 78 | for(j = 0; j < numevents; j++) { 79 | int mask = 0; 80 | struct kevent *e = state->events+j; 81 | 82 | if (e->filter == EVFILT_READ) mask |= AE_READABLE; 83 | if (e->filter == EVFILT_WRITE) mask |= AE_WRITABLE; 84 | eventLoop->fired[j].fd = e->ident; 85 | eventLoop->fired[j].mask = mask; 86 | } 87 | } 88 | return numevents; 89 | } 90 | 91 | static char *aeApiName(void) { 92 | return "kqueue"; 93 | } 94 | -------------------------------------------------------------------------------- /src/ae_select.c: -------------------------------------------------------------------------------- 1 | /* Select()-based ae.c module 2 | * Copyright (C) 2009-2010 Salvatore Sanfilippo - antirez@gmail.com 3 | * Released under the BSD license. See the COPYING file for more info. */ 4 | 5 | #include 6 | 7 | typedef struct aeApiState { 8 | fd_set rfds, wfds; 9 | /* We need to have a copy of the fd sets as it's not safe to reuse 10 | * FD sets after select(). */ 11 | fd_set _rfds, _wfds; 12 | } aeApiState; 13 | 14 | static int aeApiCreate(aeEventLoop *eventLoop) { 15 | aeApiState *state = zmalloc(sizeof(aeApiState)); 16 | 17 | if (!state) return -1; 18 | FD_ZERO(&state->rfds); 19 | FD_ZERO(&state->wfds); 20 | eventLoop->apidata = state; 21 | return 0; 22 | } 23 | 24 | static void aeApiFree(aeEventLoop *eventLoop) { 25 | zfree(eventLoop->apidata); 26 | } 27 | 28 | static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) { 29 | aeApiState *state = eventLoop->apidata; 30 | 31 | if (mask & AE_READABLE) FD_SET(fd,&state->rfds); 32 | if (mask & AE_WRITABLE) FD_SET(fd,&state->wfds); 33 | return 0; 34 | } 35 | 36 | static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int mask) { 37 | aeApiState *state = eventLoop->apidata; 38 | 39 | if (mask & AE_READABLE) FD_CLR(fd,&state->rfds); 40 | if (mask & AE_WRITABLE) FD_CLR(fd,&state->wfds); 41 | } 42 | 43 | static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) { 44 | aeApiState *state = eventLoop->apidata; 45 | int retval, j, numevents = 0; 46 | 47 | memcpy(&state->_rfds,&state->rfds,sizeof(fd_set)); 48 | memcpy(&state->_wfds,&state->wfds,sizeof(fd_set)); 49 | 50 | retval = select(eventLoop->maxfd+1, 51 | &state->_rfds,&state->_wfds,NULL,tvp); 52 | if (retval > 0) { 53 | for (j = 0; j <= eventLoop->maxfd; j++) { 54 | int mask = 0; 55 | aeFileEvent *fe = &eventLoop->events[j]; 56 | 57 | if (fe->mask == AE_NONE) continue; 58 | if (fe->mask & AE_READABLE && FD_ISSET(j,&state->_rfds)) 59 | mask |= AE_READABLE; 60 | if (fe->mask & AE_WRITABLE && FD_ISSET(j,&state->_wfds)) 61 | mask |= AE_WRITABLE; 62 | eventLoop->fired[numevents].fd = j; 63 | eventLoop->fired[numevents].mask = mask; 64 | numevents++; 65 | } 66 | } 67 | return numevents; 68 | } 69 | 70 | static char *aeApiName(void) { 71 | return "select"; 72 | } 73 | -------------------------------------------------------------------------------- /src/ae_ws2.c: -------------------------------------------------------------------------------- 1 | /* Select()-based ae.c module 2 | * Copyright (C) 2009-2010 Salvatore Sanfilippo - antirez@gmail.com 3 | * Released under the BSD license. See the COPYING file for more info. */ 4 | 5 | #include 6 | #include "win32fixes.h" 7 | 8 | typedef struct aeApiState { 9 | fd_set rfds, wfds; 10 | /* We need to have a copy of the fd sets as it's not safe to reuse 11 | * FD sets after select(). */ 12 | fd_set _rfds, _wfds; 13 | /* WIN32 select works only on sockets, so we will wati for pipes */ 14 | HANDLE vm_pipe; 15 | } aeApiState; 16 | 17 | static int aeApiCreate(aeEventLoop *eventLoop) { 18 | aeApiState *state = zmalloc(sizeof(aeApiState)); 19 | 20 | if (!state) return -1; 21 | 22 | FD_ZERO(&state->rfds); 23 | FD_ZERO(&state->wfds); 24 | state->vm_pipe = INVALID_HANDLE_VALUE; 25 | 26 | eventLoop->apidata = state; 27 | return 0; 28 | } 29 | 30 | static void aeApiFree(aeEventLoop *eventLoop) { 31 | zfree(eventLoop->apidata); 32 | } 33 | 34 | static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) { 35 | aeApiState *state = eventLoop->apidata; 36 | 37 | if (mask & AE_PIPE) { 38 | state->vm_pipe = (HANDLE) _get_osfhandle(fd); 39 | // DWORD mode = PIPE_NOWAIT; 40 | // SetNamedPipeHandleState(state->vm_pipe,&mode,NULL,NULL); 41 | } else { 42 | if (mask & AE_READABLE) FD_SET((SOCKET)fd,&state->rfds); 43 | if (mask & AE_WRITABLE) FD_SET((SOCKET)fd,&state->wfds); 44 | } 45 | return 0; 46 | } 47 | 48 | static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int mask) { 49 | aeApiState *state = eventLoop->apidata; 50 | 51 | if (mask & AE_PIPE) { 52 | state->vm_pipe = INVALID_HANDLE_VALUE; 53 | } else { 54 | if (mask & AE_READABLE) FD_CLR((SOCKET)fd,&state->rfds); 55 | if (mask & AE_WRITABLE) FD_CLR((SOCKET)fd,&state->wfds); 56 | } 57 | } 58 | 59 | static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) { 60 | aeApiState *state = eventLoop->apidata; 61 | int retval, j, numevents = 0; 62 | DWORD pipe_is_on=0; 63 | 64 | memcpy(&state->_rfds,&state->rfds,sizeof(fd_set)); 65 | memcpy(&state->_wfds,&state->wfds,sizeof(fd_set)); 66 | 67 | retval = select(eventLoop->maxfd+1, 68 | &state->_rfds,&state->_wfds,NULL,tvp); 69 | 70 | if (state->vm_pipe != INVALID_HANDLE_VALUE) { 71 | if (PeekNamedPipe(state->vm_pipe, NULL, 0, NULL, &pipe_is_on, NULL)) { 72 | if (pipe_is_on) retval++; 73 | } 74 | } 75 | 76 | if (retval > 0) { 77 | for (j = 0; j <= eventLoop->maxfd; j++) { 78 | int mask = 0; 79 | aeFileEvent *fe = &eventLoop->events[j]; 80 | 81 | if (fe->mask == AE_NONE) continue; 82 | if (fe->mask & AE_READABLE && FD_ISSET(j,&state->_rfds)) 83 | mask |= AE_READABLE; 84 | if (fe->mask & AE_WRITABLE && FD_ISSET(j,&state->_wfds)) 85 | mask |= AE_WRITABLE; 86 | if (fe->mask & AE_PIPE && pipe_is_on) 87 | mask |= AE_READABLE; 88 | eventLoop->fired[numevents].fd = j; 89 | eventLoop->fired[numevents].mask = mask; 90 | numevents++; 91 | } 92 | } 93 | return numevents; 94 | } 95 | 96 | static char *aeApiName(void) { 97 | return "winsock2"; 98 | } 99 | -------------------------------------------------------------------------------- /src/anet.h: -------------------------------------------------------------------------------- 1 | /* anet.c -- Basic TCP socket stuff made a bit less boring 2 | * 3 | * Copyright (c) 2006-2010, Salvatore Sanfilippo 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * * Neither the name of Redis nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without 16 | * specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef ANET_H 32 | #define ANET_H 33 | 34 | #define ANET_OK 0 35 | #define ANET_ERR -1 36 | #define ANET_ERR_LEN 256 37 | 38 | #if defined(__sun) 39 | #define AF_LOCAL AF_UNIX 40 | #endif 41 | 42 | int anetTcpConnect(char *err, char *addr, int port); 43 | int anetTcpNonBlockConnect(char *err, char *addr, int port); 44 | int anetUnixConnect(char *err, char *path); 45 | int anetUnixNonBlockConnect(char *err, char *path); 46 | int anetRead(int fd, char *buf, int count); 47 | int anetResolve(char *err, char *host, char *ipbuf); 48 | int anetTcpServer(char *err, int port, char *bindaddr); 49 | int anetUnixServer(char *err, char *path, mode_t perm); 50 | int anetTcpAccept(char *err, int serversock, char *ip, int *port); 51 | int anetUnixAccept(char *err, int serversock); 52 | int anetWrite(int fd, char *buf, int count); 53 | int anetNonBlock(char *err, int fd); 54 | int anetTcpNoDelay(char *err, int fd); 55 | int anetTcpKeepAlive(char *err, int fd); 56 | int anetPeerToString(int fd, char *ip, int *port); 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /src/bio.h: -------------------------------------------------------------------------------- 1 | /* Exported API */ 2 | void bioInit(void); 3 | void bioCreateBackgroundJob(int type, void *arg1, void *arg2, void *arg3); 4 | unsigned long long bioPendingJobsOfType(int type); 5 | void bioWaitPendingJobsLE(int type, unsigned long long num); 6 | time_t bioOlderJobOfType(int type); 7 | 8 | /* Background job opcodes */ 9 | #define REDIS_BIO_CLOSE_FILE 0 /* Deferred close(2) syscall. */ 10 | #define REDIS_BIO_AOF_FSYNC 1 /* Deferred AOF fsync. */ 11 | #define REDIS_BIO_NUM_OPS 2 12 | -------------------------------------------------------------------------------- /src/config.h: -------------------------------------------------------------------------------- 1 | #ifndef __CONFIG_H 2 | #define __CONFIG_H 3 | 4 | #ifdef __APPLE__ 5 | #include 6 | #endif 7 | 8 | /* Define redis_fstat to fstat or fstat64() */ 9 | #if defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_6) 10 | #define redis_fstat fstat64 11 | #define redis_stat stat64 12 | #else 13 | #define redis_fstat fstat 14 | #define redis_stat stat 15 | #endif 16 | 17 | /* Test for proc filesystem */ 18 | #ifdef __linux__ 19 | #define HAVE_PROCFS 1 20 | #endif 21 | 22 | /* Test for task_info() */ 23 | #if defined(__APPLE__) 24 | #define HAVE_TASKINFO 1 25 | #endif 26 | 27 | /* Test for backtrace() */ 28 | #if defined(__APPLE__) || defined(__linux__) 29 | #define HAVE_BACKTRACE 1 30 | #endif 31 | 32 | /* Test for polling API */ 33 | #ifdef __linux__ 34 | #define HAVE_EPOLL 1 35 | #endif 36 | 37 | #if (defined(__APPLE__) && defined(MAC_OS_X_VERSION_10_6)) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined (__NetBSD__) 38 | #define HAVE_KQUEUE 1 39 | #endif 40 | 41 | /* Define aof_fsync to fdatasync() in Linux and fsync() for all the rest */ 42 | #ifdef __linux__ 43 | #define aof_fsync fdatasync 44 | #else 45 | #define aof_fsync fsync 46 | #endif 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /src/endian.c: -------------------------------------------------------------------------------- 1 | /* Toggle the 16 bit unsigned integer pointed by *p from little endian to 2 | * big endian */ 3 | void memrev16(void *p) { 4 | unsigned char *x = p, t; 5 | 6 | t = x[0]; 7 | x[0] = x[1]; 8 | x[1] = t; 9 | } 10 | 11 | /* Toggle the 32 bit unsigned integer pointed by *p from little endian to 12 | * big endian */ 13 | void memrev32(void *p) { 14 | unsigned char *x = p, t; 15 | 16 | t = x[0]; 17 | x[0] = x[3]; 18 | x[3] = t; 19 | t = x[1]; 20 | x[1] = x[2]; 21 | x[2] = t; 22 | } 23 | 24 | /* Toggle the 64 bit unsigned integer pointed by *p from little endian to 25 | * big endian */ 26 | void memrev64(void *p) { 27 | unsigned char *x = p, t; 28 | 29 | t = x[0]; 30 | x[0] = x[7]; 31 | x[7] = t; 32 | t = x[1]; 33 | x[1] = x[6]; 34 | x[6] = t; 35 | t = x[2]; 36 | x[2] = x[5]; 37 | x[5] = t; 38 | t = x[3]; 39 | x[3] = x[4]; 40 | x[4] = t; 41 | } 42 | 43 | #ifdef TESTMAIN 44 | #include 45 | 46 | int main(void) { 47 | char buf[32]; 48 | 49 | sprintf(buf,"ciaoroma"); 50 | memrev16(buf); 51 | printf("%s\n", buf); 52 | 53 | sprintf(buf,"ciaoroma"); 54 | memrev32(buf); 55 | printf("%s\n", buf); 56 | 57 | sprintf(buf,"ciaoroma"); 58 | memrev64(buf); 59 | printf("%s\n", buf); 60 | 61 | return 0; 62 | } 63 | #endif 64 | -------------------------------------------------------------------------------- /src/endian.h: -------------------------------------------------------------------------------- 1 | #ifndef __ENDIAN_H 2 | #define __ENDIAN_H 3 | 4 | void memrev16(void *p); 5 | void memrev32(void *p); 6 | void memrev64(void *p); 7 | 8 | /* variants of the function doing the actual convertion only if the target 9 | * host is big endian */ 10 | #if (BYTE_ORDER == LITTLE_ENDIAN) 11 | #define memrev16ifbe(p) 12 | #define memrev32ifbe(p) 13 | #define memrev64ifbe(p) 14 | #else 15 | #define memrev16ifbe(p) memrev16(p) 16 | #define memrev32ifbe(p) memrev32(p) 17 | #define memrev64ifbe(p) memrev64(p) 18 | #endif 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /src/fmacros.h: -------------------------------------------------------------------------------- 1 | #ifndef _REDIS_FMACRO_H 2 | #define _REDIS_FMACRO_H 3 | 4 | #define _BSD_SOURCE 5 | 6 | #if defined(__linux__) || defined(__OpenBSD__) 7 | #define _XOPEN_SOURCE 700 8 | #else 9 | #define _XOPEN_SOURCE 10 | #endif 11 | 12 | #define _LARGEFILE_SOURCE 13 | #define _FILE_OFFSET_BITS 64 14 | 15 | #ifdef _WIN32 16 | #ifdef _WIN64 17 | #define off _off64_t 18 | #else 19 | #define off off_t 20 | #endif 21 | #endif 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/intset.h: -------------------------------------------------------------------------------- 1 | #ifndef __INTSET_H 2 | #define __INTSET_H 3 | #include 4 | 5 | typedef struct intset { 6 | uint32_t encoding; 7 | uint32_t length; 8 | int8_t contents[]; 9 | } intset; 10 | 11 | intset *intsetNew(void); 12 | intset *intsetAdd(intset *is, int64_t value, uint8_t *success); 13 | intset *intsetRemove(intset *is, int64_t value, int *success); 14 | uint8_t intsetFind(intset *is, int64_t value); 15 | int64_t intsetRandom(intset *is); 16 | uint8_t intsetGet(intset *is, uint32_t pos, int64_t *value); 17 | uint32_t intsetLen(intset *is); 18 | size_t intsetBlobLen(intset *is); 19 | 20 | #endif // __INTSET_H 21 | -------------------------------------------------------------------------------- /src/lzf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000-2008 Marc Alexander Lehmann 3 | * 4 | * Redistribution and use in source and binary forms, with or without modifica- 5 | * tion, are permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, 8 | * this list of conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 15 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- 16 | * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 17 | * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- 18 | * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 20 | * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 21 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- 22 | * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 23 | * OF THE POSSIBILITY OF SUCH DAMAGE. 24 | * 25 | * Alternatively, the contents of this file may be used under the terms of 26 | * the GNU General Public License ("GPL") version 2 or any later version, 27 | * in which case the provisions of the GPL are applicable instead of 28 | * the above. If you wish to allow the use of your version of this file 29 | * only under the terms of the GPL and not to allow others to use your 30 | * version of this file under the BSD license, indicate your decision 31 | * by deleting the provisions above and replace them with the notice 32 | * and other provisions required by the GPL. If you do not delete the 33 | * provisions above, a recipient may use your version of this file under 34 | * either the BSD or the GPL. 35 | */ 36 | 37 | #ifndef LZF_H 38 | #define LZF_H 39 | 40 | /*********************************************************************** 41 | ** 42 | ** lzf -- an extremely fast/free compression/decompression-method 43 | ** http://liblzf.plan9.de/ 44 | ** 45 | ** This algorithm is believed to be patent-free. 46 | ** 47 | ***********************************************************************/ 48 | 49 | #define LZF_VERSION 0x0105 /* 1.5, API version */ 50 | 51 | /* 52 | * Compress in_len bytes stored at the memory block starting at 53 | * in_data and write the result to out_data, up to a maximum length 54 | * of out_len bytes. 55 | * 56 | * If the output buffer is not large enough or any error occurs return 0, 57 | * otherwise return the number of bytes used, which might be considerably 58 | * more than in_len (but less than 104% of the original size), so it 59 | * makes sense to always use out_len == in_len - 1), to ensure _some_ 60 | * compression, and store the data uncompressed otherwise (with a flag, of 61 | * course. 62 | * 63 | * lzf_compress might use different algorithms on different systems and 64 | * even different runs, thus might result in different compressed strings 65 | * depending on the phase of the moon or similar factors. However, all 66 | * these strings are architecture-independent and will result in the 67 | * original data when decompressed using lzf_decompress. 68 | * 69 | * The buffers must not be overlapping. 70 | * 71 | * If the option LZF_STATE_ARG is enabled, an extra argument must be 72 | * supplied which is not reflected in this header file. Refer to lzfP.h 73 | * and lzf_c.c. 74 | * 75 | */ 76 | unsigned int 77 | lzf_compress (const void *const in_data, unsigned int in_len, 78 | void *out_data, unsigned int out_len); 79 | 80 | /* 81 | * Decompress data compressed with some version of the lzf_compress 82 | * function and stored at location in_data and length in_len. The result 83 | * will be stored at out_data up to a maximum of out_len characters. 84 | * 85 | * If the output buffer is not large enough to hold the decompressed 86 | * data, a 0 is returned and errno is set to E2BIG. Otherwise the number 87 | * of decompressed bytes (i.e. the original length of the data) is 88 | * returned. 89 | * 90 | * If an error in the compressed data is detected, a zero is returned and 91 | * errno is set to EINVAL. 92 | * 93 | * This function is very fast, about as fast as a copying loop. 94 | */ 95 | unsigned int 96 | lzf_decompress (const void *const in_data, unsigned int in_len, 97 | void *out_data, unsigned int out_len); 98 | 99 | #endif 100 | 101 | -------------------------------------------------------------------------------- /src/mkreleasehdr.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | GIT_SHA1=`(git show-ref --head --hash=8 2> /dev/null || echo 00000000) | head -n1` 3 | GIT_DIRTY=`git diff 2> /dev/null | wc -l` 4 | test -f release.h || touch release.h 5 | (cat release.h | grep SHA1 | grep $GIT_SHA1) && \ 6 | (cat release.h | grep DIRTY | grep $GIT_DIRTY) && exit 0 # Already uptodate 7 | echo "#define REDIS_GIT_SHA1 \"$GIT_SHA1\"" > release.h 8 | echo "#define REDIS_GIT_DIRTY \"$GIT_DIRTY\"" >> release.h 9 | touch release.c # Force recompile of release.c 10 | -------------------------------------------------------------------------------- /src/pqsort.h: -------------------------------------------------------------------------------- 1 | /* The following is the NetBSD libc qsort implementation modified in order to 2 | * support partial sorting of ranges for Redis. 3 | * 4 | * Copyright(C) 2009-2010 Salvatore Sanfilippo. All rights reserved. 5 | * 6 | * See the pqsort.c file for the original copyright notice. */ 7 | 8 | #ifndef __PQSORT_H 9 | #define __PQSORT_H 10 | 11 | void 12 | pqsort(void *a, size_t n, size_t es, 13 | int (*cmp) (const void *, const void *), size_t lrange, size_t rrange); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /src/release.c: -------------------------------------------------------------------------------- 1 | /* Every time the Redis Git SHA1 or Dirty status changes only this file 2 | * small file is recompiled, as we access this information in all the other 3 | * files using this functions. */ 4 | 5 | #include "release.h" 6 | 7 | char *redisGitSHA1(void) { 8 | return REDIS_GIT_SHA1; 9 | } 10 | 11 | char *redisGitDirty(void) { 12 | return REDIS_GIT_DIRTY; 13 | } 14 | -------------------------------------------------------------------------------- /src/sds.h: -------------------------------------------------------------------------------- 1 | /* SDSLib, A C dynamic strings library 2 | * 3 | * Copyright (c) 2006-2010, Salvatore Sanfilippo 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * * Neither the name of Redis nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without 16 | * specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef __SDS_H 32 | #define __SDS_H 33 | 34 | #include 35 | #include 36 | #ifdef _MSC_VER 37 | #include 38 | #endif 39 | 40 | typedef char *sds; 41 | 42 | struct sdshdr { 43 | int len; 44 | int free; 45 | char buf[]; 46 | }; 47 | 48 | static inline size_t sdslen(const sds s) { 49 | struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr))); 50 | return sh->len; 51 | } 52 | 53 | static inline size_t sdsavail(const sds s) { 54 | struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr))); 55 | return sh->free; 56 | } 57 | 58 | sds sdsnewlen(const void *init, size_t initlen); 59 | sds sdsnew(const char *init); 60 | sds sdsempty(); 61 | size_t sdslen(const sds s); 62 | sds sdsdup(const sds s); 63 | void sdsfree(sds s); 64 | size_t sdsavail(sds s); 65 | sds sdsgrowzero(sds s, size_t len); 66 | sds sdscatlen(sds s, void *t, size_t len); 67 | sds sdscat(sds s, char *t); 68 | sds sdscatsds(sds s, sds t); 69 | sds sdscpylen(sds s, char *t, size_t len); 70 | sds sdscpy(sds s, char *t); 71 | 72 | sds sdscatvprintf(sds s, const char *fmt, va_list ap); 73 | #ifdef _WIN32 74 | sds sdscatprintf(sds s, const char *fmt, ...); 75 | #else 76 | #ifdef __GNUC__ 77 | sds sdscatprintf(sds s, const char *fmt, ...) 78 | __attribute__((format(printf, 2, 3))); 79 | #else 80 | sds sdscatprintf(sds s, const char *fmt, ...); 81 | #endif 82 | #endif /* _WIN32 */ 83 | 84 | sds sdstrim(sds s, const char *cset); 85 | sds sdsrange(sds s, int start, int end); 86 | void sdsupdatelen(sds s); 87 | void sdsclear(sds s); 88 | int sdscmp(sds s1, sds s2); 89 | sds *sdssplitlen(char *s, int len, char *sep, int seplen, int *count); 90 | void sdsfreesplitres(sds *tokens, int count); 91 | void sdstolower(sds s); 92 | void sdstoupper(sds s); 93 | sds sdsfromlonglong(long long value); 94 | sds sdscatrepr(sds s, char *p, size_t len); 95 | sds *sdssplitargs(char *line, int *argc); 96 | 97 | #endif 98 | -------------------------------------------------------------------------------- /src/service.rc: -------------------------------------------------------------------------------- 1 | #include 2 | #include "version.h" 3 | #include "release.h" 4 | 5 | #define REDIS_FILE_VERSION_STR REDIS_VERSION "-" REDIS_GIT_SHA1 6 | 7 | #ifdef DEBUG 8 | #define REDIS_FILE_FLAG_DEBUG VS_FF_DEBUG 9 | #else 10 | #define REDIS_FILE_FLAG_DEBUG 0 11 | #endif 12 | 13 | 1 ICON "../setup/redis.ico" 14 | 15 | VS_VERSION_INFO VERSIONINFO 16 | FILEVERSION REDIS_FILE_VERSION 17 | PRODUCTVERSION REDIS_FILE_VERSION 18 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK 19 | FILEFLAGS (VS_FF_PRERELEASE | REDIS_FILE_FLAG_DEBUG) 20 | FILEOS VOS_NT_WINDOWS32 21 | FILETYPE VFT_APP 22 | FILESUBTYPE VFT2_UNKNOWN 23 | BEGIN 24 | BLOCK "StringFileInfo" 25 | BEGIN 26 | BLOCK "040904E4" 27 | BEGIN 28 | VALUE "FileDescription", "Redis Server Windows service" 29 | VALUE "FileVersion", REDIS_FILE_VERSION_STR 30 | VALUE "LegalCopyright", "See http://redis.io/" 31 | VALUE "ProductName", "Redis" 32 | VALUE "ProductVersion", REDIS_FILE_VERSION_STR 33 | END 34 | END 35 | BLOCK "VarFileInfo" 36 | BEGIN 37 | VALUE "Translation", 0x409, 1252 38 | END 39 | END 40 | -------------------------------------------------------------------------------- /src/sha1.h: -------------------------------------------------------------------------------- 1 | /* ================ sha1.h ================ */ 2 | /* 3 | SHA-1 in C 4 | By Steve Reid 5 | 100% Public Domain 6 | */ 7 | 8 | #ifdef _WIN32 9 | #include 10 | #define u_int32_t uint32_t 11 | #endif 12 | typedef struct { 13 | u_int32_t state[5]; 14 | u_int32_t count[2]; 15 | unsigned char buffer[64]; 16 | } SHA1_CTX; 17 | 18 | void SHA1Transform(u_int32_t state[5], const unsigned char buffer[64]); 19 | void SHA1Init(SHA1_CTX* context); 20 | void SHA1Update(SHA1_CTX* context, const unsigned char* data, u_int32_t len); 21 | void SHA1Final(unsigned char digest[20], SHA1_CTX* context); 22 | -------------------------------------------------------------------------------- /src/slowlog.c: -------------------------------------------------------------------------------- 1 | #include "redis.h" 2 | #include "slowlog.h" 3 | 4 | /* Slowlog implements a system that is able to remember the latest N 5 | * queries that took more than M microseconds to execute. 6 | * 7 | * The execution time to reach to be logged in the slow log is set 8 | * using the 'slowlog-log-slower-than' config directive, that is also 9 | * readable and writable using the CONFIG SET/GET command. 10 | * 11 | * The slow queries log is actually not "logged" in the Redis log file 12 | * but is accessible thanks to the SLOWLOG command. */ 13 | 14 | /* Create a new slowlog entry. 15 | * Incrementing the ref count of all the objects retained is up to 16 | * this function. */ 17 | slowlogEntry *slowlogCreateEntry(robj **argv, int argc, long long duration) { 18 | slowlogEntry *se = zmalloc(sizeof(*se)); 19 | int j; 20 | 21 | se->argc = argc; 22 | se->argv = zmalloc(sizeof(robj*)*argc); 23 | for (j = 0; j < argc; j++) { 24 | se->argv[j] = argv[j]; 25 | incrRefCount(argv[j]); 26 | } 27 | se->time = time(NULL); 28 | se->duration = duration; 29 | se->id = server.slowlog_entry_id++; 30 | return se; 31 | } 32 | 33 | /* Free a slow log entry. The argument is void so that the prototype of this 34 | * function matches the one of the 'free' method of adlist.c. 35 | * 36 | * This function will take care to release all the retained object. */ 37 | void slowlogFreeEntry(void *septr) { 38 | slowlogEntry *se = septr; 39 | int j; 40 | 41 | for (j = 0; j < se->argc; j++) 42 | decrRefCount(se->argv[j]); 43 | zfree(se->argv); 44 | zfree(se); 45 | } 46 | 47 | /* Initialize the slow log. This function should be called a single time 48 | * at server startup. */ 49 | void slowlogInit(void) { 50 | server.slowlog = listCreate(); 51 | server.slowlog_entry_id = 0; 52 | listSetFreeMethod(server.slowlog,slowlogFreeEntry); 53 | } 54 | 55 | /* Push a new entry into the slow log. 56 | * This function will make sure to trim the slow log accordingly to the 57 | * configured max length. */ 58 | void slowlogPushEntryIfNeeded(robj **argv, int argc, long long duration) { 59 | if (server.slowlog_log_slower_than < 0) return; /* Slowlog disabled */ 60 | if (duration >= server.slowlog_log_slower_than) 61 | listAddNodeHead(server.slowlog,slowlogCreateEntry(argv,argc,duration)); 62 | 63 | /* Remove old entries if needed. */ 64 | while (listLength(server.slowlog) > server.slowlog_max_len) 65 | listDelNode(server.slowlog,listLast(server.slowlog)); 66 | } 67 | 68 | /* Remove all the entries from the current slow log. */ 69 | void slowlogReset(void) { 70 | while (listLength(server.slowlog) > 0) 71 | listDelNode(server.slowlog,listLast(server.slowlog)); 72 | } 73 | 74 | /* The SLOWLOG command. Implements all the subcommands needed to handle the 75 | * Redis slow log. */ 76 | void slowlogCommand(redisClient *c) { 77 | if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"reset")) { 78 | slowlogReset(); 79 | addReply(c,shared.ok); 80 | } else if (c->argc == 2 && !strcasecmp(c->argv[1]->ptr,"len")) { 81 | addReplyLongLong(c,listLength(server.slowlog)); 82 | } else if ((c->argc == 2 || c->argc == 3) && 83 | !strcasecmp(c->argv[1]->ptr,"get")) 84 | { 85 | #ifdef _WIN64 86 | long long count = 10, sent = 0; 87 | #else 88 | long count = 10, sent = 0; 89 | #endif 90 | listIter li; 91 | void *totentries; 92 | listNode *ln; 93 | slowlogEntry *se; 94 | 95 | if (c->argc == 3 && 96 | getLongFromObjectOrReply(c,c->argv[2],&count,NULL) != REDIS_OK) 97 | return; 98 | 99 | listRewind(server.slowlog,&li); 100 | totentries = addDeferredMultiBulkLength(c); 101 | while(count-- && (ln = listNext(&li))) { 102 | int j; 103 | 104 | se = ln->value; 105 | addReplyMultiBulkLen(c,4); 106 | addReplyLongLong(c,se->id); 107 | addReplyLongLong(c,se->time); 108 | addReplyLongLong(c,se->duration); 109 | addReplyMultiBulkLen(c,se->argc); 110 | for (j = 0; j < se->argc; j++) 111 | addReplyBulk(c,se->argv[j]); 112 | sent++; 113 | } 114 | setDeferredMultiBulkLength(c,totentries,sent); 115 | } else { 116 | addReplyError(c, 117 | "Unknown SLOWLOG subcommand or wrong # of args. Try GET, RESET, LEN."); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/slowlog.h: -------------------------------------------------------------------------------- 1 | /* This structure defines an entry inside the slow log list */ 2 | typedef struct slowlogEntry { 3 | robj **argv; 4 | int argc; 5 | long long id; /* Unique entry identifier. */ 6 | long long duration; /* Time spent by the query, in nanoseconds. */ 7 | time_t time; /* Unix time at which the query was executed. */ 8 | } slowlogEntry; 9 | 10 | /* Exported API */ 11 | void slowlogInit(void); 12 | void slowlogPushEntryIfNeeded(robj **argv, int argc, long long duration); 13 | 14 | /* Exported commands */ 15 | void slowlogCommand(redisClient *c); 16 | -------------------------------------------------------------------------------- /src/solarisfixes.h: -------------------------------------------------------------------------------- 1 | /* Solaris specific fixes */ 2 | 3 | #if defined(__GNUC__) 4 | #include 5 | #undef isnan 6 | #define isnan(x) \ 7 | __extension__({ __typeof (x) __x_a = (x); \ 8 | __builtin_expect(__x_a != __x_a, 0); }) 9 | 10 | #undef isfinite 11 | #define isfinite(x) \ 12 | __extension__ ({ __typeof (x) __x_f = (x); \ 13 | __builtin_expect(!isnan(__x_f - __x_f), 1); }) 14 | 15 | #undef isinf 16 | #define isinf(x) \ 17 | __extension__ ({ __typeof (x) __x_i = (x); \ 18 | __builtin_expect(!isnan(__x_i) && !isfinite(__x_i), 0); }) 19 | 20 | #define u_int uint 21 | #define u_int32_t uint32_t 22 | #endif /* __GNUC__ */ 23 | -------------------------------------------------------------------------------- /src/testhelp.h: -------------------------------------------------------------------------------- 1 | /* This is a really minimal testing framework for C. 2 | * 3 | * Example: 4 | * 5 | * test_cond("Check if 1 == 1", 1==1) 6 | * test_cond("Check if 5 > 10", 5 > 10) 7 | * test_report() 8 | * 9 | * Copyright (c) 2010, Salvatore Sanfilippo 10 | * All rights reserved. 11 | * 12 | * Redistribution and use in source and binary forms, with or without 13 | * modification, are permitted provided that the following conditions are met: 14 | * 15 | * * Redistributions of source code must retain the above copyright notice, 16 | * this list of conditions and the following disclaimer. 17 | * * Redistributions in binary form must reproduce the above copyright 18 | * notice, this list of conditions and the following disclaimer in the 19 | * documentation and/or other materials provided with the distribution. 20 | * * Neither the name of Redis nor the names of its contributors may be used 21 | * to endorse or promote products derived from this software without 22 | * specific prior written permission. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 25 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 28 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 29 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 30 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 31 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 32 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 | * POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | #ifndef __TESTHELP_H 38 | #define __TESTHELP_H 39 | 40 | int __failed_tests = 0; 41 | int __test_num = 0; 42 | #define test_cond(descr,_c) do { \ 43 | __test_num++; printf("%d - %s: ", __test_num, descr); \ 44 | if(_c) printf("PASSED\n"); else {printf("FAILED\n"); __failed_tests++;} \ 45 | } while(0); 46 | #define test_report() do { \ 47 | printf("%d tests, %d passed, %d failed\n", __test_num, \ 48 | __test_num-__failed_tests, __failed_tests); \ 49 | if (__failed_tests) { \ 50 | printf("=== WARNING === We have failed tests here...\n"); \ 51 | } \ 52 | } while(0); 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/util.h: -------------------------------------------------------------------------------- 1 | #ifndef __REDIS_UTIL_H 2 | #define __REDIS_UTIL_H 3 | 4 | int stringmatchlen(const char *p, int plen, const char *s, int slen, int nocase); 5 | int stringmatch(const char *p, const char *s, int nocase); 6 | long long memtoll(const char *p, int *err); 7 | int ll2string(char *s, size_t len, long long value); 8 | int string2ll(char *s, size_t slen, long long *value); 9 | int string2l(char *s, size_t slen, long *value); 10 | int d2string(char *buf, size_t len, double value); 11 | long long ustime(void); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /src/valgrind.sup: -------------------------------------------------------------------------------- 1 | { 2 | 3 | Memcheck:Cond 4 | fun:lzf_compress 5 | } 6 | -------------------------------------------------------------------------------- /src/version.h: -------------------------------------------------------------------------------- 1 | #define REDIS_VERSION "2.4.6" 2 | #define REDIS_FILE_VERSION 2,4,6,0 3 | -------------------------------------------------------------------------------- /src/win32err.h: -------------------------------------------------------------------------------- 1 | /* 2 | */ 3 | 4 | #include 5 | #include 6 | 7 | char * redis_strerror(int code) { 8 | 9 | switch(code) { 10 | case 10004: return "Interrupted system call"; 11 | case 10009: return "Bad file number"; 12 | case 10013: return "Permission denied"; 13 | case 10014: return "Bad address"; 14 | case 10022: return "Invalid argument (not bind)"; 15 | case 10024: return "Too many open files"; 16 | case 10035: return "Operation would block"; 17 | case 10036: return "Operation now in progress"; 18 | case 10037: return "Operation already in progress"; 19 | case 10038: return "Socket operation on non-socket"; 20 | case 10039: return "Destination address required"; 21 | case 10040: return "Message too long"; 22 | case 10041: return "Protocol wrong type for socket"; 23 | case 10042: return "Bad protocol option"; 24 | case 10043: return "Protocol not supported"; 25 | case 10044: return "Socket type not supported"; 26 | case 10045: return "Operation not supported on socket"; 27 | case 10046: return "Protocol family not supported"; 28 | case 10047: return "Address family not supported by protocol family"; 29 | case 10048: return "Address already in use"; 30 | case 10049: return "Can't assign requested address"; 31 | case 10050: return "Network is down"; 32 | case 10051: return "Network is unreachable"; 33 | case 10052: return "Net dropped connection or reset"; 34 | case 10053: return "Software caused connection abort"; 35 | case 10054: return "Connection reset by peer"; 36 | case 10055: return "No buffer space available"; 37 | case 10056: return "Socket is already connected"; 38 | case 10057: return "Socket is not connected"; 39 | case 10058: return "Can't send after socket shutdown"; 40 | case 10059: return "Too many references, can't splice"; 41 | case 10060: return "Connection timed out"; 42 | case 10061: return "Connection refused"; 43 | case 10062: return "Too many levels of symbolic links"; 44 | case 10063: return "File name too long"; 45 | case 10064: return "Host is down"; 46 | case 10065: return "No Route to Host"; 47 | case 10066: return "Directory not empty"; 48 | case 10067: return "Too many processes"; 49 | case 10068: return "Too many users"; 50 | case 10069: return "Disc Quota Exceeded"; 51 | case 10070: return "Stale NFS file handle"; 52 | case 10091: return "Network SubSystem is unavailable"; 53 | case 10092: return "WINSOCK DLL Version out of range"; 54 | case 10093: return "Successful WSASTARTUP not yet performed"; 55 | case 10071: return "Too many levels of remote in path"; 56 | case 11001: return "Host not found"; 57 | case 11002: return "Non-Authoritative Host not found"; 58 | case 11003: return "Non-Recoverable errors: FORMERR, REFUSED, NOTIMP"; 59 | case 11004: return "Valid name, no data record of requested type"; 60 | default: return strerror(code); 61 | } 62 | } 63 | 64 | -------------------------------------------------------------------------------- /src/ziplist.h: -------------------------------------------------------------------------------- 1 | #define ZIPLIST_HEAD 0 2 | #define ZIPLIST_TAIL 1 3 | 4 | unsigned char *ziplistNew(void); 5 | unsigned char *ziplistPush(unsigned char *zl, unsigned char *s, unsigned int slen, int where); 6 | unsigned char *ziplistIndex(unsigned char *zl, int index); 7 | unsigned char *ziplistNext(unsigned char *zl, unsigned char *p); 8 | unsigned char *ziplistPrev(unsigned char *zl, unsigned char *p); 9 | unsigned int ziplistGet(unsigned char *p, unsigned char **sval, unsigned int *slen, long long *lval); 10 | unsigned char *ziplistInsert(unsigned char *zl, unsigned char *p, unsigned char *s, unsigned int slen); 11 | unsigned char *ziplistDelete(unsigned char *zl, unsigned char **p); 12 | unsigned char *ziplistDeleteRange(unsigned char *zl, unsigned int index, unsigned int num); 13 | unsigned int ziplistCompare(unsigned char *p, unsigned char *s, unsigned int slen); 14 | unsigned int ziplistLen(unsigned char *zl); 15 | size_t ziplistBlobLen(unsigned char *zl); 16 | -------------------------------------------------------------------------------- /src/zipmap.h: -------------------------------------------------------------------------------- 1 | /* String -> String Map data structure optimized for size. 2 | * 3 | * See zipmap.c for more info. 4 | * 5 | * -------------------------------------------------------------------------- 6 | * 7 | * Copyright (c) 2009-2010, Salvatore Sanfilippo 8 | * All rights reserved. 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions are met: 12 | * 13 | * * Redistributions of source code must retain the above copyright notice, 14 | * this list of conditions and the following disclaimer. 15 | * * Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * * Neither the name of Redis nor the names of its contributors may be used 19 | * to endorse or promote products derived from this software without 20 | * specific prior written permission. 21 | * 22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 23 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 26 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 | * POSSIBILITY OF SUCH DAMAGE. 33 | */ 34 | 35 | #ifndef _ZIMMAP_H 36 | #define _ZIPMAP_H 37 | 38 | unsigned char *zipmapNew(void); 39 | unsigned char *zipmapSet(unsigned char *zm, unsigned char *key, unsigned int klen, unsigned char *val, unsigned int vlen, int *update); 40 | unsigned char *zipmapDel(unsigned char *zm, unsigned char *key, unsigned int klen, int *deleted); 41 | unsigned char *zipmapRewind(unsigned char *zm); 42 | unsigned char *zipmapNext(unsigned char *zm, unsigned char **key, unsigned int *klen, unsigned char **value, unsigned int *vlen); 43 | int zipmapGet(unsigned char *zm, unsigned char *key, unsigned int klen, unsigned char **value, unsigned int *vlen); 44 | int zipmapExists(unsigned char *zm, unsigned char *key, unsigned int klen); 45 | unsigned int zipmapLen(unsigned char *zm); 46 | size_t zipmapBlobLen(unsigned char *zm); 47 | void zipmapRepr(unsigned char *p); 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /src/zmalloc.h: -------------------------------------------------------------------------------- 1 | /* zmalloc - total amount of allocated memory aware version of malloc() 2 | * 3 | * Copyright (c) 2009-2010, Salvatore Sanfilippo 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are met: 8 | * 9 | * * Redistributions of source code must retain the above copyright notice, 10 | * this list of conditions and the following disclaimer. 11 | * * Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * * Neither the name of Redis nor the names of its contributors may be used 15 | * to endorse or promote products derived from this software without 16 | * specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 | * POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef __ZMALLOC_H 32 | #define __ZMALLOC_H 33 | 34 | /* Double expansion needed for stringification of macro values. */ 35 | #define __xstr(s) __str(s) 36 | #define __str(s) #s 37 | 38 | #if defined(USE_TCMALLOC) 39 | #define ZMALLOC_LIB ("tcmalloc-" __xstr(TC_VERSION_MAJOR) "." __xstr(TC_VERSION_MINOR)) 40 | #include 41 | #if TC_VERSION_MAJOR >= 1 && TC_VERSION_MINOR >= 6 42 | #define HAVE_MALLOC_SIZE 1 43 | #define zmalloc_size(p) tc_malloc_size(p) 44 | #else 45 | #error "Newer version of tcmalloc required" 46 | #endif 47 | 48 | #elif defined(USE_JEMALLOC) 49 | #define ZMALLOC_LIB ("jemalloc-" __xstr(JEMALLOC_VERSION_MAJOR) "." __xstr(JEMALLOC_VERSION_MINOR) "." __xstr(JEMALLOC_VERSION_BUGFIX)) 50 | #define JEMALLOC_MANGLE 51 | #include 52 | #if JEMALLOC_VERSION_MAJOR >= 2 && JEMALLOC_VERSION_MINOR >= 1 53 | #define HAVE_MALLOC_SIZE 1 54 | #define zmalloc_size(p) JEMALLOC_P(malloc_usable_size)(p) 55 | #else 56 | #error "Newer version of jemalloc required" 57 | #endif 58 | 59 | #elif defined(__APPLE__) 60 | #include 61 | #define HAVE_MALLOC_SIZE 1 62 | #define zmalloc_size(p) malloc_size(p) 63 | #endif 64 | 65 | #ifndef ZMALLOC_LIB 66 | #define ZMALLOC_LIB "libc" 67 | #endif 68 | 69 | void *zmalloc(size_t size); 70 | void *zcalloc(size_t size); 71 | void *zrealloc(void *ptr, size_t size); 72 | void zfree(void *ptr); 73 | char *zstrdup(const char *s); 74 | size_t zmalloc_used_memory(void); 75 | void zmalloc_enable_thread_safeness(void); 76 | float zmalloc_get_fragmentation_ratio(void); 77 | size_t zmalloc_get_rss(void); 78 | #ifdef _WIN32 79 | void zmalloc_free_used_memory_mutex(void); 80 | #endif 81 | 82 | #endif /* __ZMALLOC_H */ 83 | -------------------------------------------------------------------------------- /tests/helpers/gen_write_load.tcl: -------------------------------------------------------------------------------- 1 | source tests/support/redis.tcl 2 | 3 | proc gen_write_load {host port seconds} { 4 | set start_time [clock seconds] 5 | set r [redis $host $port 1] 6 | $r select 9 7 | while 1 { 8 | $r set [expr rand()] [expr rand()] 9 | if {[clock seconds]-$start_time > $seconds} { 10 | exit 0 11 | } 12 | } 13 | } 14 | 15 | gen_write_load [lindex $argv 0] [lindex $argv 1] [lindex $argv 2] 16 | -------------------------------------------------------------------------------- /tests/integration/aof-race.tcl: -------------------------------------------------------------------------------- 1 | set defaults { appendonly {yes} appendfilename {appendonly.aof} } 2 | set server_path [tmpdir server.aof] 3 | set aof_path "$server_path/appendonly.aof" 4 | 5 | proc start_server_aof {overrides code} { 6 | upvar defaults defaults srv srv server_path server_path 7 | set config [concat $defaults $overrides] 8 | start_server [list overrides $config] $code 9 | } 10 | 11 | tags {"aof"} { 12 | # Specific test for a regression where internal buffers were not properly 13 | # cleaned after a child responsible for an AOF rewrite exited. This buffer 14 | # was subsequently appended to the new AOF, resulting in duplicate commands. 15 | start_server_aof [list dir $server_path] { 16 | set client [redis [srv host] [srv port]] 17 | set bench [open "|src/redis-benchmark -q -p [srv port] -c 20 -n 20000 incr foo" "r+"] 18 | after 100 19 | 20 | # Benchmark should be running by now: start background rewrite 21 | $client bgrewriteaof 22 | 23 | # Read until benchmark pipe reaches EOF 24 | while {[string length [read $bench]] > 0} {} 25 | 26 | # Check contents of foo 27 | assert_equal 20000 [$client get foo] 28 | } 29 | 30 | # Restart server to replay AOF 31 | start_server_aof [list dir $server_path] { 32 | set client [redis [srv host] [srv port]] 33 | assert_equal 20000 [$client get foo] 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /tests/integration/replication-2.tcl: -------------------------------------------------------------------------------- 1 | start_server {tags {"repl"}} { 2 | start_server {} { 3 | test {First server should have role slave after SLAVEOF} { 4 | r -1 slaveof [srv 0 host] [srv 0 port] 5 | after 1000 6 | s -1 role 7 | } {slave} 8 | 9 | test {MASTER and SLAVE dataset should be identical after complex ops} { 10 | createComplexDataset r 10000 11 | after 500 12 | if {[r debug digest] ne [r -1 debug digest]} { 13 | set csv1 [csvdump r] 14 | set csv2 [csvdump {r -1}] 15 | set fd [open /tmp/repldump1.txt w] 16 | puts -nonewline $fd $csv1 17 | close $fd 18 | set fd [open /tmp/repldump2.txt w] 19 | puts -nonewline $fd $csv2 20 | close $fd 21 | puts "Master - Slave inconsistency" 22 | puts "Run diff -u against /tmp/repldump*.txt for more info" 23 | } 24 | assert_equal [r debug digest] [r -1 debug digest] 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tests/integration/replication-3.tcl: -------------------------------------------------------------------------------- 1 | start_server {tags {"repl"}} { 2 | start_server {} { 3 | test {First server should have role slave after SLAVEOF} { 4 | r -1 slaveof [srv 0 host] [srv 0 port] 5 | after 1000 6 | s -1 role 7 | } {slave} 8 | 9 | if {$::accurate} {set numops 50000} else {set numops 5000} 10 | 11 | test {MASTER and SLAVE consistency with expire} { 12 | createComplexDataset r $numops useexpire 13 | after 4000 ;# Make sure everything expired before taking the digest 14 | r keys * ;# Force DEL syntesizing to slave 15 | after 1000 ;# Wait another second. Now everything should be fine. 16 | if {[r debug digest] ne [r -1 debug digest]} { 17 | set csv1 [csvdump r] 18 | set csv2 [csvdump {r -1}] 19 | set fd [open /tmp/repldump1.txt w] 20 | puts -nonewline $fd $csv1 21 | close $fd 22 | set fd [open /tmp/repldump2.txt w] 23 | puts -nonewline $fd $csv2 24 | close $fd 25 | puts "Master - Slave inconsistency" 26 | puts "Run diff -u against /tmp/repldump*.txt for more info" 27 | } 28 | assert_equal [r debug digest] [r -1 debug digest] 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/support/test.tcl: -------------------------------------------------------------------------------- 1 | set ::num_tests 0 2 | set ::num_passed 0 3 | set ::num_failed 0 4 | set ::tests_failed {} 5 | 6 | proc assert {condition} { 7 | if {![uplevel 1 [list expr $condition]]} { 8 | error "assertion:Expected condition '$condition' to be true ([uplevel 1 [list subst -nocommands $condition]])" 9 | } 10 | } 11 | 12 | proc assert_match {pattern value} { 13 | if {![string match $pattern $value]} { 14 | error "assertion:Expected '$value' to match '$pattern'" 15 | } 16 | } 17 | 18 | proc assert_equal {expected value} { 19 | if {$expected ne $value} { 20 | error "assertion:Expected '$value' to be equal to '$expected'" 21 | } 22 | } 23 | 24 | proc assert_error {pattern code} { 25 | if {[catch {uplevel 1 $code} error]} { 26 | assert_match $pattern $error 27 | } else { 28 | error "assertion:Expected an error but nothing was catched" 29 | } 30 | } 31 | 32 | proc assert_encoding {enc key} { 33 | # Swapped out values don't have an encoding, so make sure that 34 | # the value is swapped in before checking the encoding. 35 | set dbg [r debug object $key] 36 | while {[string match "* swapped at:*" $dbg]} { 37 | r debug swapin $key 38 | set dbg [r debug object $key] 39 | } 40 | assert_match "* encoding:$enc *" $dbg 41 | } 42 | 43 | proc assert_type {type key} { 44 | assert_equal $type [r type $key] 45 | } 46 | 47 | # Test if TERM looks like to support colors 48 | proc color_term {} { 49 | expr {[info exists ::env(TERM)] && [string match *xterm* $::env(TERM)]} 50 | } 51 | 52 | proc colorstr {color str} { 53 | if {[color_term]} { 54 | set b 0 55 | if {[string range $color 0 4] eq {bold-}} { 56 | set b 1 57 | set color [string range $color 5 end] 58 | } 59 | switch $color { 60 | red {set colorcode {31}} 61 | green {set colorcode {32}} 62 | yellow {set colorcode {33}} 63 | blue {set colorcode {34}} 64 | magenta {set colorcode {35}} 65 | cyan {set colorcode {36}} 66 | white {set colorcode {37}} 67 | default {set colorcode {37}} 68 | } 69 | if {$colorcode ne {}} { 70 | return "\033\[$b;${colorcode};40m$str\033\[0m" 71 | } 72 | } else { 73 | return $str 74 | } 75 | } 76 | 77 | proc test {name code {okpattern undefined}} { 78 | # abort if tagged with a tag to deny 79 | foreach tag $::denytags { 80 | if {[lsearch $::tags $tag] >= 0} { 81 | return 82 | } 83 | } 84 | 85 | # check if tagged with at least 1 tag to allow when there *is* a list 86 | # of tags to allow, because default policy is to run everything 87 | if {[llength $::allowtags] > 0} { 88 | set matched 0 89 | foreach tag $::allowtags { 90 | if {[lsearch $::tags $tag] >= 0} { 91 | incr matched 92 | } 93 | } 94 | if {$matched < 1} { 95 | return 96 | } 97 | } 98 | 99 | incr ::num_tests 100 | set details {} 101 | lappend details "$name in $::curfile" 102 | 103 | send_data_packet $::test_server_fd testing $name 104 | 105 | if {[catch {set retval [uplevel 1 $code]} error]} { 106 | if {[string match "assertion:*" $error]} { 107 | set msg [string range $error 10 end] 108 | lappend details $msg 109 | lappend ::tests_failed $details 110 | 111 | incr ::num_failed 112 | send_data_packet $::test_server_fd err [join $details "\n"] 113 | } else { 114 | # Re-raise, let handler up the stack take care of this. 115 | error $error $::errorInfo 116 | } 117 | } else { 118 | if {$okpattern eq "undefined" || $okpattern eq $retval || [string match $okpattern $retval]} { 119 | incr ::num_passed 120 | send_data_packet $::test_server_fd ok $name 121 | } else { 122 | set msg "Expected '$okpattern' to equal or match '$retval'" 123 | lappend details $msg 124 | lappend ::tests_failed $details 125 | 126 | incr ::num_failed 127 | send_data_packet $::test_server_fd err [join $details "\n"] 128 | } 129 | } 130 | 131 | if {$::traceleaks} { 132 | set output [exec leaks redis-server] 133 | if {![string match {*0 leaks*} $output]} { 134 | send_data_packet $::test_server_fd err "Detected a memory leak in test '$name': $output" 135 | } 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /tests/support/tmpfile.tcl: -------------------------------------------------------------------------------- 1 | set ::tmpcounter 0 2 | set ::tmproot "./tests/tmp" 3 | file mkdir $::tmproot 4 | 5 | # returns a dirname unique to this process to write to 6 | proc tmpdir {basename} { 7 | set dir [file join $::tmproot $basename.[pid].[incr ::tmpcounter]] 8 | file mkdir $dir 9 | set _ $dir 10 | } 11 | 12 | # return a filename unique to this process to write to 13 | proc tmpfile {basename} { 14 | file join $::tmproot $basename.[pid].[incr ::tmpcounter] 15 | } 16 | -------------------------------------------------------------------------------- /tests/tmp/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | -------------------------------------------------------------------------------- /tests/unit/auth.tcl: -------------------------------------------------------------------------------- 1 | start_server {tags {"auth"}} { 2 | test {AUTH fails if there is no password configured server side} { 3 | catch {r auth foo} err 4 | set _ $err 5 | } {ERR*no password*} 6 | } 7 | 8 | start_server {tags {"auth"} overrides {requirepass foobar}} { 9 | test {AUTH fails when a wrong password is given} { 10 | catch {r auth wrong!} err 11 | set _ $err 12 | } {ERR*invalid password} 13 | 14 | test {Arbitrary command gives an error when AUTH is required} { 15 | catch {r set foo bar} err 16 | set _ $err 17 | } {ERR*operation not permitted} 18 | 19 | test {AUTH succeeds when the right password is given} { 20 | r auth foobar 21 | } {OK} 22 | 23 | test {Once AUTH succeeded we can actually send commands to the server} { 24 | r set foo 100 25 | r incr foo 26 | } {101} 27 | } 28 | -------------------------------------------------------------------------------- /tests/unit/cas.tcl: -------------------------------------------------------------------------------- 1 | start_server {tags {"cas"}} { 2 | test {EXEC works on WATCHed key not modified} { 3 | r watch x y z 4 | r watch k 5 | r multi 6 | r ping 7 | r exec 8 | } {PONG} 9 | 10 | test {EXEC fail on WATCHed key modified (1 key of 1 watched)} { 11 | r set x 30 12 | r watch x 13 | r set x 40 14 | r multi 15 | r ping 16 | r exec 17 | } {} 18 | 19 | test {EXEC fail on WATCHed key modified (1 key of 5 watched)} { 20 | r set x 30 21 | r watch a b x k z 22 | r set x 40 23 | r multi 24 | r ping 25 | r exec 26 | } {} 27 | 28 | test {After successful EXEC key is no longer watched} { 29 | r set x 30 30 | r watch x 31 | r multi 32 | r ping 33 | r exec 34 | r set x 40 35 | r multi 36 | r ping 37 | r exec 38 | } {PONG} 39 | 40 | test {After failed EXEC key is no longer watched} { 41 | r set x 30 42 | r watch x 43 | r set x 40 44 | r multi 45 | r ping 46 | r exec 47 | r set x 40 48 | r multi 49 | r ping 50 | r exec 51 | } {PONG} 52 | 53 | test {It is possible to UNWATCH} { 54 | r set x 30 55 | r watch x 56 | r set x 40 57 | r unwatch 58 | r multi 59 | r ping 60 | r exec 61 | } {PONG} 62 | 63 | test {UNWATCH when there is nothing watched works as expected} { 64 | r unwatch 65 | } {OK} 66 | 67 | test {FLUSHALL is able to touch the watched keys} { 68 | r set x 30 69 | r watch x 70 | r flushall 71 | r multi 72 | r ping 73 | r exec 74 | } {} 75 | 76 | test {FLUSHALL does not touch non affected keys} { 77 | r del x 78 | r watch x 79 | r flushall 80 | r multi 81 | r ping 82 | r exec 83 | } {PONG} 84 | 85 | test {FLUSHDB is able to touch the watched keys} { 86 | r set x 30 87 | r watch x 88 | r flushdb 89 | r multi 90 | r ping 91 | r exec 92 | } {} 93 | 94 | test {FLUSHDB does not touch non affected keys} { 95 | r del x 96 | r watch x 97 | r flushdb 98 | r multi 99 | r ping 100 | r exec 101 | } {PONG} 102 | 103 | test {WATCH is able to remember the DB a key belongs to} { 104 | r select 5 105 | r set x 30 106 | r watch x 107 | r select 1 108 | r set x 10 109 | r select 5 110 | r multi 111 | r ping 112 | r exec 113 | } {PONG} 114 | 115 | test {WATCH will consider touched keys target of EXPIRE} { 116 | r del x 117 | r set x foo 118 | r watch x 119 | r expire x 10 120 | r multi 121 | r ping 122 | r exec 123 | } {} 124 | 125 | test {WATCH will not consider touched expired keys} { 126 | r del x 127 | r set x foo 128 | r expire x 1 129 | r watch x 130 | after 1100 131 | r multi 132 | r ping 133 | r exec 134 | } {PONG} 135 | 136 | test {DISCARD should clear the WATCH dirty flag on the client} { 137 | r watch x 138 | r set x 10 139 | r multi 140 | r discard 141 | r multi 142 | r incr x 143 | r exec 144 | } {11} 145 | 146 | test {DISCARD should UNWATCH all the keys} { 147 | r watch x 148 | r set x 10 149 | r multi 150 | r discard 151 | r set x 10 152 | r multi 153 | r incr x 154 | r exec 155 | } {11} 156 | } 157 | -------------------------------------------------------------------------------- /tests/unit/expire.tcl: -------------------------------------------------------------------------------- 1 | start_server {tags {"expire"}} { 2 | test {EXPIRE - set timeouts multiple times} { 3 | r set x foobar 4 | set v1 [r expire x 5] 5 | set v2 [r ttl x] 6 | set v3 [r expire x 10] 7 | set v4 [r ttl x] 8 | r expire x 4 9 | list $v1 $v2 $v3 $v4 10 | } {1 [45] 1 10} 11 | 12 | test {EXPIRE - It should be still possible to read 'x'} { 13 | r get x 14 | } {foobar} 15 | 16 | tags {"slow"} { 17 | test {EXPIRE - After 6 seconds the key should no longer be here} { 18 | after 6000 19 | list [r get x] [r exists x] 20 | } {{} 0} 21 | } 22 | 23 | test {EXPIRE - write on expire should work} { 24 | r del x 25 | r lpush x foo 26 | r expire x 1000 27 | r lpush x bar 28 | r lrange x 0 -1 29 | } {bar foo} 30 | 31 | test {EXPIREAT - Check for EXPIRE alike behavior} { 32 | r del x 33 | r set x foo 34 | r expireat x [expr [clock seconds]+15] 35 | r ttl x 36 | } {1[345]} 37 | 38 | test {SETEX - Set + Expire combo operation. Check for TTL} { 39 | r setex x 12 test 40 | r ttl x 41 | } {1[012]} 42 | 43 | test {SETEX - Check value} { 44 | r get x 45 | } {test} 46 | 47 | test {SETEX - Overwrite old key} { 48 | r setex y 1 foo 49 | r get y 50 | } {foo} 51 | 52 | tags {"slow"} { 53 | test {SETEX - Wait for the key to expire} { 54 | after 3000 55 | r get y 56 | } {} 57 | } 58 | 59 | test {SETEX - Wrong time parameter} { 60 | catch {r setex z -10 foo} e 61 | set _ $e 62 | } {*invalid expire*} 63 | 64 | test {PERSIST can undo an EXPIRE} { 65 | r set x foo 66 | r expire x 50 67 | list [r ttl x] [r persist x] [r ttl x] [r get x] 68 | } {50 1 -1 foo} 69 | 70 | test {PERSIST returns 0 against non existing or non volatile keys} { 71 | r set x foo 72 | list [r persist foo] [r persist nokeyatall] 73 | } {0 0} 74 | } 75 | -------------------------------------------------------------------------------- /tests/unit/introspection.tcl: -------------------------------------------------------------------------------- 1 | start_server {tags {"introspection"}} { 2 | test {CLIENT LIST} { 3 | r client list 4 | } {*addr=*:* fd=* idle=* flags=N db=9 sub=0 psub=0 qbuf=0 obl=0 oll=0 events=r cmd=client*} 5 | } 6 | -------------------------------------------------------------------------------- /tests/unit/printver.tcl: -------------------------------------------------------------------------------- 1 | start_server {} { 2 | set i [r info] 3 | regexp {redis_version:(.*?)\r\n} $i - version 4 | regexp {redis_git_sha1:(.*?)\r\n} $i - sha1 5 | puts "Testing Redis version $version ($sha1)" 6 | } 7 | -------------------------------------------------------------------------------- /tests/unit/protocol.tcl: -------------------------------------------------------------------------------- 1 | start_server {tags {"protocol"}} { 2 | test "Handle an empty query" { 3 | reconnect 4 | r write "\r\n" 5 | r flush 6 | assert_equal "PONG" [r ping] 7 | } 8 | 9 | test "Negative multibulk length" { 10 | reconnect 11 | r write "*-10\r\n" 12 | r flush 13 | assert_equal PONG [r ping] 14 | } 15 | 16 | test "Out of range multibulk length" { 17 | reconnect 18 | r write "*20000000\r\n" 19 | r flush 20 | assert_error "*invalid multibulk length*" {r read} 21 | } 22 | 23 | test "Wrong multibulk payload header" { 24 | reconnect 25 | r write "*3\r\n\$3\r\nSET\r\n\$1\r\nx\r\nfooz\r\n" 26 | r flush 27 | assert_error "*expected '$', got 'f'*" {r read} 28 | } 29 | 30 | test "Negative multibulk payload length" { 31 | reconnect 32 | r write "*3\r\n\$3\r\nSET\r\n\$1\r\nx\r\n\$-10\r\n" 33 | r flush 34 | assert_error "*invalid bulk length*" {r read} 35 | } 36 | 37 | test "Out of range multibulk payload length" { 38 | reconnect 39 | r write "*3\r\n\$3\r\nSET\r\n\$1\r\nx\r\n\$2000000000\r\n" 40 | r flush 41 | assert_error "*invalid bulk length*" {r read} 42 | } 43 | 44 | test "Non-number multibulk payload length" { 45 | reconnect 46 | r write "*3\r\n\$3\r\nSET\r\n\$1\r\nx\r\n\$blabla\r\n" 47 | r flush 48 | assert_error "*invalid bulk length*" {r read} 49 | } 50 | 51 | test "Multi bulk request not followed by bulk arguments" { 52 | reconnect 53 | r write "*1\r\nfoo\r\n" 54 | r flush 55 | assert_error "*expected '$', got 'f'*" {r read} 56 | } 57 | 58 | test "Generic wrong number of args" { 59 | reconnect 60 | assert_error "*wrong*arguments*ping*" {r ping x y z} 61 | } 62 | 63 | set c 0 64 | foreach seq [list "\x00" "*\x00" "$\x00"] { 65 | incr c 66 | test "Protocol desync regression test #$c" { 67 | set s [socket [srv 0 host] [srv 0 port]] 68 | puts -nonewline $s $seq 69 | set payload [string repeat A 1024]"\n" 70 | set test_start [clock seconds] 71 | set test_time_limit 5 72 | while 1 { 73 | if {[catch { 74 | puts -nonewline $s payload 75 | flush $s 76 | incr payload_size [string length $payload] 77 | }]} { 78 | set retval [gets $s] 79 | close $s 80 | break 81 | } else { 82 | set elapsed [expr {[clock seconds]-$test_start}] 83 | if {$elapsed > $test_time_limit} { 84 | close $s 85 | error "assertion:Redis did not closed connection after protocol desync" 86 | } 87 | } 88 | } 89 | set retval 90 | } {*Protocol error*} 91 | } 92 | unset c 93 | } 94 | -------------------------------------------------------------------------------- /tests/unit/quit.tcl: -------------------------------------------------------------------------------- 1 | start_server {tags {"quit"}} { 2 | proc format_command {args} { 3 | set cmd "*[llength $args]\r\n" 4 | foreach a $args { 5 | append cmd "$[string length $a]\r\n$a\r\n" 6 | } 7 | set _ $cmd 8 | } 9 | 10 | test "QUIT returns OK" { 11 | reconnect 12 | assert_equal OK [r quit] 13 | assert_error * {r ping} 14 | } 15 | 16 | test "Pipelined commands after QUIT must not be executed" { 17 | reconnect 18 | r write [format_command quit] 19 | r write [format_command set foo bar] 20 | r flush 21 | assert_equal OK [r read] 22 | assert_error * {r read} 23 | 24 | reconnect 25 | assert_equal {} [r get foo] 26 | } 27 | 28 | test "Pipelined commands after QUIT that exceed read buffer size" { 29 | reconnect 30 | r write [format_command quit] 31 | r write [format_command set foo [string repeat "x" 1024]] 32 | r flush 33 | assert_equal OK [r read] 34 | assert_error * {r read} 35 | 36 | reconnect 37 | assert_equal {} [r get foo] 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tests/unit/slowlog.tcl: -------------------------------------------------------------------------------- 1 | start_server {tags {"slowlog"}} { 2 | test {SLOWLOG - check that it starts with an empty log} { 3 | r slowlog len 4 | } {0} 5 | 6 | test {SLOWLOG - only logs commands taking more time than specified} { 7 | r config set slowlog-log-slower-than 100000 8 | r ping 9 | assert_equal [r slowlog len] 0 10 | r debug sleep 0.2 11 | assert_equal [r slowlog len] 1 12 | } 13 | 14 | test {SLOWLOG - max entries is correctly handled} { 15 | r config set slowlog-log-slower-than 0 16 | r config set slowlog-max-len 10 17 | for {set i 0} {$i < 100} {incr i} { 18 | r ping 19 | } 20 | r slowlog len 21 | } {10} 22 | 23 | test {SLOWLOG - GET optional argument to limit output len works} { 24 | llength [r slowlog get 5] 25 | } {5} 26 | 27 | test {SLOWLOG - RESET subcommand works} { 28 | r config set slowlog-log-slower-than 100000 29 | r slowlog reset 30 | r slowlog len 31 | } {0} 32 | 33 | test {SLOWLOG - logged entry sanity check} { 34 | r debug sleep 0.2 35 | set e [lindex [r slowlog get] 0] 36 | assert_equal [llength $e] 4 37 | assert_equal [lindex $e 0] 105 38 | assert_equal [expr {[lindex $e 2] > 100000}] 1 39 | assert_equal [lindex $e 3] {debug sleep 0.2} 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tests/unit/type/list-2.tcl: -------------------------------------------------------------------------------- 1 | start_server { 2 | tags {"list"} 3 | overrides { 4 | "list-max-ziplist-value" 16 5 | "list-max-ziplist-entries" 256 6 | } 7 | } { 8 | source "tests/unit/type/list-common.tcl" 9 | 10 | foreach {type large} [array get largevalue] { 11 | tags {"slow"} { 12 | test "LTRIM stress testing - $type" { 13 | set mylist {} 14 | set startlen 32 15 | r del mylist 16 | 17 | # Start with the large value to ensure the 18 | # right encoding is used. 19 | r rpush mylist $large 20 | lappend mylist $large 21 | 22 | for {set i 0} {$i < $startlen} {incr i} { 23 | set str [randomInt 9223372036854775807] 24 | r rpush mylist $str 25 | lappend mylist $str 26 | } 27 | 28 | for {set i 0} {$i < 1000} {incr i} { 29 | set min [expr {int(rand()*$startlen)}] 30 | set max [expr {$min+int(rand()*$startlen)}] 31 | set mylist [lrange $mylist $min $max] 32 | r ltrim mylist $min $max 33 | assert_equal $mylist [r lrange mylist 0 -1] 34 | 35 | for {set j [r llen mylist]} {$j < $startlen} {incr j} { 36 | set str [randomInt 9223372036854775807] 37 | r rpush mylist $str 38 | lappend mylist $str 39 | } 40 | } 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /tests/unit/type/list-3.tcl: -------------------------------------------------------------------------------- 1 | start_server { 2 | tags {list ziplist} 3 | overrides { 4 | "list-max-ziplist-value" 200000 5 | "list-max-ziplist-entries" 256 6 | } 7 | } { 8 | test {Explicit regression for a list bug} { 9 | set mylist {49376042582 {BkG2o\pIC]4YYJa9cJ4GWZalG[4tin;1D2whSkCOW`mX;SFXGyS8sedcff3fQI^tgPCC@^Nu1J6o]meM@Lko]t_jRyotK?tH[\EvWqS]b`o2OCtjg:?nUTwdjpcUm]y:pg5q24q7LlCOwQE^}} 10 | r del l 11 | r rpush l [lindex $mylist 0] 12 | r rpush l [lindex $mylist 1] 13 | assert_equal [r lindex l 0] [lindex $mylist 0] 14 | assert_equal [r lindex l 1] [lindex $mylist 1] 15 | } 16 | 17 | tags {slow} { 18 | test {ziplist implementation: value encoding and backlink} { 19 | if {$::accurate} {set iterations 100} else {set iterations 10} 20 | for {set j 0} {$j < $iterations} {incr j} { 21 | r del l 22 | set l {} 23 | for {set i 0} {$i < 200} {incr i} { 24 | randpath { 25 | set data [string repeat x [randomInt 100000]] 26 | } { 27 | set data [randomInt 65536] 28 | } { 29 | set data [randomInt 4294967296] 30 | } { 31 | set data [randomInt 18446744073709551616] 32 | } 33 | lappend l $data 34 | r rpush l $data 35 | } 36 | assert_equal [llength $l] [r llen l] 37 | # Traverse backward 38 | for {set i 199} {$i >= 0} {incr i -1} { 39 | if {[lindex $l $i] ne [r lindex l $i]} { 40 | assert_equal [lindex $l $i] [r lindex l $i] 41 | } 42 | } 43 | } 44 | } 45 | 46 | test {ziplist implementation: encoding stress testing} { 47 | for {set j 0} {$j < 200} {incr j} { 48 | r del l 49 | set l {} 50 | set len [randomInt 400] 51 | for {set i 0} {$i < $len} {incr i} { 52 | set rv [randomValue] 53 | randpath { 54 | lappend l $rv 55 | r rpush l $rv 56 | } { 57 | set l [concat [list $rv] $l] 58 | r lpush l $rv 59 | } 60 | } 61 | assert_equal [llength $l] [r llen l] 62 | for {set i 0} {$i < $len} {incr i} { 63 | if {[lindex $l $i] ne [r lindex l $i]} { 64 | assert_equal [lindex $l $i] [r lindex l $i] 65 | } 66 | } 67 | } 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /tests/unit/type/list-common.tcl: -------------------------------------------------------------------------------- 1 | # We need a value larger than list-max-ziplist-value to make sure 2 | # the list has the right encoding when it is swapped in again. 3 | array set largevalue {} 4 | set largevalue(ziplist) "hello" 5 | set largevalue(linkedlist) [string repeat "hello" 4] 6 | -------------------------------------------------------------------------------- /utils/generate-command-help.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | GROUPS = [ 4 | "generic", 5 | "string", 6 | "list", 7 | "set", 8 | "sorted_set", 9 | "hash", 10 | "pubsub", 11 | "transactions", 12 | "connection", 13 | "server" 14 | ].freeze 15 | 16 | GROUPS_BY_NAME = Hash[* 17 | GROUPS.each_with_index.map do |n,i| 18 | [n,i] 19 | end.flatten 20 | ].freeze 21 | 22 | def argument arg 23 | name = arg["name"].is_a?(Array) ? arg["name"].join(" ") : arg["name"] 24 | name = arg["enum"].join "|" if "enum" == arg["type"] 25 | name = arg["command"] + " " + name if arg["command"] 26 | if arg["multiple"] 27 | name = "#{name} [#{name} ...]" 28 | end 29 | if arg["optional"] 30 | name = "[#{name}]" 31 | end 32 | name 33 | end 34 | 35 | def arguments command 36 | return "-" unless command["arguments"] 37 | command["arguments"].map do |arg| 38 | argument arg 39 | end.join " " 40 | end 41 | 42 | def commands 43 | return @commands if @commands 44 | 45 | require "rubygems" 46 | require "net/http" 47 | require "net/https" 48 | require "json" 49 | require "uri" 50 | 51 | url = URI.parse "https://github.com/antirez/redis-doc/raw/master/commands.json" 52 | client = Net::HTTP.new url.host, url.port 53 | client.use_ssl = true 54 | response = client.get url.path 55 | if response.is_a?(Net::HTTPSuccess) 56 | @commands = JSON.parse(response.body) 57 | else 58 | response.error! 59 | end 60 | end 61 | 62 | def generate_groups 63 | GROUPS.map do |n| 64 | "\"#{n}\"" 65 | end.join(",\n "); 66 | end 67 | 68 | def generate_commands 69 | commands.to_a.sort do |x,y| 70 | x[0] <=> y[0] 71 | end.map do |key, command| 72 | group = GROUPS_BY_NAME[command["group"]] 73 | if group.nil? 74 | STDERR.puts "Please update groups array in #{__FILE__}" 75 | raise "Unknown group #{command["group"]}" 76 | end 77 | 78 | ret = <<-SPEC 79 | { "#{key}", 80 | "#{arguments(command)}", 81 | "#{command["summary"]}", 82 | #{group}, 83 | "#{command["since"]}" } 84 | SPEC 85 | ret.strip 86 | end.join(",\n ") 87 | end 88 | 89 | # Write to stdout 90 | puts <<-HELP_H 91 | /* Automatically generated by #{__FILE__}, do not edit. */ 92 | 93 | #ifndef __REDIS_HELP_H 94 | #define __REDIS_HELP_H 95 | 96 | static char *commandGroups[] = { 97 | #{generate_groups} 98 | }; 99 | 100 | struct commandHelp { 101 | char *name; 102 | char *params; 103 | char *summary; 104 | int group; 105 | char *since; 106 | } commandHelp[] = { 107 | #{generate_commands} 108 | }; 109 | 110 | #endif 111 | HELP_H 112 | 113 | -------------------------------------------------------------------------------- /utils/mkrelease.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [ $# != "1" ] 3 | then 4 | echo "Usage: ./mkrelease.sh " 5 | exit 1 6 | fi 7 | 8 | TAG=$1 9 | TARNAME="redis-${TAG}.tar" 10 | echo "Generating /tmp/${TARNAME}" 11 | git archive $TAG --prefix redis-${TAG}/ > /tmp/$TARNAME || exit 1 12 | echo "Gizipping the archive" 13 | rm -f /tmp/$TARNAME.gz 14 | gzip -9 /tmp/$TARNAME 15 | -------------------------------------------------------------------------------- /utils/mktarball.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "$1" = "" ] 4 | then 5 | echo "Usage: mktarball.sh " 6 | echo "Example: mktarball.sh 2.2-rc4" 7 | exit 1 8 | fi 9 | 10 | PREFIX="redis-${1}/" 11 | TARBALL="/tmp/redis-${1}.tar.gz" 12 | git archive --format=tar --prefix=$PREFIX $1 | gzip -c > $TARBALL 13 | echo "File created: $TARBALL" 14 | -------------------------------------------------------------------------------- /utils/redis_init_script: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Simple Redis init.d script conceived to work on Linux systems 4 | # as it does use of the /proc filesystem. 5 | 6 | REDISPORT=6379 7 | EXEC=/usr/local/bin/redis-server 8 | CLIEXEC=/usr/local/bin/redis-cli 9 | 10 | PIDFILE=/var/run/redis_${REDISPORT}.pid 11 | CONF="/etc/redis/${REDISPORT}.conf" 12 | 13 | case "$1" in 14 | start) 15 | if [ -f $PIDFILE ] 16 | then 17 | echo "$PIDFILE exists, process is already running or crashed" 18 | else 19 | echo "Starting Redis server..." 20 | $EXEC $CONF 21 | fi 22 | ;; 23 | stop) 24 | if [ ! -f $PIDFILE ] 25 | then 26 | echo "$PIDFILE does not exist, process is not running" 27 | else 28 | PID=$(cat $PIDFILE) 29 | echo "Stopping ..." 30 | $CLIEXEC -p $REDISPORT shutdown 31 | while [ -x /proc/${PID} ] 32 | do 33 | echo "Waiting for Redis to shutdown ..." 34 | sleep 1 35 | done 36 | echo "Redis stopped" 37 | fi 38 | ;; 39 | *) 40 | echo "Please use start or stop as first argument" 41 | ;; 42 | esac 43 | -------------------------------------------------------------------------------- /utils/redis_init_script.tpl: -------------------------------------------------------------------------------- 1 | 2 | case "$1" in 3 | start) 4 | if [ -f $$PIDFILE ] 5 | then 6 | echo "$PIDFILE exists, process is already running or crashed" 7 | else 8 | echo "Starting Redis server..." 9 | $EXEC $CONF 10 | fi 11 | ;; 12 | stop) 13 | if [ ! -f $PIDFILE ] 14 | then 15 | echo "$PIDFILE does not exist, process is not running" 16 | else 17 | PID=$(cat $PIDFILE) 18 | echo "Stopping ..." 19 | $CLIEXEC -p $REDISPORT shutdown 20 | while [ -x /proc/${PID} ] 21 | do 22 | echo "Waiting for Redis to shutdown ..." 23 | sleep 1 24 | done 25 | echo "Redis stopped" 26 | fi 27 | ;; 28 | *) 29 | echo "Please use start or stop as first argument" 30 | ;; 31 | esac 32 | --------------------------------------------------------------------------------