├── .bzrignore ├── .gitignore ├── .travis.yml ├── COPYING ├── Makefile ├── README.md ├── debian ├── README.md ├── changelog ├── compat ├── control ├── copyright ├── discnt-server.1 ├── install └── rules ├── deps ├── Makefile ├── README.md ├── hiredis │ ├── .gitignore │ ├── .travis.yml │ ├── CHANGELOG.md │ ├── COPYING │ ├── Makefile │ ├── README.md │ ├── adapters │ │ ├── ae.h │ │ ├── libev.h │ │ ├── libevent.h │ │ └── libuv.h │ ├── async.c │ ├── async.h │ ├── dict.c │ ├── dict.h │ ├── examples │ │ ├── example-ae.c │ │ ├── example-libev.c │ │ ├── example-libevent.c │ │ ├── example-libuv.c │ │ └── example.c │ ├── fmacros.h │ ├── hiredis.c │ ├── hiredis.h │ ├── net.c │ ├── net.h │ ├── sds.c │ ├── sds.h │ ├── sdsalloc.h │ ├── test.c │ └── zmalloc.h ├── jemalloc │ ├── .autom4te.cfg │ ├── .gitattributes │ ├── .gitignore │ ├── COPYING │ ├── ChangeLog │ ├── INSTALL │ ├── Makefile.in │ ├── README │ ├── VERSION │ ├── autogen.sh │ ├── bin │ │ ├── jemalloc-config.in │ │ ├── jemalloc.sh.in │ │ └── jeprof.in │ ├── config.guess │ ├── config.stamp.in │ ├── config.sub │ ├── configure │ ├── configure.ac │ ├── coverage.sh │ ├── 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 │ │ │ │ ├── ckh.h │ │ │ │ ├── ctl.h │ │ │ │ ├── extent.h │ │ │ │ ├── hash.h │ │ │ │ ├── huge.h │ │ │ │ ├── jemalloc_internal.h.in │ │ │ │ ├── jemalloc_internal_decls.h │ │ │ │ ├── jemalloc_internal_defs.h.in │ │ │ │ ├── jemalloc_internal_macros.h │ │ │ │ ├── mb.h │ │ │ │ ├── mutex.h │ │ │ │ ├── pages.h │ │ │ │ ├── private_namespace.sh │ │ │ │ ├── private_symbols.txt │ │ │ │ ├── private_unnamespace.sh │ │ │ │ ├── prng.h │ │ │ │ ├── prof.h │ │ │ │ ├── public_namespace.sh │ │ │ │ ├── public_unnamespace.sh │ │ │ │ ├── ql.h │ │ │ │ ├── qr.h │ │ │ │ ├── quarantine.h │ │ │ │ ├── rb.h │ │ │ │ ├── rtree.h │ │ │ │ ├── size_classes.sh │ │ │ │ ├── stats.h │ │ │ │ ├── tcache.h │ │ │ │ ├── tsd.h │ │ │ │ ├── util.h │ │ │ │ └── valgrind.h │ │ │ ├── jemalloc.sh │ │ │ ├── jemalloc_defs.h.in │ │ │ ├── jemalloc_macros.h.in │ │ │ ├── jemalloc_mangle.sh │ │ │ ├── jemalloc_protos.h.in │ │ │ ├── jemalloc_rename.sh │ │ │ └── jemalloc_typedefs.h.in │ │ └── msvc_compat │ │ │ ├── C99 │ │ │ ├── stdbool.h │ │ │ └── stdint.h │ │ │ ├── strings.h │ │ │ └── windows_extra.h │ ├── install-sh │ ├── jemalloc.pc.in │ ├── src │ │ ├── arena.c │ │ ├── atomic.c │ │ ├── base.c │ │ ├── bitmap.c │ │ ├── chunk.c │ │ ├── chunk_dss.c │ │ ├── chunk_mmap.c │ │ ├── ckh.c │ │ ├── ctl.c │ │ ├── extent.c │ │ ├── hash.c │ │ ├── huge.c │ │ ├── jemalloc.c │ │ ├── mb.c │ │ ├── mutex.c │ │ ├── pages.c │ │ ├── prof.c │ │ ├── quarantine.c │ │ ├── rtree.c │ │ ├── stats.c │ │ ├── tcache.c │ │ ├── tsd.c │ │ ├── util.c │ │ ├── valgrind.c │ │ └── zone.c │ └── test │ │ ├── include │ │ └── test │ │ │ ├── SFMT-alti.h │ │ │ ├── SFMT-params.h │ │ │ ├── SFMT-params11213.h │ │ │ ├── SFMT-params1279.h │ │ │ ├── SFMT-params132049.h │ │ │ ├── SFMT-params19937.h │ │ │ ├── SFMT-params216091.h │ │ │ ├── SFMT-params2281.h │ │ │ ├── SFMT-params4253.h │ │ │ ├── SFMT-params44497.h │ │ │ ├── SFMT-params607.h │ │ │ ├── SFMT-params86243.h │ │ │ ├── SFMT-sse2.h │ │ │ ├── SFMT.h │ │ │ ├── btalloc.h │ │ │ ├── jemalloc_test.h.in │ │ │ ├── jemalloc_test_defs.h.in │ │ │ ├── math.h │ │ │ ├── mq.h │ │ │ ├── mtx.h │ │ │ ├── test.h │ │ │ ├── thd.h │ │ │ └── timer.h │ │ ├── integration │ │ ├── MALLOCX_ARENA.c │ │ ├── aligned_alloc.c │ │ ├── allocated.c │ │ ├── chunk.c │ │ ├── mallocx.c │ │ ├── overflow.c │ │ ├── posix_memalign.c │ │ ├── rallocx.c │ │ ├── sdallocx.c │ │ ├── thread_arena.c │ │ ├── thread_tcache_enabled.c │ │ └── xallocx.c │ │ ├── src │ │ ├── SFMT.c │ │ ├── btalloc.c │ │ ├── btalloc_0.c │ │ ├── btalloc_1.c │ │ ├── math.c │ │ ├── mq.c │ │ ├── mtx.c │ │ ├── test.c │ │ ├── thd.c │ │ └── timer.c │ │ ├── stress │ │ └── microbench.c │ │ ├── test.sh.in │ │ └── unit │ │ ├── SFMT.c │ │ ├── atomic.c │ │ ├── bitmap.c │ │ ├── ckh.c │ │ ├── hash.c │ │ ├── junk.c │ │ ├── junk_alloc.c │ │ ├── junk_free.c │ │ ├── lg_chunk.c │ │ ├── mallctl.c │ │ ├── math.c │ │ ├── mq.c │ │ ├── mtx.c │ │ ├── prof_accum.c │ │ ├── prof_active.c │ │ ├── prof_gdump.c │ │ ├── prof_idump.c │ │ ├── prof_reset.c │ │ ├── prof_thread_name.c │ │ ├── ql.c │ │ ├── qr.c │ │ ├── quarantine.c │ │ ├── rb.c │ │ ├── rtree.c │ │ ├── size_classes.c │ │ ├── stats.c │ │ ├── tsd.c │ │ ├── util.c │ │ └── zero.c ├── linenoise │ ├── .gitignore │ ├── Makefile │ ├── README.markdown │ ├── example.c │ ├── linenoise.c │ └── linenoise.h └── update-jemalloc.sh ├── discnt.conf ├── runtest ├── runtest-cluster ├── runtest-unit ├── src ├── .gitignore ├── Makefile ├── Makefile.dep ├── adlist.c ├── adlist.h ├── ae.c ├── ae.h ├── ae_epoll.c ├── ae_evport.c ├── ae_kqueue.c ├── ae_select.c ├── anet.c ├── anet.h ├── asciilogo.h ├── atomicvar.h ├── bio.c ├── bio.h ├── blocked.c ├── cluster.c ├── cluster.h ├── config.c ├── config.h ├── counter.c ├── counter.h ├── crc64.c ├── crc64.h ├── ddb.c ├── ddb.h ├── debug.c ├── dict.c ├── dict.h ├── discnt-benchmark.c ├── discnt-cli.c ├── discntassert.h ├── endianconv.c ├── endianconv.h ├── fmacros.h ├── help.h ├── latency.c ├── latency.h ├── memtest.c ├── mkreleasehdr.sh ├── networking.c ├── object.c ├── pubsub.c ├── release.c ├── rio.c ├── rio.h ├── sds.c ├── sds.h ├── sdsalloc.h ├── server.c ├── server.h ├── setproctitle.c ├── sha1.c ├── sha1.h ├── solarisfixes.h ├── sparkline.c ├── sparkline.h ├── syncio.c ├── testhelp.h ├── util.c ├── util.h ├── valgrind.sup ├── version.h ├── zmalloc.c └── zmalloc.h ├── tests ├── assets │ └── default.conf ├── cluster │ ├── cluster.tcl │ ├── run.tcl │ ├── tests │ │ ├── 00-base.tcl │ │ ├── 01-faildet.tcl │ │ ├── 02-sync.tcl │ │ ├── 03-state.tcl │ │ ├── 04-ack.tcl │ │ ├── 05-history.tcl │ │ ├── 06-reset.tcl │ │ ├── 07-unused.tcl │ │ ├── 98-random.tcl │ │ ├── 99-oneminute.tcl │ │ └── includes │ │ │ └── init-tests.tcl │ └── tmp │ │ └── .gitignore ├── instances.tcl ├── support │ ├── cluster.tcl │ ├── redis.tcl │ ├── server.tcl │ ├── test.tcl │ ├── tmpfile.tcl │ └── util.tcl ├── test_helper.tcl ├── tmp │ └── .gitignore └── unit │ ├── auth.tcl │ ├── counters.tcl │ ├── introspection.tcl │ ├── latency-monitor.tcl │ ├── limits.tcl │ ├── other.tcl │ ├── printver.tcl │ ├── protocol.tcl │ └── pubsub.tcl └── utils ├── discnt_init_script ├── discnt_init_script.tpl ├── install_server.sh └── replay.tcl /.bzrignore: -------------------------------------------------------------------------------- 1 | .*.swp 2 | *.o 3 | *.log 4 | discnt-server 5 | discnt-cli 6 | discnt-benchmark 7 | doc-tools 8 | release 9 | misc/* 10 | src/release.h 11 | release.h 12 | src/transfer.sh 13 | src/configs 14 | .make-* 15 | .prerequisites 16 | *.dSYM 17 | 18 | tests/tmp/* 19 | deps/jemalloc/lib/ 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .*.swp 2 | *.o 3 | *.log 4 | discnt-server 5 | discnt-cli 6 | discnt-benchmark 7 | doc-tools 8 | release 9 | misc/* 10 | src/release.h 11 | release.h 12 | src/transfer.sh 13 | src/configs 14 | .make-* 15 | .prerequisites 16 | *.dSYM 17 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | sudo: false 3 | os: 4 | - linux 5 | - osx 6 | addons: 7 | apt: 8 | packages: 9 | - tcl8.5 10 | before_script: 11 | - if [ "$TRAVIS_OS_NAME" == "osx" ] ; then brew update; brew tap homebrew/dupes; brew install tcl-tk; fi 12 | cache: 13 | directories: 14 | - $HOME/.ccache 15 | install: 16 | - if [ "$TRAVIS_OS_NAME" == "linux" ] ; then make CC="ccache $CC"; fi 17 | - if [ "$TRAVIS_OS_NAME" == "osx" ] ; then make; fi 18 | script: make test 19 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | Copyright (c) 2006-2015, Erik Dubbelboer 2 | Copyright (c) 2006-2015, Salvatore Sanfilippo 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 8 | * 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. 9 | * Neither the name of Discnt nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 10 | 11 | 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. 12 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Top level makefile, the real shit is at src/Makefile 2 | 3 | default: all 4 | 5 | .DEFAULT: 6 | cd src && $(MAKE) $@ 7 | 8 | install: 9 | cd src && $(MAKE) $@ 10 | 11 | .PHONY: install 12 | -------------------------------------------------------------------------------- /debian/README.md: -------------------------------------------------------------------------------- 1 | 2 | How to do a new release 3 | === 4 | 5 | ```bash 6 | cd .. 7 | rm -rf ppa 8 | bzr branch lp:~discnt/+junk/discnt ppa 9 | cd ppa 10 | find . -not -wholename '*.bzr*' -delete 11 | rsync -r ../discnt/ . 12 | rm -rf .git 13 | make distclean 14 | ``` 15 | 16 | Now you should have all the changes, check, commit and push them: 17 | ```bash 18 | bzr status 19 | bzr add * 20 | bzr commit 21 | bzr push lp:~discnt/+junk/discnt 22 | ``` 23 | 24 | After this go to the [recipe page](https://code.launchpad.net/~discnt/+recipe/discnt-stable) and request a build. 25 | 26 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | discnt (1.0.3-0ubuntu1) precise; urgency=low 2 | 3 | * Fix eventual consistency. 4 | 5 | -- Erik Dubbelboer Fri, 27 Nov 2015 04:44:38 +0000 6 | 7 | discnt (1.0.2-1) precise; urgency=low 8 | 9 | * Initial PPA release. 10 | 11 | -- Erik Dubbelboer Sat, 21 Nov 2015 05:39:18 +0000 12 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 8 2 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: discnt 2 | Section: database 3 | Priority: extra 4 | Maintainer: Erik Dubbelboer 5 | Build-Depends: debhelper (>= 8.0.0) 6 | Standards-Version: 3.9.3 7 | Homepage: http://discnt.io/ 8 | Vcs-Git: https://github.com/erikdubbelboer/discnt.git 9 | Vcs-Browser: https://github.com/erikdubbelboer/discnt 10 | 11 | Package: discnt 12 | Section: database 13 | Priority: extra 14 | Architecture: any 15 | Depends: ${misc:Depends}, ${shlibs:Depends} 16 | Description: In memory distributed eventually consistent counters. 17 | Discnt provides in memory distributed eventually consistent counters. 18 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Upstream-Name: discnt 3 | Source: https://raw.githubusercontent.com/erikdubbelboer/discnt/master/COPYING 4 | 5 | Files: * 6 | Copyright: 2015 Erik Dubbelboer 7 | License: BSD 8 | Copyright (c) 2006-2015, Erik Dubbelboer 9 | Copyright (c) 2006-2015, Salvatore Sanfilippo 10 | All rights reserved. 11 | . 12 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 13 | . 14 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 15 | * 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. 16 | * Neither the name of Discnt nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 17 | . 18 | 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. 19 | 20 | -------------------------------------------------------------------------------- /debian/discnt-server.1: -------------------------------------------------------------------------------- 1 | .TH REDIS-SERVER 1 "November 27, 2015" 2 | .SH NAME 3 | discnt-server \- Distributed counters 4 | .SH SYNOPSIS 5 | .B discnt-server 6 | .RI configfile 7 | .SH DESCRIPTION 8 | Discnt provides in memory distributed eventually consistent counters. 9 | .PP 10 | .SH OPTIONS 11 | .IP "configfile" 12 | Read options from specified configuration file. 13 | .SH AUTHOR 14 | \fBdiscnt-server\fP was written by Erik Dubbelboer. 15 | .PP 16 | -------------------------------------------------------------------------------- /debian/install: -------------------------------------------------------------------------------- 1 | src/discnt-server usr/bin 2 | src/discnt-cli usr/bin 3 | src/discnt-benchmark usr/bin 4 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | %: 4 | dh $@ 5 | 6 | override_dh_auto_test: 7 | true 8 | 9 | override_dh_auto_install: 10 | true 11 | 12 | override_dh_usrlocal: 13 | true 14 | 15 | -------------------------------------------------------------------------------- /deps/Makefile: -------------------------------------------------------------------------------- 1 | # Redis dependency Makefile 2 | 3 | uname_S:= $(shell sh -c 'uname -s 2>/dev/null || echo not') 4 | 5 | CCCOLOR="\033[34m" 6 | LINKCOLOR="\033[34;1m" 7 | SRCCOLOR="\033[33m" 8 | BINCOLOR="\033[37;1m" 9 | MAKECOLOR="\033[32;1m" 10 | ENDCOLOR="\033[0m" 11 | 12 | default: 13 | @echo "Explicit target required" 14 | 15 | .PHONY: default 16 | 17 | # Prerequisites target 18 | .make-prerequisites: 19 | @touch $@ 20 | 21 | # Clean everything when CFLAGS is different 22 | ifneq ($(shell sh -c '[ -f .make-cflags ] && cat .make-cflags || echo none'), $(CFLAGS)) 23 | .make-cflags: distclean 24 | -(echo "$(CFLAGS)" > .make-cflags) 25 | .make-prerequisites: .make-cflags 26 | endif 27 | 28 | # Clean everything when LDFLAGS is different 29 | ifneq ($(shell sh -c '[ -f .make-ldflags ] && cat .make-ldflags || echo none'), $(LDFLAGS)) 30 | .make-ldflags: distclean 31 | -(echo "$(LDFLAGS)" > .make-ldflags) 32 | .make-prerequisites: .make-ldflags 33 | endif 34 | 35 | distclean: 36 | -(cd hiredis && $(MAKE) clean) > /dev/null || true 37 | -(cd linenoise && $(MAKE) clean) > /dev/null || true 38 | -(cd jemalloc && [ -f Makefile ] && $(MAKE) distclean) > /dev/null || true 39 | -(rm -f .make-*) 40 | 41 | .PHONY: distclean 42 | 43 | hiredis: .make-prerequisites 44 | @printf '%b %b\n' $(MAKECOLOR)MAKE$(ENDCOLOR) $(BINCOLOR)$@$(ENDCOLOR) 45 | cd hiredis && $(MAKE) static 46 | 47 | .PHONY: hiredis 48 | 49 | linenoise: .make-prerequisites 50 | @printf '%b %b\n' $(MAKECOLOR)MAKE$(ENDCOLOR) $(BINCOLOR)$@$(ENDCOLOR) 51 | cd linenoise && $(MAKE) 52 | 53 | .PHONY: linenoise 54 | 55 | JEMALLOC_CFLAGS= -std=gnu99 -Wall -pipe -g3 -O3 -funroll-loops $(CFLAGS) 56 | JEMALLOC_LDFLAGS= $(LDFLAGS) 57 | 58 | jemalloc: .make-prerequisites 59 | @printf '%b %b\n' $(MAKECOLOR)MAKE$(ENDCOLOR) $(BINCOLOR)$@$(ENDCOLOR) 60 | cd jemalloc && ./configure --with-jemalloc-prefix=je_ --enable-cc-silence CFLAGS="$(JEMALLOC_CFLAGS)" LDFLAGS="$(JEMALLOC_LDFLAGS)" 61 | cd jemalloc && $(MAKE) CFLAGS="$(JEMALLOC_CFLAGS)" LDFLAGS="$(JEMALLOC_LDFLAGS)" lib/libjemalloc.a 62 | 63 | .PHONY: jemalloc 64 | -------------------------------------------------------------------------------- /deps/README.md: -------------------------------------------------------------------------------- 1 | This directory contains all Discnt dependencies, except for the libc that 2 | should be provided by the operating system. 3 | 4 | * **Jemalloc** is our memory allocator, used as replacement for libc malloc on Linux by default. It has good performances and excellent fragmentation behavior. This component is upgraded from time to time. 5 | * **hiredis** is the official C client library for Discnt. It is used by discnt-cli and discnt-benchmark. It is part of the Discnt official ecosystem but is developed externally from the Discnt repository, so we just upgrade it as needed. 6 | * **linenoise** is a readline replacement. It is developed by the same authors of Discnt but is managed as a separated project and updated as needed. 7 | 8 | How to upgrade the above dependencies 9 | === 10 | 11 | Jemalloc 12 | --- 13 | 14 | Jemalloc is unmodified. We only change settings via the `configure` script of Jemalloc using the `--with-lg-quantum` option, setting it to the value of 3 instead of 4. This provides us with more size classes that better suit the Discnt data structures, in order to gain memory efficiency. 15 | 16 | So in order to upgrade jemalloc: 17 | 18 | 1. Remove the jemalloc directory. 19 | 2. Substitute it with the new jemalloc source tree. 20 | 21 | Hiredis 22 | --- 23 | 24 | Hiredis uses the SDS string library, that must be the same version used inside Discnt itself. Historically Discnt often used forked versions of hiredis in a way or the other. In order to upgrade it is adviced to take a lot of care: 25 | 26 | 1. Check with diff if hiredis API changed and what impact it could have in Discnt. 27 | 2. Make sure thet the SDS library inside Hiredis and inside Discnt are compatible. 28 | 3. After the upgrade, run the Discnt Sentinel test. 29 | 4. Check manually that discnt-cli and discnt-benchmark behave as expecteed, since we have no tests for CLI utilities currently. 30 | 31 | Linenoise 32 | --- 33 | 34 | Linenoise is rarely upgraded as needed. The upgrade process is trivial since 35 | Discnt uses a non modified version of linenoise, so to upgrade just do the 36 | following: 37 | 38 | 1. Remove the linenoise directory. 39 | 2. Substitute it with the new linenoise source tree. 40 | 41 | -------------------------------------------------------------------------------- /deps/hiredis/.gitignore: -------------------------------------------------------------------------------- 1 | /hiredis-test 2 | /examples/hiredis-example* 3 | /*.o 4 | /*.so 5 | /*.dylib 6 | /*.a 7 | -------------------------------------------------------------------------------- /deps/hiredis/.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | compiler: 3 | - gcc 4 | - clang 5 | 6 | script: make && make check 7 | -------------------------------------------------------------------------------- /deps/hiredis/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ### 0.11.0 2 | 3 | * Increase the maximum multi-bulk reply depth to 7. 4 | 5 | * Increase the read buffer size from 2k to 16k. 6 | 7 | * Use poll(2) instead of select(2) to support large fds (>= 1024). 8 | 9 | ### 0.10.1 10 | 11 | * Makefile overhaul. Important to check out if you override one or more 12 | variables using environment variables or via arguments to the "make" tool. 13 | 14 | * Issue #45: Fix potential memory leak for a multi bulk reply with 0 elements 15 | being created by the default reply object functions. 16 | 17 | * Issue #43: Don't crash in an asynchronous context when Redis returns an error 18 | reply after the connection has been made (this happens when the maximum 19 | number of connections is reached). 20 | 21 | ### 0.10.0 22 | 23 | * See commit log. 24 | 25 | -------------------------------------------------------------------------------- /deps/hiredis/COPYING: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009-2011, Salvatore Sanfilippo 2 | Copyright (c) 2010-2011, Pieter Noordhuis 3 | 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 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 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 specific 18 | prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 21 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 24 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 27 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /deps/hiredis/adapters/libuv.h: -------------------------------------------------------------------------------- 1 | #ifndef __HIREDIS_LIBUV_H__ 2 | #define __HIREDIS_LIBUV_H__ 3 | #include 4 | #include "../hiredis.h" 5 | #include "../async.h" 6 | #include 7 | 8 | typedef struct redisLibuvEvents { 9 | redisAsyncContext* context; 10 | uv_poll_t handle; 11 | int events; 12 | } redisLibuvEvents; 13 | 14 | int redisLibuvAttach(redisAsyncContext*, uv_loop_t*); 15 | 16 | static void redisLibuvPoll(uv_poll_t* handle, int status, int events) { 17 | redisLibuvEvents* p = (redisLibuvEvents*)handle->data; 18 | 19 | if (status != 0) { 20 | return; 21 | } 22 | 23 | if (events & UV_READABLE) { 24 | redisAsyncHandleRead(p->context); 25 | } 26 | if (events & UV_WRITABLE) { 27 | redisAsyncHandleWrite(p->context); 28 | } 29 | } 30 | 31 | 32 | static void redisLibuvAddRead(void *privdata) { 33 | redisLibuvEvents* p = (redisLibuvEvents*)privdata; 34 | 35 | p->events |= UV_READABLE; 36 | 37 | uv_poll_start(&p->handle, p->events, redisLibuvPoll); 38 | } 39 | 40 | 41 | static void redisLibuvDelRead(void *privdata) { 42 | redisLibuvEvents* p = (redisLibuvEvents*)privdata; 43 | 44 | p->events &= ~UV_READABLE; 45 | 46 | if (p->events) { 47 | uv_poll_start(&p->handle, p->events, redisLibuvPoll); 48 | } else { 49 | uv_poll_stop(&p->handle); 50 | } 51 | } 52 | 53 | 54 | static void redisLibuvAddWrite(void *privdata) { 55 | redisLibuvEvents* p = (redisLibuvEvents*)privdata; 56 | 57 | p->events |= UV_WRITABLE; 58 | 59 | uv_poll_start(&p->handle, p->events, redisLibuvPoll); 60 | } 61 | 62 | 63 | static void redisLibuvDelWrite(void *privdata) { 64 | redisLibuvEvents* p = (redisLibuvEvents*)privdata; 65 | 66 | p->events &= ~UV_WRITABLE; 67 | 68 | if (p->events) { 69 | uv_poll_start(&p->handle, p->events, redisLibuvPoll); 70 | } else { 71 | uv_poll_stop(&p->handle); 72 | } 73 | } 74 | 75 | 76 | static void on_close(uv_handle_t* handle) { 77 | redisLibuvEvents* p = (redisLibuvEvents*)handle->data; 78 | 79 | free(p); 80 | } 81 | 82 | 83 | static void redisLibuvCleanup(void *privdata) { 84 | redisLibuvEvents* p = (redisLibuvEvents*)privdata; 85 | 86 | uv_close((uv_handle_t*)&p->handle, on_close); 87 | } 88 | 89 | 90 | static int redisLibuvAttach(redisAsyncContext* ac, uv_loop_t* loop) { 91 | redisContext *c = &(ac->c); 92 | 93 | if (ac->ev.data != NULL) { 94 | return REDIS_ERR; 95 | } 96 | 97 | ac->ev.addRead = redisLibuvAddRead; 98 | ac->ev.delRead = redisLibuvDelRead; 99 | ac->ev.addWrite = redisLibuvAddWrite; 100 | ac->ev.delWrite = redisLibuvDelWrite; 101 | ac->ev.cleanup = redisLibuvCleanup; 102 | 103 | redisLibuvEvents* p = (redisLibuvEvents*)malloc(sizeof(*p)); 104 | 105 | if (!p) { 106 | return REDIS_ERR; 107 | } 108 | 109 | memset(p, 0, sizeof(*p)); 110 | 111 | if (uv_poll_init(loop, &p->handle, c->fd) != 0) { 112 | return REDIS_ERR; 113 | } 114 | 115 | ac->ev.data = p; 116 | p->handle.data = p; 117 | p->context = ac; 118 | 119 | return REDIS_OK; 120 | } 121 | #endif 122 | -------------------------------------------------------------------------------- /deps/hiredis/examples/example-ae.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | /* Put event loop in the global scope, so it can be explicitly stopped */ 11 | static aeEventLoop *loop; 12 | 13 | void getCallback(redisAsyncContext *c, void *r, void *privdata) { 14 | redisReply *reply = r; 15 | if (reply == NULL) return; 16 | printf("argv[%s]: %s\n", (char*)privdata, reply->str); 17 | 18 | /* Disconnect after receiving the reply to GET */ 19 | redisAsyncDisconnect(c); 20 | } 21 | 22 | void connectCallback(const redisAsyncContext *c, int status) { 23 | if (status != REDIS_OK) { 24 | printf("Error: %s\n", c->errstr); 25 | aeStop(loop); 26 | return; 27 | } 28 | 29 | printf("Connected...\n"); 30 | } 31 | 32 | void disconnectCallback(const redisAsyncContext *c, int status) { 33 | if (status != REDIS_OK) { 34 | printf("Error: %s\n", c->errstr); 35 | aeStop(loop); 36 | return; 37 | } 38 | 39 | printf("Disconnected...\n"); 40 | aeStop(loop); 41 | } 42 | 43 | int main (int argc, char **argv) { 44 | signal(SIGPIPE, SIG_IGN); 45 | 46 | redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); 47 | if (c->err) { 48 | /* Let *c leak for now... */ 49 | printf("Error: %s\n", c->errstr); 50 | return 1; 51 | } 52 | 53 | loop = aeCreateEventLoop(64); 54 | redisAeAttach(loop, c); 55 | redisAsyncSetConnectCallback(c,connectCallback); 56 | redisAsyncSetDisconnectCallback(c,disconnectCallback); 57 | redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); 58 | redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); 59 | aeMain(loop); 60 | return 0; 61 | } 62 | 63 | -------------------------------------------------------------------------------- /deps/hiredis/examples/example-libev.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | void getCallback(redisAsyncContext *c, void *r, void *privdata) { 11 | redisReply *reply = r; 12 | if (reply == NULL) return; 13 | printf("argv[%s]: %s\n", (char*)privdata, reply->str); 14 | 15 | /* Disconnect after receiving the reply to GET */ 16 | redisAsyncDisconnect(c); 17 | } 18 | 19 | void connectCallback(const redisAsyncContext *c, int status) { 20 | if (status != REDIS_OK) { 21 | printf("Error: %s\n", c->errstr); 22 | return; 23 | } 24 | printf("Connected...\n"); 25 | } 26 | 27 | void disconnectCallback(const redisAsyncContext *c, int status) { 28 | if (status != REDIS_OK) { 29 | printf("Error: %s\n", c->errstr); 30 | return; 31 | } 32 | printf("Disconnected...\n"); 33 | } 34 | 35 | int main (int argc, char **argv) { 36 | signal(SIGPIPE, SIG_IGN); 37 | 38 | redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); 39 | if (c->err) { 40 | /* Let *c leak for now... */ 41 | printf("Error: %s\n", c->errstr); 42 | return 1; 43 | } 44 | 45 | redisLibevAttach(EV_DEFAULT_ 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 | ev_loop(EV_DEFAULT_ 0); 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /deps/hiredis/examples/example-libevent.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | void getCallback(redisAsyncContext *c, void *r, void *privdata) { 11 | redisReply *reply = r; 12 | if (reply == NULL) return; 13 | printf("argv[%s]: %s\n", (char*)privdata, reply->str); 14 | 15 | /* Disconnect after receiving the reply to GET */ 16 | redisAsyncDisconnect(c); 17 | } 18 | 19 | void connectCallback(const redisAsyncContext *c, int status) { 20 | if (status != REDIS_OK) { 21 | printf("Error: %s\n", c->errstr); 22 | return; 23 | } 24 | printf("Connected...\n"); 25 | } 26 | 27 | void disconnectCallback(const redisAsyncContext *c, int status) { 28 | if (status != REDIS_OK) { 29 | printf("Error: %s\n", c->errstr); 30 | return; 31 | } 32 | printf("Disconnected...\n"); 33 | } 34 | 35 | int main (int argc, char **argv) { 36 | signal(SIGPIPE, SIG_IGN); 37 | struct event_base *base = event_base_new(); 38 | 39 | redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); 40 | if (c->err) { 41 | /* Let *c leak for now... */ 42 | printf("Error: %s\n", c->errstr); 43 | return 1; 44 | } 45 | 46 | redisLibeventAttach(c,base); 47 | redisAsyncSetConnectCallback(c,connectCallback); 48 | redisAsyncSetDisconnectCallback(c,disconnectCallback); 49 | redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); 50 | redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); 51 | event_base_dispatch(base); 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /deps/hiredis/examples/example-libuv.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | void getCallback(redisAsyncContext *c, void *r, void *privdata) { 11 | redisReply *reply = r; 12 | if (reply == NULL) return; 13 | printf("argv[%s]: %s\n", (char*)privdata, reply->str); 14 | 15 | /* Disconnect after receiving the reply to GET */ 16 | redisAsyncDisconnect(c); 17 | } 18 | 19 | void connectCallback(const redisAsyncContext *c, int status) { 20 | if (status != REDIS_OK) { 21 | printf("Error: %s\n", c->errstr); 22 | return; 23 | } 24 | printf("Connected...\n"); 25 | } 26 | 27 | void disconnectCallback(const redisAsyncContext *c, int status) { 28 | if (status != REDIS_OK) { 29 | printf("Error: %s\n", c->errstr); 30 | return; 31 | } 32 | printf("Disconnected...\n"); 33 | } 34 | 35 | int main (int argc, char **argv) { 36 | signal(SIGPIPE, SIG_IGN); 37 | uv_loop_t* loop = uv_default_loop(); 38 | 39 | redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379); 40 | if (c->err) { 41 | /* Let *c leak for now... */ 42 | printf("Error: %s\n", c->errstr); 43 | return 1; 44 | } 45 | 46 | redisLibuvAttach(c,loop); 47 | redisAsyncSetConnectCallback(c,connectCallback); 48 | redisAsyncSetDisconnectCallback(c,disconnectCallback); 49 | redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1])); 50 | redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key"); 51 | uv_run(loop, UV_RUN_DEFAULT); 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /deps/hiredis/examples/example.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | int main(int argc, char **argv) { 8 | unsigned int j; 9 | redisContext *c; 10 | redisReply *reply; 11 | const char *hostname = (argc > 1) ? argv[1] : "127.0.0.1"; 12 | int port = (argc > 2) ? atoi(argv[2]) : 6379; 13 | 14 | struct timeval timeout = { 1, 500000 }; // 1.5 seconds 15 | c = redisConnectWithTimeout(hostname, port, timeout); 16 | if (c == NULL || c->err) { 17 | if (c) { 18 | printf("Connection error: %s\n", c->errstr); 19 | redisFree(c); 20 | } else { 21 | printf("Connection error: can't allocate redis context\n"); 22 | } 23 | exit(1); 24 | } 25 | 26 | /* PING server */ 27 | reply = redisCommand(c,"PING"); 28 | printf("PING: %s\n", reply->str); 29 | freeReplyObject(reply); 30 | 31 | /* Set a key */ 32 | reply = redisCommand(c,"SET %s %s", "foo", "hello world"); 33 | printf("SET: %s\n", reply->str); 34 | freeReplyObject(reply); 35 | 36 | /* Set a key using binary safe API */ 37 | reply = redisCommand(c,"SET %b %b", "bar", (size_t) 3, "hello", (size_t) 5); 38 | printf("SET (binary API): %s\n", reply->str); 39 | freeReplyObject(reply); 40 | 41 | /* Try a GET and two INCR */ 42 | reply = redisCommand(c,"GET foo"); 43 | printf("GET foo: %s\n", reply->str); 44 | freeReplyObject(reply); 45 | 46 | reply = redisCommand(c,"INCR counter"); 47 | printf("INCR counter: %lld\n", reply->integer); 48 | freeReplyObject(reply); 49 | /* again ... */ 50 | reply = redisCommand(c,"INCR counter"); 51 | printf("INCR counter: %lld\n", reply->integer); 52 | freeReplyObject(reply); 53 | 54 | /* Create a list of numbers, from 0 to 9 */ 55 | reply = redisCommand(c,"DEL mylist"); 56 | freeReplyObject(reply); 57 | for (j = 0; j < 10; j++) { 58 | char buf[64]; 59 | 60 | snprintf(buf,64,"%u",j); 61 | reply = redisCommand(c,"LPUSH mylist element-%s", buf); 62 | freeReplyObject(reply); 63 | } 64 | 65 | /* Let's check what we have inside the list */ 66 | reply = redisCommand(c,"LRANGE mylist 0 -1"); 67 | if (reply->type == REDIS_REPLY_ARRAY) { 68 | for (j = 0; j < reply->elements; j++) { 69 | printf("%u) %s\n", j, reply->element[j]->str); 70 | } 71 | } 72 | freeReplyObject(reply); 73 | 74 | /* Disconnects and frees the context */ 75 | redisFree(c); 76 | 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /deps/hiredis/fmacros.h: -------------------------------------------------------------------------------- 1 | #ifndef __HIREDIS_FMACRO_H 2 | #define __HIREDIS_FMACRO_H 3 | 4 | #if !defined(_BSD_SOURCE) 5 | #define _BSD_SOURCE 6 | #define _DEFAULT_SOURCE 7 | #endif 8 | 9 | #if defined(_AIX) 10 | #define _ALL_SOURCE 11 | #endif 12 | 13 | #if defined(__sun__) 14 | #define _POSIX_C_SOURCE 200112L 15 | #elif defined(__linux__) || defined(__OpenBSD__) || defined(__NetBSD__) 16 | #define _XOPEN_SOURCE 600 17 | #else 18 | #define _XOPEN_SOURCE 19 | #endif 20 | 21 | #if __APPLE__ && __MACH__ 22 | #define _OSX 23 | #endif 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /deps/hiredis/net.h: -------------------------------------------------------------------------------- 1 | /* Extracted from anet.c to work properly with Hiredis error reporting. 2 | * 3 | * Copyright (c) 2006-2011, Salvatore Sanfilippo 4 | * Copyright (c) 2010-2011, 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) || defined(_AIX) 39 | #define AF_LOCAL AF_UNIX 40 | #endif 41 | 42 | int redisCheckSocketError(redisContext *c); 43 | int redisContextSetTimeout(redisContext *c, const struct timeval tv); 44 | int redisContextConnectTcp(redisContext *c, const char *addr, int port, const struct timeval *timeout); 45 | int redisContextConnectBindTcp(redisContext *c, const char *addr, int port, 46 | const struct timeval *timeout, 47 | const char *source_addr); 48 | int redisContextConnectUnix(redisContext *c, const char *path, const struct timeval *timeout); 49 | int redisKeepAlive(redisContext *c, int interval); 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /deps/hiredis/sdsalloc.h: -------------------------------------------------------------------------------- 1 | /* SDSLib 2.0 -- A C dynamic strings library 2 | * 3 | * Copyright (c) 2006-2015, Salvatore Sanfilippo 4 | * Copyright (c) 2015, Redis Labs, Inc 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * * Neither the name of Redis nor the names of its contributors may be used 16 | * to endorse or promote products derived from this software without 17 | * specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | * POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | 32 | /* SDS allocator selection. 33 | * 34 | * This file is used in order to change the SDS allocator at compile time. 35 | * Just define the following defines to what you want to use. Also add 36 | * the include of your alternate allocator if needed (not needed in order 37 | * to use the default libc allocator). */ 38 | 39 | #include "zmalloc.h" 40 | #define s_malloc zmalloc 41 | #define s_realloc zrealloc 42 | #define s_free zfree 43 | -------------------------------------------------------------------------------- /deps/hiredis/zmalloc.h: -------------------------------------------------------------------------------- 1 | /* Drop in replacement for zmalloc.h in order to just use libc malloc without 2 | * any wrappering. */ 3 | 4 | #ifndef ZMALLOC_H 5 | #define ZMALLOC_H 6 | 7 | #define zmalloc malloc 8 | #define zrealloc realloc 9 | #define zcalloc(x) calloc(x,1) 10 | #define zfree free 11 | #define zstrdup strdup 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /deps/jemalloc/.autom4te.cfg: -------------------------------------------------------------------------------- 1 | begin-language: "Autoconf-without-aclocal-m4" 2 | args: --no-cache 3 | end-language: "Autoconf-without-aclocal-m4" 4 | -------------------------------------------------------------------------------- /deps/jemalloc/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /deps/jemalloc/.gitignore: -------------------------------------------------------------------------------- 1 | /*.gcov.* 2 | 3 | /bin/jemalloc-config 4 | /bin/jemalloc.sh 5 | /bin/jeprof 6 | 7 | /config.stamp 8 | /config.log 9 | /config.status 10 | /configure 11 | 12 | /doc/html.xsl 13 | /doc/manpages.xsl 14 | /doc/jemalloc.xml 15 | /doc/jemalloc.html 16 | /doc/jemalloc.3 17 | 18 | /jemalloc.pc 19 | 20 | /lib/ 21 | 22 | /Makefile 23 | 24 | /include/jemalloc/internal/jemalloc_internal.h 25 | /include/jemalloc/internal/jemalloc_internal_defs.h 26 | /include/jemalloc/internal/private_namespace.h 27 | /include/jemalloc/internal/private_unnamespace.h 28 | /include/jemalloc/internal/public_namespace.h 29 | /include/jemalloc/internal/public_symbols.txt 30 | /include/jemalloc/internal/public_unnamespace.h 31 | /include/jemalloc/internal/size_classes.h 32 | /include/jemalloc/jemalloc.h 33 | /include/jemalloc/jemalloc_defs.h 34 | /include/jemalloc/jemalloc_macros.h 35 | /include/jemalloc/jemalloc_mangle.h 36 | /include/jemalloc/jemalloc_mangle_jet.h 37 | /include/jemalloc/jemalloc_protos.h 38 | /include/jemalloc/jemalloc_protos_jet.h 39 | /include/jemalloc/jemalloc_rename.h 40 | /include/jemalloc/jemalloc_typedefs.h 41 | 42 | /src/*.[od] 43 | /src/*.gcda 44 | /src/*.gcno 45 | 46 | /test/test.sh 47 | test/include/test/jemalloc_test.h 48 | test/include/test/jemalloc_test_defs.h 49 | 50 | /test/integration/[A-Za-z]* 51 | !/test/integration/[A-Za-z]*.* 52 | /test/integration/*.[od] 53 | /test/integration/*.gcda 54 | /test/integration/*.gcno 55 | /test/integration/*.out 56 | 57 | /test/src/*.[od] 58 | /test/src/*.gcda 59 | /test/src/*.gcno 60 | 61 | /test/stress/[A-Za-z]* 62 | !/test/stress/[A-Za-z]*.* 63 | /test/stress/*.[od] 64 | /test/stress/*.gcda 65 | /test/stress/*.gcno 66 | /test/stress/*.out 67 | 68 | /test/unit/[A-Za-z]* 69 | !/test/unit/[A-Za-z]*.* 70 | /test/unit/*.[od] 71 | /test/unit/*.gcda 72 | /test/unit/*.gcno 73 | /test/unit/*.out 74 | 75 | /VERSION 76 | -------------------------------------------------------------------------------- /deps/jemalloc/COPYING: -------------------------------------------------------------------------------- 1 | Unless otherwise specified, files in the jemalloc source distribution are 2 | subject to the following license: 3 | -------------------------------------------------------------------------------- 4 | Copyright (C) 2002-2015 Jason Evans . 5 | All rights reserved. 6 | Copyright (C) 2007-2012 Mozilla Foundation. All rights reserved. 7 | Copyright (C) 2009-2015 Facebook, Inc. All rights reserved. 8 | 9 | Redistribution and use in source and binary forms, with or without 10 | modification, are permitted provided that the following conditions are met: 11 | 1. Redistributions of source code must retain the above copyright notice(s), 12 | this list of conditions and the following disclaimer. 13 | 2. Redistributions in binary form must reproduce the above copyright notice(s), 14 | this list of conditions and the following disclaimer in the documentation 15 | and/or other materials provided with the distribution. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY EXPRESS 18 | OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 20 | EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 | OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 26 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- 28 | -------------------------------------------------------------------------------- /deps/jemalloc/README: -------------------------------------------------------------------------------- 1 | jemalloc is a general purpose malloc(3) implementation that emphasizes 2 | fragmentation avoidance and scalable concurrency support. jemalloc first came 3 | into use as the FreeBSD libc allocator in 2005, and since then it has found its 4 | way into numerous applications that rely on its predictable behavior. In 2010 5 | jemalloc development efforts broadened to include developer support features 6 | such as heap profiling, Valgrind integration, and extensive monitoring/tuning 7 | hooks. Modern jemalloc releases continue to be integrated back into FreeBSD, 8 | and therefore versatility remains critical. Ongoing development efforts trend 9 | toward making jemalloc among the best allocators for a broad range of demanding 10 | applications, and eliminating/mitigating weaknesses that have practical 11 | repercussions for real world applications. 12 | 13 | The COPYING file contains copyright and licensing information. 14 | 15 | The INSTALL file contains information on how to configure, build, and install 16 | jemalloc. 17 | 18 | The ChangeLog file contains a brief summary of changes for each release. 19 | 20 | URL: http://www.canonware.com/jemalloc/ 21 | -------------------------------------------------------------------------------- /deps/jemalloc/VERSION: -------------------------------------------------------------------------------- 1 | 4.0.3-0-ge9192eacf8935e29fc62fddc2701f7942b1cc02c 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/bin/jemalloc-config.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | usage() { 4 | cat < 7 | Options: 8 | --help | -h : Print usage. 9 | --version : Print jemalloc version. 10 | --revision : Print shared library revision number. 11 | --config : Print configure options used to build jemalloc. 12 | --prefix : Print installation directory prefix. 13 | --bindir : Print binary installation directory. 14 | --datadir : Print data installation directory. 15 | --includedir : Print include installation directory. 16 | --libdir : Print library installation directory. 17 | --mandir : Print manual page installation directory. 18 | --cc : Print compiler used to build jemalloc. 19 | --cflags : Print compiler flags used to build jemalloc. 20 | --cppflags : Print preprocessor flags used to build jemalloc. 21 | --ldflags : Print library flags used to build jemalloc. 22 | --libs : Print libraries jemalloc was linked against. 23 | EOF 24 | } 25 | 26 | prefix="@prefix@" 27 | exec_prefix="@exec_prefix@" 28 | 29 | case "$1" in 30 | --help | -h) 31 | usage 32 | exit 0 33 | ;; 34 | --version) 35 | echo "@jemalloc_version@" 36 | ;; 37 | --revision) 38 | echo "@rev@" 39 | ;; 40 | --config) 41 | echo "@CONFIG@" 42 | ;; 43 | --prefix) 44 | echo "@PREFIX@" 45 | ;; 46 | --bindir) 47 | echo "@BINDIR@" 48 | ;; 49 | --datadir) 50 | echo "@DATADIR@" 51 | ;; 52 | --includedir) 53 | echo "@INCLUDEDIR@" 54 | ;; 55 | --libdir) 56 | echo "@LIBDIR@" 57 | ;; 58 | --mandir) 59 | echo "@MANDIR@" 60 | ;; 61 | --cc) 62 | echo "@CC@" 63 | ;; 64 | --cflags) 65 | echo "@CFLAGS@" 66 | ;; 67 | --cppflags) 68 | echo "@CPPFLAGS@" 69 | ;; 70 | --ldflags) 71 | echo "@LDFLAGS@ @EXTRA_LDFLAGS@" 72 | ;; 73 | --libs) 74 | echo "@LIBS@" 75 | ;; 76 | *) 77 | usage 78 | exit 1 79 | esac 80 | -------------------------------------------------------------------------------- /deps/jemalloc/bin/jemalloc.sh.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | prefix=@prefix@ 4 | exec_prefix=@exec_prefix@ 5 | libdir=@libdir@ 6 | 7 | @LD_PRELOAD_VAR@=${libdir}/libjemalloc.@SOREV@ 8 | export @LD_PRELOAD_VAR@ 9 | exec "$@" 10 | -------------------------------------------------------------------------------- /deps/jemalloc/config.stamp.in: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erikdubbelboer/discnt/6ec37ecc9a060ea938335ed59e52df83b9e0d72f/deps/jemalloc/config.stamp.in -------------------------------------------------------------------------------- /deps/jemalloc/coverage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | objdir=$1 6 | suffix=$2 7 | shift 2 8 | objs=$@ 9 | 10 | gcov -b -p -f -o "${objdir}" ${objs} 11 | 12 | # Move gcov outputs so that subsequent gcov invocations won't clobber results 13 | # for the same sources with different compilation flags. 14 | for f in `find . -maxdepth 1 -type f -name '*.gcov'` ; do 15 | mv "${f}" "${f}.${suffix}" 16 | done 17 | -------------------------------------------------------------------------------- /deps/jemalloc/doc/html.xsl.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /deps/jemalloc/doc/jemalloc.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erikdubbelboer/discnt/6ec37ecc9a060ea938335ed59e52df83b9e0d72f/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 | void *base_alloc(size_t size); 13 | void base_stats_get(size_t *allocated, size_t *resident, size_t *mapped); 14 | bool base_boot(void); 15 | void base_prefork(void); 16 | void base_postfork_parent(void); 17 | void base_postfork_child(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_dss.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | #ifdef JEMALLOC_H_TYPES 3 | 4 | typedef enum { 5 | dss_prec_disabled = 0, 6 | dss_prec_primary = 1, 7 | dss_prec_secondary = 2, 8 | 9 | dss_prec_limit = 3 10 | } dss_prec_t; 11 | #define DSS_PREC_DEFAULT dss_prec_secondary 12 | #define DSS_DEFAULT "secondary" 13 | 14 | #endif /* JEMALLOC_H_TYPES */ 15 | /******************************************************************************/ 16 | #ifdef JEMALLOC_H_STRUCTS 17 | 18 | extern const char *dss_prec_names[]; 19 | 20 | #endif /* JEMALLOC_H_STRUCTS */ 21 | /******************************************************************************/ 22 | #ifdef JEMALLOC_H_EXTERNS 23 | 24 | dss_prec_t chunk_dss_prec_get(void); 25 | bool chunk_dss_prec_set(dss_prec_t dss_prec); 26 | void *chunk_alloc_dss(arena_t *arena, void *new_addr, size_t size, 27 | size_t alignment, bool *zero, bool *commit); 28 | bool chunk_in_dss(void *chunk); 29 | bool chunk_dss_boot(void); 30 | void chunk_dss_prefork(void); 31 | void chunk_dss_postfork_parent(void); 32 | void chunk_dss_postfork_child(void); 33 | 34 | #endif /* JEMALLOC_H_EXTERNS */ 35 | /******************************************************************************/ 36 | #ifdef JEMALLOC_H_INLINES 37 | 38 | #endif /* JEMALLOC_H_INLINES */ 39 | /******************************************************************************/ 40 | -------------------------------------------------------------------------------- /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, size_t alignment, bool *zero, 13 | bool *commit); 14 | bool chunk_dalloc_mmap(void *chunk, size_t size); 15 | 16 | #endif /* JEMALLOC_H_EXTERNS */ 17 | /******************************************************************************/ 18 | #ifdef JEMALLOC_H_INLINES 19 | 20 | #endif /* JEMALLOC_H_INLINES */ 21 | /******************************************************************************/ 22 | -------------------------------------------------------------------------------- /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 *, size_t[2]); 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 CKH_COUNT 34 | /* Counters used to get an idea of performance. */ 35 | uint64_t ngrows; 36 | uint64_t nshrinks; 37 | uint64_t nshrinkfails; 38 | uint64_t ninserts; 39 | uint64_t nrelocs; 40 | #endif 41 | 42 | /* Used for pseudo-random number generation. */ 43 | #define CKH_A 1103515241 44 | #define CKH_C 12347 45 | uint32_t prng_state; 46 | 47 | /* Total number of items. */ 48 | size_t count; 49 | 50 | /* 51 | * Minimum and current number of hash table buckets. There are 52 | * 2^LG_CKH_BUCKET_CELLS cells per bucket. 53 | */ 54 | unsigned lg_minbuckets; 55 | unsigned lg_curbuckets; 56 | 57 | /* Hash and comparison functions. */ 58 | ckh_hash_t *hash; 59 | ckh_keycomp_t *keycomp; 60 | 61 | /* Hash table with 2^lg_curbuckets buckets. */ 62 | ckhc_t *tab; 63 | }; 64 | 65 | #endif /* JEMALLOC_H_STRUCTS */ 66 | /******************************************************************************/ 67 | #ifdef JEMALLOC_H_EXTERNS 68 | 69 | bool ckh_new(tsd_t *tsd, ckh_t *ckh, size_t minitems, ckh_hash_t *hash, 70 | ckh_keycomp_t *keycomp); 71 | void ckh_delete(tsd_t *tsd, ckh_t *ckh); 72 | size_t ckh_count(ckh_t *ckh); 73 | bool ckh_iter(ckh_t *ckh, size_t *tabind, void **key, void **data); 74 | bool ckh_insert(tsd_t *tsd, ckh_t *ckh, const void *key, const void *data); 75 | bool ckh_remove(tsd_t *tsd, ckh_t *ckh, const void *searchkey, void **key, 76 | void **data); 77 | bool ckh_search(ckh_t *ckh, const void *seachkey, void **key, void **data); 78 | void ckh_string_hash(const void *key, size_t r_hash[2]); 79 | bool ckh_string_keycomp(const void *k1, const void *k2); 80 | void ckh_pointer_hash(const void *key, size_t r_hash[2]); 81 | bool ckh_pointer_keycomp(const void *k1, const void *k2); 82 | 83 | #endif /* JEMALLOC_H_EXTERNS */ 84 | /******************************************************************************/ 85 | #ifdef JEMALLOC_H_INLINES 86 | 87 | #endif /* JEMALLOC_H_INLINES */ 88 | /******************************************************************************/ 89 | -------------------------------------------------------------------------------- /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 | void *huge_malloc(tsd_t *tsd, arena_t *arena, size_t size, bool zero, 13 | tcache_t *tcache); 14 | void *huge_palloc(tsd_t *tsd, arena_t *arena, size_t size, size_t alignment, 15 | bool zero, tcache_t *tcache); 16 | bool huge_ralloc_no_move(void *ptr, size_t oldsize, size_t usize_min, 17 | size_t usize_max, bool zero); 18 | void *huge_ralloc(tsd_t *tsd, arena_t *arena, void *ptr, size_t oldsize, 19 | size_t usize, size_t alignment, bool zero, tcache_t *tcache); 20 | #ifdef JEMALLOC_JET 21 | typedef void (huge_dalloc_junk_t)(void *, size_t); 22 | extern huge_dalloc_junk_t *huge_dalloc_junk; 23 | #endif 24 | void huge_dalloc(tsd_t *tsd, void *ptr, tcache_t *tcache); 25 | arena_t *huge_aalloc(const void *ptr); 26 | size_t huge_salloc(const void *ptr); 27 | prof_tctx_t *huge_prof_tctx_get(const void *ptr); 28 | void huge_prof_tctx_set(const void *ptr, prof_tctx_t *tctx); 29 | void huge_prof_tctx_reset(const void *ptr); 30 | 31 | #endif /* JEMALLOC_H_EXTERNS */ 32 | /******************************************************************************/ 33 | #ifdef JEMALLOC_H_INLINES 34 | 35 | #endif /* JEMALLOC_H_INLINES */ 36 | /******************************************************************************/ 37 | -------------------------------------------------------------------------------- /deps/jemalloc/include/jemalloc/internal/jemalloc_internal_decls.h: -------------------------------------------------------------------------------- 1 | #ifndef JEMALLOC_INTERNAL_DECLS_H 2 | #define JEMALLOC_INTERNAL_DECLS_H 3 | 4 | #include 5 | #ifdef _WIN32 6 | # include 7 | # include "msvc_compat/windows_extra.h" 8 | 9 | #else 10 | # include 11 | # include 12 | # if !defined(__pnacl__) && !defined(__native_client__) 13 | # include 14 | # if !defined(SYS_write) && defined(__NR_write) 15 | # define SYS_write __NR_write 16 | # endif 17 | # include 18 | # endif 19 | # include 20 | # include 21 | #endif 22 | #include 23 | 24 | #include 25 | #ifndef SIZE_T_MAX 26 | # define SIZE_T_MAX SIZE_MAX 27 | #endif 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #ifndef offsetof 35 | # define offsetof(type, member) ((size_t)&(((type *)NULL)->member)) 36 | #endif 37 | #include 38 | #include 39 | #include 40 | #ifdef _MSC_VER 41 | # include 42 | typedef intptr_t ssize_t; 43 | # define PATH_MAX 1024 44 | # define STDERR_FILENO 2 45 | # define __func__ __FUNCTION__ 46 | # ifdef JEMALLOC_HAS_RESTRICT 47 | # define restrict __restrict 48 | # endif 49 | /* Disable warnings about deprecated system functions. */ 50 | # pragma warning(disable: 4996) 51 | #if _MSC_VER < 1800 52 | static int 53 | isblank(int c) 54 | { 55 | 56 | return (c == '\t' || c == ' '); 57 | } 58 | #endif 59 | #else 60 | # include 61 | #endif 62 | #include 63 | 64 | #endif /* JEMALLOC_INTERNAL_H */ 65 | -------------------------------------------------------------------------------- /deps/jemalloc/include/jemalloc/internal/jemalloc_internal_macros.h: -------------------------------------------------------------------------------- 1 | /* 2 | * JEMALLOC_ALWAYS_INLINE and JEMALLOC_INLINE are used within header files for 3 | * functions that are static inline functions if inlining is enabled, and 4 | * single-definition library-private functions if inlining is disabled. 5 | * 6 | * JEMALLOC_ALWAYS_INLINE_C and JEMALLOC_INLINE_C are for use in .c files, in 7 | * which case the denoted functions are always static, regardless of whether 8 | * inlining is enabled. 9 | */ 10 | #if defined(JEMALLOC_DEBUG) || defined(JEMALLOC_CODE_COVERAGE) 11 | /* Disable inlining to make debugging/profiling easier. */ 12 | # define JEMALLOC_ALWAYS_INLINE 13 | # define JEMALLOC_ALWAYS_INLINE_C static 14 | # define JEMALLOC_INLINE 15 | # define JEMALLOC_INLINE_C static 16 | # define inline 17 | #else 18 | # define JEMALLOC_ENABLE_INLINE 19 | # ifdef JEMALLOC_HAVE_ATTR 20 | # define JEMALLOC_ALWAYS_INLINE \ 21 | static inline JEMALLOC_ATTR(unused) JEMALLOC_ATTR(always_inline) 22 | # define JEMALLOC_ALWAYS_INLINE_C \ 23 | static inline JEMALLOC_ATTR(always_inline) 24 | # else 25 | # define JEMALLOC_ALWAYS_INLINE static inline 26 | # define JEMALLOC_ALWAYS_INLINE_C static inline 27 | # endif 28 | # define JEMALLOC_INLINE static inline 29 | # define JEMALLOC_INLINE_C static inline 30 | # ifdef _MSC_VER 31 | # define inline _inline 32 | # endif 33 | #endif 34 | 35 | #ifdef JEMALLOC_CC_SILENCE 36 | # define UNUSED JEMALLOC_ATTR(unused) 37 | #else 38 | # define UNUSED 39 | #endif 40 | 41 | #define ZU(z) ((size_t)z) 42 | #define ZI(z) ((ssize_t)z) 43 | #define QU(q) ((uint64_t)q) 44 | #define QI(q) ((int64_t)q) 45 | 46 | #define KZU(z) ZU(z##ULL) 47 | #define KZI(z) ZI(z##LL) 48 | #define KQU(q) QU(q##ULL) 49 | #define KQI(q) QI(q##LL) 50 | 51 | #ifndef __DECONST 52 | # define __DECONST(type, var) ((type)(uintptr_t)(const void *)(var)) 53 | #endif 54 | 55 | #ifndef JEMALLOC_HAS_RESTRICT 56 | # define restrict 57 | #endif 58 | -------------------------------------------------------------------------------- /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 | #elif defined(__tile__) 91 | JEMALLOC_INLINE void 92 | mb_write(void) 93 | { 94 | 95 | __sync_synchronize(); 96 | } 97 | #else 98 | /* 99 | * This is much slower than a simple memory barrier, but the semantics of mutex 100 | * unlock make this work. 101 | */ 102 | JEMALLOC_INLINE void 103 | mb_write(void) 104 | { 105 | malloc_mutex_t mtx; 106 | 107 | malloc_mutex_init(&mtx); 108 | malloc_mutex_lock(&mtx); 109 | malloc_mutex_unlock(&mtx); 110 | } 111 | #endif 112 | #endif 113 | 114 | #endif /* JEMALLOC_H_INLINES */ 115 | /******************************************************************************/ 116 | -------------------------------------------------------------------------------- /deps/jemalloc/include/jemalloc/internal/pages.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 *pages_map(void *addr, size_t size); 13 | void pages_unmap(void *addr, size_t size); 14 | void *pages_trim(void *addr, size_t alloc_size, size_t leadsize, 15 | size_t size); 16 | bool pages_commit(void *addr, size_t size); 17 | bool pages_decommit(void *addr, size_t size); 18 | bool pages_purge(void *addr, size_t size); 19 | 20 | #endif /* JEMALLOC_H_EXTERNS */ 21 | /******************************************************************************/ 22 | #ifdef JEMALLOC_H_INLINES 23 | 24 | #endif /* JEMALLOC_H_INLINES */ 25 | /******************************************************************************/ 26 | 27 | -------------------------------------------------------------------------------- /deps/jemalloc/include/jemalloc/internal/private_namespace.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for symbol in `cat $1` ; do 4 | echo "#define ${symbol} JEMALLOC_N(${symbol})" 5 | done 6 | -------------------------------------------------------------------------------- /deps/jemalloc/include/jemalloc/internal/private_unnamespace.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for symbol in `cat $1` ; do 4 | echo "#undef ${symbol}" 5 | done 6 | -------------------------------------------------------------------------------- /deps/jemalloc/include/jemalloc/internal/prng.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | #ifdef JEMALLOC_H_TYPES 3 | 4 | /* 5 | * Simple linear congruential pseudo-random number generator: 6 | * 7 | * prng(y) = (a*x + c) % m 8 | * 9 | * where the following constants ensure maximal period: 10 | * 11 | * a == Odd number (relatively prime to 2^n), and (a-1) is a multiple of 4. 12 | * c == Odd number (relatively prime to 2^n). 13 | * m == 2^32 14 | * 15 | * See Knuth's TAOCP 3rd Ed., Vol. 2, pg. 17 for details on these constraints. 16 | * 17 | * This choice of m has the disadvantage that the quality of the bits is 18 | * proportional to bit position. For example, the lowest bit has a cycle of 2, 19 | * the next has a cycle of 4, etc. For this reason, we prefer to use the upper 20 | * bits. 21 | * 22 | * Macro parameters: 23 | * uint32_t r : Result. 24 | * unsigned lg_range : (0..32], number of least significant bits to return. 25 | * uint32_t state : Seed value. 26 | * const uint32_t a, c : See above discussion. 27 | */ 28 | #define prng32(r, lg_range, state, a, c) do { \ 29 | assert((lg_range) > 0); \ 30 | assert((lg_range) <= 32); \ 31 | \ 32 | r = (state * (a)) + (c); \ 33 | state = r; \ 34 | r >>= (32 - (lg_range)); \ 35 | } while (false) 36 | 37 | /* Same as prng32(), but 64 bits of pseudo-randomness, using uint64_t. */ 38 | #define prng64(r, lg_range, state, a, c) do { \ 39 | assert((lg_range) > 0); \ 40 | assert((lg_range) <= 64); \ 41 | \ 42 | r = (state * (a)) + (c); \ 43 | state = r; \ 44 | r >>= (64 - (lg_range)); \ 45 | } while (false) 46 | 47 | #endif /* JEMALLOC_H_TYPES */ 48 | /******************************************************************************/ 49 | #ifdef JEMALLOC_H_STRUCTS 50 | 51 | #endif /* JEMALLOC_H_STRUCTS */ 52 | /******************************************************************************/ 53 | #ifdef JEMALLOC_H_EXTERNS 54 | 55 | #endif /* JEMALLOC_H_EXTERNS */ 56 | /******************************************************************************/ 57 | #ifdef JEMALLOC_H_INLINES 58 | 59 | #endif /* JEMALLOC_H_INLINES */ 60 | /******************************************************************************/ 61 | -------------------------------------------------------------------------------- /deps/jemalloc/include/jemalloc/internal/public_namespace.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for nm in `cat $1` ; do 4 | n=`echo ${nm} |tr ':' ' ' |awk '{print $1}'` 5 | echo "#define je_${n} JEMALLOC_N(${n})" 6 | done 7 | -------------------------------------------------------------------------------- /deps/jemalloc/include/jemalloc/internal/public_unnamespace.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | for nm in `cat $1` ; do 4 | n=`echo ${nm} |tr ':' ' ' |awk '{print $1}'` 5 | echo "#undef je_${n}" 6 | done 7 | -------------------------------------------------------------------------------- /deps/jemalloc/include/jemalloc/internal/ql.h: -------------------------------------------------------------------------------- 1 | /* List definitions. */ 2 | #define ql_head(a_type) \ 3 | struct { \ 4 | a_type *qlh_first; \ 5 | } 6 | 7 | #define ql_head_initializer(a_head) {NULL} 8 | 9 | #define ql_elm(a_type) qr(a_type) 10 | 11 | /* List functions. */ 12 | #define ql_new(a_head) do { \ 13 | (a_head)->qlh_first = NULL; \ 14 | } while (0) 15 | 16 | #define ql_elm_new(a_elm, a_field) qr_new((a_elm), a_field) 17 | 18 | #define ql_first(a_head) ((a_head)->qlh_first) 19 | 20 | #define ql_last(a_head, a_field) \ 21 | ((ql_first(a_head) != NULL) \ 22 | ? qr_prev(ql_first(a_head), a_field) : NULL) 23 | 24 | #define ql_next(a_head, a_elm, a_field) \ 25 | ((ql_last(a_head, a_field) != (a_elm)) \ 26 | ? qr_next((a_elm), a_field) : NULL) 27 | 28 | #define ql_prev(a_head, a_elm, a_field) \ 29 | ((ql_first(a_head) != (a_elm)) ? qr_prev((a_elm), a_field) \ 30 | : NULL) 31 | 32 | #define ql_before_insert(a_head, a_qlelm, a_elm, a_field) do { \ 33 | qr_before_insert((a_qlelm), (a_elm), a_field); \ 34 | if (ql_first(a_head) == (a_qlelm)) { \ 35 | ql_first(a_head) = (a_elm); \ 36 | } \ 37 | } while (0) 38 | 39 | #define ql_after_insert(a_qlelm, a_elm, a_field) \ 40 | qr_after_insert((a_qlelm), (a_elm), a_field) 41 | 42 | #define ql_head_insert(a_head, a_elm, a_field) do { \ 43 | if (ql_first(a_head) != NULL) { \ 44 | qr_before_insert(ql_first(a_head), (a_elm), a_field); \ 45 | } \ 46 | ql_first(a_head) = (a_elm); \ 47 | } while (0) 48 | 49 | #define ql_tail_insert(a_head, a_elm, a_field) do { \ 50 | if (ql_first(a_head) != NULL) { \ 51 | qr_before_insert(ql_first(a_head), (a_elm), a_field); \ 52 | } \ 53 | ql_first(a_head) = qr_next((a_elm), a_field); \ 54 | } while (0) 55 | 56 | #define ql_remove(a_head, a_elm, a_field) do { \ 57 | if (ql_first(a_head) == (a_elm)) { \ 58 | ql_first(a_head) = qr_next(ql_first(a_head), a_field); \ 59 | } \ 60 | if (ql_first(a_head) != (a_elm)) { \ 61 | qr_remove((a_elm), a_field); \ 62 | } else { \ 63 | ql_first(a_head) = NULL; \ 64 | } \ 65 | } while (0) 66 | 67 | #define ql_head_remove(a_head, a_type, a_field) do { \ 68 | a_type *t = ql_first(a_head); \ 69 | ql_remove((a_head), t, a_field); \ 70 | } while (0) 71 | 72 | #define ql_tail_remove(a_head, a_type, a_field) do { \ 73 | a_type *t = ql_last(a_head, a_field); \ 74 | ql_remove((a_head), t, a_field); \ 75 | } while (0) 76 | 77 | #define ql_foreach(a_var, a_head, a_field) \ 78 | qr_foreach((a_var), ql_first(a_head), a_field) 79 | 80 | #define ql_reverse_foreach(a_var, a_head, a_field) \ 81 | qr_reverse_foreach((a_var), ql_first(a_head), a_field) 82 | -------------------------------------------------------------------------------- /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 | /* 44 | * qr_meld() and qr_split() are functionally equivalent, so there's no need to 45 | * have two copies of the code. 46 | */ 47 | #define qr_split(a_qr_a, a_qr_b, a_field) \ 48 | qr_meld((a_qr_a), (a_qr_b), a_field) 49 | 50 | #define qr_remove(a_qr, a_field) do { \ 51 | (a_qr)->a_field.qre_prev->a_field.qre_next \ 52 | = (a_qr)->a_field.qre_next; \ 53 | (a_qr)->a_field.qre_next->a_field.qre_prev \ 54 | = (a_qr)->a_field.qre_prev; \ 55 | (a_qr)->a_field.qre_next = (a_qr); \ 56 | (a_qr)->a_field.qre_prev = (a_qr); \ 57 | } while (0) 58 | 59 | #define qr_foreach(var, a_qr, a_field) \ 60 | for ((var) = (a_qr); \ 61 | (var) != NULL; \ 62 | (var) = (((var)->a_field.qre_next != (a_qr)) \ 63 | ? (var)->a_field.qre_next : NULL)) 64 | 65 | #define qr_reverse_foreach(var, a_qr, a_field) \ 66 | for ((var) = ((a_qr) != NULL) ? qr_prev(a_qr, a_field) : NULL; \ 67 | (var) != NULL; \ 68 | (var) = (((var) != (a_qr)) \ 69 | ? (var)->a_field.qre_prev : NULL)) 70 | -------------------------------------------------------------------------------- /deps/jemalloc/include/jemalloc/internal/quarantine.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************/ 2 | #ifdef JEMALLOC_H_TYPES 3 | 4 | typedef struct quarantine_obj_s quarantine_obj_t; 5 | typedef struct quarantine_s quarantine_t; 6 | 7 | /* Default per thread quarantine size if valgrind is enabled. */ 8 | #define JEMALLOC_VALGRIND_QUARANTINE_DEFAULT (ZU(1) << 24) 9 | 10 | #endif /* JEMALLOC_H_TYPES */ 11 | /******************************************************************************/ 12 | #ifdef JEMALLOC_H_STRUCTS 13 | 14 | struct quarantine_obj_s { 15 | void *ptr; 16 | size_t usize; 17 | }; 18 | 19 | struct quarantine_s { 20 | size_t curbytes; 21 | size_t curobjs; 22 | size_t first; 23 | #define LG_MAXOBJS_INIT 10 24 | size_t lg_maxobjs; 25 | quarantine_obj_t objs[1]; /* Dynamically sized ring buffer. */ 26 | }; 27 | 28 | #endif /* JEMALLOC_H_STRUCTS */ 29 | /******************************************************************************/ 30 | #ifdef JEMALLOC_H_EXTERNS 31 | 32 | void quarantine_alloc_hook_work(tsd_t *tsd); 33 | void quarantine(tsd_t *tsd, void *ptr); 34 | void quarantine_cleanup(tsd_t *tsd); 35 | 36 | #endif /* JEMALLOC_H_EXTERNS */ 37 | /******************************************************************************/ 38 | #ifdef JEMALLOC_H_INLINES 39 | 40 | #ifndef JEMALLOC_ENABLE_INLINE 41 | void quarantine_alloc_hook(void); 42 | #endif 43 | 44 | #if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_QUARANTINE_C_)) 45 | JEMALLOC_ALWAYS_INLINE void 46 | quarantine_alloc_hook(void) 47 | { 48 | tsd_t *tsd; 49 | 50 | assert(config_fill && opt_quarantine); 51 | 52 | tsd = tsd_fetch(); 53 | if (tsd_quarantine_get(tsd) == NULL) 54 | quarantine_alloc_hook_work(tsd); 55 | } 56 | #endif 57 | 58 | #endif /* JEMALLOC_H_INLINES */ 59 | /******************************************************************************/ 60 | 61 | -------------------------------------------------------------------------------- /deps/jemalloc/include/jemalloc/jemalloc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | objroot=$1 4 | 5 | cat < 5 | 6 | /* MSVC doesn't define _Bool or bool in C, but does have BOOL */ 7 | /* Note this doesn't pass autoconf's test because (bool) 0.5 != true */ 8 | /* Clang-cl uses MSVC headers, so needs msvc_compat, but has _Bool as 9 | * a built-in type. */ 10 | #ifndef __clang__ 11 | typedef BOOL _Bool; 12 | #endif 13 | 14 | #define bool _Bool 15 | #define true 1 16 | #define false 0 17 | 18 | #define __bool_true_false_are_defined 1 19 | 20 | #endif /* stdbool_h */ 21 | -------------------------------------------------------------------------------- /deps/jemalloc/include/msvc_compat/strings.h: -------------------------------------------------------------------------------- 1 | #ifndef strings_h 2 | #define strings_h 3 | 4 | /* MSVC doesn't define ffs/ffsl. This dummy strings.h header is provided 5 | * for both */ 6 | #ifdef _MSC_VER 7 | # include 8 | # pragma intrinsic(_BitScanForward) 9 | static __forceinline int ffsl(long x) 10 | { 11 | unsigned long i; 12 | 13 | if (_BitScanForward(&i, x)) 14 | return (i + 1); 15 | return (0); 16 | } 17 | 18 | static __forceinline int ffs(int x) 19 | { 20 | 21 | return (ffsl(x)); 22 | } 23 | 24 | #else 25 | # define ffsl(x) __builtin_ffsl(x) 26 | # define ffs(x) __builtin_ffs(x) 27 | #endif 28 | 29 | #endif /* strings_h */ 30 | -------------------------------------------------------------------------------- /deps/jemalloc/include/msvc_compat/windows_extra.h: -------------------------------------------------------------------------------- 1 | #ifndef MSVC_COMPAT_WINDOWS_EXTRA_H 2 | #define MSVC_COMPAT_WINDOWS_EXTRA_H 3 | 4 | #ifndef ENOENT 5 | # define ENOENT ERROR_PATH_NOT_FOUND 6 | #endif 7 | #ifndef EINVAL 8 | # define EINVAL ERROR_BAD_ARGUMENTS 9 | #endif 10 | #ifndef EAGAIN 11 | # define EAGAIN ERROR_OUTOFMEMORY 12 | #endif 13 | #ifndef EPERM 14 | # define EPERM ERROR_WRITE_FAULT 15 | #endif 16 | #ifndef EFAULT 17 | # define EFAULT ERROR_INVALID_ADDRESS 18 | #endif 19 | #ifndef ENOMEM 20 | # define ENOMEM ERROR_NOT_ENOUGH_MEMORY 21 | #endif 22 | #ifndef ERANGE 23 | # define ERANGE ERROR_INVALID_DATA 24 | #endif 25 | 26 | #endif /* MSVC_COMPAT_WINDOWS_EXTRA_H */ 27 | -------------------------------------------------------------------------------- /deps/jemalloc/jemalloc.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@ 5 | install_suffix=@install_suffix@ 6 | 7 | Name: jemalloc 8 | Description: A general purpose malloc(3) implementation that emphasizes fragmentation avoidance and scalable concurrency support. 9 | URL: http://www.canonware.com/jemalloc 10 | Version: @jemalloc_version@ 11 | Cflags: -I${includedir} 12 | Libs: -L${libdir} -ljemalloc${install_suffix} 13 | -------------------------------------------------------------------------------- /deps/jemalloc/src/atomic.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_ATOMIC_C_ 2 | #include "jemalloc/internal/jemalloc_internal.h" 3 | -------------------------------------------------------------------------------- /deps/jemalloc/src/bitmap.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_BITMAP_C_ 2 | #include "jemalloc/internal/jemalloc_internal.h" 3 | 4 | /******************************************************************************/ 5 | 6 | void 7 | bitmap_info_init(bitmap_info_t *binfo, size_t nbits) 8 | { 9 | unsigned i; 10 | size_t group_count; 11 | 12 | assert(nbits > 0); 13 | assert(nbits <= (ZU(1) << LG_BITMAP_MAXBITS)); 14 | 15 | /* 16 | * Compute the number of groups necessary to store nbits bits, and 17 | * progressively work upward through the levels until reaching a level 18 | * that requires only one group. 19 | */ 20 | binfo->levels[0].group_offset = 0; 21 | group_count = BITMAP_BITS2GROUPS(nbits); 22 | for (i = 1; group_count > 1; i++) { 23 | assert(i < BITMAP_MAX_LEVELS); 24 | binfo->levels[i].group_offset = binfo->levels[i-1].group_offset 25 | + group_count; 26 | group_count = BITMAP_BITS2GROUPS(group_count); 27 | } 28 | binfo->levels[i].group_offset = binfo->levels[i-1].group_offset 29 | + group_count; 30 | assert(binfo->levels[i].group_offset <= BITMAP_GROUPS_MAX); 31 | binfo->nlevels = i; 32 | binfo->nbits = nbits; 33 | } 34 | 35 | size_t 36 | bitmap_info_ngroups(const bitmap_info_t *binfo) 37 | { 38 | 39 | return (binfo->levels[binfo->nlevels].group_offset << LG_SIZEOF_BITMAP); 40 | } 41 | 42 | size_t 43 | bitmap_size(size_t nbits) 44 | { 45 | bitmap_info_t binfo; 46 | 47 | bitmap_info_init(&binfo, nbits); 48 | return (bitmap_info_ngroups(&binfo)); 49 | } 50 | 51 | void 52 | bitmap_init(bitmap_t *bitmap, const bitmap_info_t *binfo) 53 | { 54 | size_t extra; 55 | unsigned i; 56 | 57 | /* 58 | * Bits are actually inverted with regard to the external bitmap 59 | * interface, so the bitmap starts out with all 1 bits, except for 60 | * trailing unused bits (if any). Note that each group uses bit 0 to 61 | * correspond to the first logical bit in the group, so extra bits 62 | * are the most significant bits of the last group. 63 | */ 64 | memset(bitmap, 0xffU, binfo->levels[binfo->nlevels].group_offset << 65 | LG_SIZEOF_BITMAP); 66 | extra = (BITMAP_GROUP_NBITS - (binfo->nbits & BITMAP_GROUP_NBITS_MASK)) 67 | & BITMAP_GROUP_NBITS_MASK; 68 | if (extra != 0) 69 | bitmap[binfo->levels[1].group_offset - 1] >>= extra; 70 | for (i = 1; i < binfo->nlevels; i++) { 71 | size_t group_count = binfo->levels[i].group_offset - 72 | binfo->levels[i-1].group_offset; 73 | extra = (BITMAP_GROUP_NBITS - (group_count & 74 | BITMAP_GROUP_NBITS_MASK)) & BITMAP_GROUP_NBITS_MASK; 75 | if (extra != 0) 76 | bitmap[binfo->levels[i+1].group_offset - 1] >>= extra; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /deps/jemalloc/src/chunk_mmap.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_CHUNK_MMAP_C_ 2 | #include "jemalloc/internal/jemalloc_internal.h" 3 | 4 | /******************************************************************************/ 5 | 6 | static void * 7 | chunk_alloc_mmap_slow(size_t size, size_t alignment, bool *zero, bool *commit) 8 | { 9 | void *ret; 10 | size_t alloc_size; 11 | 12 | alloc_size = size + alignment - PAGE; 13 | /* Beware size_t wrap-around. */ 14 | if (alloc_size < size) 15 | return (NULL); 16 | do { 17 | void *pages; 18 | size_t leadsize; 19 | pages = pages_map(NULL, alloc_size); 20 | if (pages == NULL) 21 | return (NULL); 22 | leadsize = ALIGNMENT_CEILING((uintptr_t)pages, alignment) - 23 | (uintptr_t)pages; 24 | ret = pages_trim(pages, alloc_size, leadsize, size); 25 | } while (ret == NULL); 26 | 27 | assert(ret != NULL); 28 | *zero = true; 29 | if (!*commit) 30 | *commit = pages_decommit(ret, size); 31 | return (ret); 32 | } 33 | 34 | void * 35 | chunk_alloc_mmap(size_t size, size_t alignment, bool *zero, bool *commit) 36 | { 37 | void *ret; 38 | size_t offset; 39 | 40 | /* 41 | * Ideally, there would be a way to specify alignment to mmap() (like 42 | * NetBSD has), but in the absence of such a feature, we have to work 43 | * hard to efficiently create aligned mappings. The reliable, but 44 | * slow method is to create a mapping that is over-sized, then trim the 45 | * excess. However, that always results in one or two calls to 46 | * pages_unmap(). 47 | * 48 | * Optimistically try mapping precisely the right amount before falling 49 | * back to the slow method, with the expectation that the optimistic 50 | * approach works most of the time. 51 | */ 52 | 53 | assert(alignment != 0); 54 | assert((alignment & chunksize_mask) == 0); 55 | 56 | ret = pages_map(NULL, size); 57 | if (ret == NULL) 58 | return (NULL); 59 | offset = ALIGNMENT_ADDR2OFFSET(ret, alignment); 60 | if (offset != 0) { 61 | pages_unmap(ret, size); 62 | return (chunk_alloc_mmap_slow(size, alignment, zero, commit)); 63 | } 64 | 65 | assert(ret != NULL); 66 | *zero = true; 67 | if (!*commit) 68 | *commit = pages_decommit(ret, size); 69 | return (ret); 70 | } 71 | 72 | bool 73 | chunk_dalloc_mmap(void *chunk, size_t size) 74 | { 75 | 76 | if (config_munmap) 77 | pages_unmap(chunk, size); 78 | 79 | return (!config_munmap); 80 | } 81 | -------------------------------------------------------------------------------- /deps/jemalloc/src/extent.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_EXTENT_C_ 2 | #include "jemalloc/internal/jemalloc_internal.h" 3 | 4 | /******************************************************************************/ 5 | 6 | JEMALLOC_INLINE_C size_t 7 | extent_quantize(size_t size) 8 | { 9 | 10 | /* 11 | * Round down to the nearest chunk size that can actually be requested 12 | * during normal huge allocation. 13 | */ 14 | return (index2size(size2index(size + 1) - 1)); 15 | } 16 | 17 | JEMALLOC_INLINE_C int 18 | extent_szad_comp(extent_node_t *a, extent_node_t *b) 19 | { 20 | int ret; 21 | size_t a_qsize = extent_quantize(extent_node_size_get(a)); 22 | size_t b_qsize = extent_quantize(extent_node_size_get(b)); 23 | 24 | /* 25 | * Compare based on quantized size rather than size, in order to sort 26 | * equally useful extents only by address. 27 | */ 28 | ret = (a_qsize > b_qsize) - (a_qsize < b_qsize); 29 | if (ret == 0) { 30 | uintptr_t a_addr = (uintptr_t)extent_node_addr_get(a); 31 | uintptr_t b_addr = (uintptr_t)extent_node_addr_get(b); 32 | 33 | ret = (a_addr > b_addr) - (a_addr < b_addr); 34 | } 35 | 36 | return (ret); 37 | } 38 | 39 | /* Generate red-black tree functions. */ 40 | rb_gen(, extent_tree_szad_, extent_tree_t, extent_node_t, szad_link, 41 | extent_szad_comp) 42 | 43 | JEMALLOC_INLINE_C int 44 | extent_ad_comp(extent_node_t *a, extent_node_t *b) 45 | { 46 | uintptr_t a_addr = (uintptr_t)extent_node_addr_get(a); 47 | uintptr_t b_addr = (uintptr_t)extent_node_addr_get(b); 48 | 49 | return ((a_addr > b_addr) - (a_addr < b_addr)); 50 | } 51 | 52 | /* Generate red-black tree functions. */ 53 | rb_gen(, extent_tree_ad_, extent_tree_t, extent_node_t, ad_link, extent_ad_comp) 54 | -------------------------------------------------------------------------------- /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/valgrind.c: -------------------------------------------------------------------------------- 1 | #include "jemalloc/internal/jemalloc_internal.h" 2 | #ifndef JEMALLOC_VALGRIND 3 | # error "This source file is for Valgrind integration." 4 | #endif 5 | 6 | #include 7 | 8 | void 9 | valgrind_make_mem_noaccess(void *ptr, size_t usize) 10 | { 11 | 12 | VALGRIND_MAKE_MEM_NOACCESS(ptr, usize); 13 | } 14 | 15 | void 16 | valgrind_make_mem_undefined(void *ptr, size_t usize) 17 | { 18 | 19 | VALGRIND_MAKE_MEM_UNDEFINED(ptr, usize); 20 | } 21 | 22 | void 23 | valgrind_make_mem_defined(void *ptr, size_t usize) 24 | { 25 | 26 | VALGRIND_MAKE_MEM_DEFINED(ptr, usize); 27 | } 28 | 29 | void 30 | valgrind_freelike_block(void *ptr, size_t usize) 31 | { 32 | 33 | VALGRIND_FREELIKE_BLOCK(ptr, usize); 34 | } 35 | -------------------------------------------------------------------------------- /deps/jemalloc/test/include/test/btalloc.h: -------------------------------------------------------------------------------- 1 | /* btalloc() provides a mechanism for allocating via permuted backtraces. */ 2 | void *btalloc(size_t size, unsigned bits); 3 | 4 | #define btalloc_n_proto(n) \ 5 | void *btalloc_##n(size_t size, unsigned bits); 6 | btalloc_n_proto(0) 7 | btalloc_n_proto(1) 8 | 9 | #define btalloc_n_gen(n) \ 10 | void * \ 11 | btalloc_##n(size_t size, unsigned bits) \ 12 | { \ 13 | void *p; \ 14 | \ 15 | if (bits == 0) \ 16 | p = mallocx(size, 0); \ 17 | else { \ 18 | switch (bits & 0x1U) { \ 19 | case 0: \ 20 | p = (btalloc_0(size, bits >> 1)); \ 21 | break; \ 22 | case 1: \ 23 | p = (btalloc_1(size, bits >> 1)); \ 24 | break; \ 25 | default: not_reached(); \ 26 | } \ 27 | } \ 28 | /* Intentionally sabotage tail call optimization. */ \ 29 | assert_ptr_not_null(p, "Unexpected mallocx() failure"); \ 30 | return (p); \ 31 | } 32 | -------------------------------------------------------------------------------- /deps/jemalloc/test/include/test/jemalloc_test_defs.h.in: -------------------------------------------------------------------------------- 1 | #include "jemalloc/internal/jemalloc_internal_defs.h" 2 | #include "jemalloc/internal/jemalloc_internal_decls.h" 3 | 4 | /* 5 | * For use by SFMT. configure.ac doesn't actually define HAVE_SSE2 because its 6 | * dependencies are notoriously unportable in practice. 7 | */ 8 | #undef HAVE_SSE2 9 | #undef HAVE_ALTIVEC 10 | -------------------------------------------------------------------------------- /deps/jemalloc/test/include/test/mq.h: -------------------------------------------------------------------------------- 1 | void mq_nanosleep(unsigned ns); 2 | 3 | /* 4 | * Simple templated message queue implementation that relies on only mutexes for 5 | * synchronization (which reduces portability issues). Given the following 6 | * setup: 7 | * 8 | * typedef struct mq_msg_s mq_msg_t; 9 | * struct mq_msg_s { 10 | * mq_msg(mq_msg_t) link; 11 | * [message data] 12 | * }; 13 | * mq_gen(, mq_, mq_t, mq_msg_t, link) 14 | * 15 | * The API is as follows: 16 | * 17 | * bool mq_init(mq_t *mq); 18 | * void mq_fini(mq_t *mq); 19 | * unsigned mq_count(mq_t *mq); 20 | * mq_msg_t *mq_tryget(mq_t *mq); 21 | * mq_msg_t *mq_get(mq_t *mq); 22 | * void mq_put(mq_t *mq, mq_msg_t *msg); 23 | * 24 | * The message queue linkage embedded in each message is to be treated as 25 | * externally opaque (no need to initialize or clean up externally). mq_fini() 26 | * does not perform any cleanup of messages, since it knows nothing of their 27 | * payloads. 28 | */ 29 | #define mq_msg(a_mq_msg_type) ql_elm(a_mq_msg_type) 30 | 31 | #define mq_gen(a_attr, a_prefix, a_mq_type, a_mq_msg_type, a_field) \ 32 | typedef struct { \ 33 | mtx_t lock; \ 34 | ql_head(a_mq_msg_type) msgs; \ 35 | unsigned count; \ 36 | } a_mq_type; \ 37 | a_attr bool \ 38 | a_prefix##init(a_mq_type *mq) { \ 39 | \ 40 | if (mtx_init(&mq->lock)) \ 41 | return (true); \ 42 | ql_new(&mq->msgs); \ 43 | mq->count = 0; \ 44 | return (false); \ 45 | } \ 46 | a_attr void \ 47 | a_prefix##fini(a_mq_type *mq) \ 48 | { \ 49 | \ 50 | mtx_fini(&mq->lock); \ 51 | } \ 52 | a_attr unsigned \ 53 | a_prefix##count(a_mq_type *mq) \ 54 | { \ 55 | unsigned count; \ 56 | \ 57 | mtx_lock(&mq->lock); \ 58 | count = mq->count; \ 59 | mtx_unlock(&mq->lock); \ 60 | return (count); \ 61 | } \ 62 | a_attr a_mq_msg_type * \ 63 | a_prefix##tryget(a_mq_type *mq) \ 64 | { \ 65 | a_mq_msg_type *msg; \ 66 | \ 67 | mtx_lock(&mq->lock); \ 68 | msg = ql_first(&mq->msgs); \ 69 | if (msg != NULL) { \ 70 | ql_head_remove(&mq->msgs, a_mq_msg_type, a_field); \ 71 | mq->count--; \ 72 | } \ 73 | mtx_unlock(&mq->lock); \ 74 | return (msg); \ 75 | } \ 76 | a_attr a_mq_msg_type * \ 77 | a_prefix##get(a_mq_type *mq) \ 78 | { \ 79 | a_mq_msg_type *msg; \ 80 | unsigned ns; \ 81 | \ 82 | msg = a_prefix##tryget(mq); \ 83 | if (msg != NULL) \ 84 | return (msg); \ 85 | \ 86 | ns = 1; \ 87 | while (true) { \ 88 | mq_nanosleep(ns); \ 89 | msg = a_prefix##tryget(mq); \ 90 | if (msg != NULL) \ 91 | return (msg); \ 92 | if (ns < 1000*1000*1000) { \ 93 | /* Double sleep time, up to max 1 second. */ \ 94 | ns <<= 1; \ 95 | if (ns > 1000*1000*1000) \ 96 | ns = 1000*1000*1000; \ 97 | } \ 98 | } \ 99 | } \ 100 | a_attr void \ 101 | a_prefix##put(a_mq_type *mq, a_mq_msg_type *msg) \ 102 | { \ 103 | \ 104 | mtx_lock(&mq->lock); \ 105 | ql_elm_new(msg, a_field); \ 106 | ql_tail_insert(&mq->msgs, msg, a_field); \ 107 | mq->count++; \ 108 | mtx_unlock(&mq->lock); \ 109 | } 110 | -------------------------------------------------------------------------------- /deps/jemalloc/test/include/test/mtx.h: -------------------------------------------------------------------------------- 1 | /* 2 | * mtx is a slightly simplified version of malloc_mutex. This code duplication 3 | * is unfortunate, but there are allocator bootstrapping considerations that 4 | * would leak into the test infrastructure if malloc_mutex were used directly 5 | * in tests. 6 | */ 7 | 8 | typedef struct { 9 | #ifdef _WIN32 10 | CRITICAL_SECTION lock; 11 | #elif (defined(JEMALLOC_OSSPIN)) 12 | OSSpinLock lock; 13 | #else 14 | pthread_mutex_t lock; 15 | #endif 16 | } mtx_t; 17 | 18 | bool mtx_init(mtx_t *mtx); 19 | void mtx_fini(mtx_t *mtx); 20 | void mtx_lock(mtx_t *mtx); 21 | void mtx_unlock(mtx_t *mtx); 22 | -------------------------------------------------------------------------------- /deps/jemalloc/test/include/test/thd.h: -------------------------------------------------------------------------------- 1 | /* Abstraction layer for threading in tests. */ 2 | #ifdef _WIN32 3 | typedef HANDLE thd_t; 4 | #else 5 | typedef pthread_t thd_t; 6 | #endif 7 | 8 | void thd_create(thd_t *thd, void *(*proc)(void *), void *arg); 9 | void thd_join(thd_t thd, void **ret); 10 | -------------------------------------------------------------------------------- /deps/jemalloc/test/include/test/timer.h: -------------------------------------------------------------------------------- 1 | /* Simple timer, for use in benchmark reporting. */ 2 | 3 | #include 4 | #include 5 | 6 | #define JEMALLOC_CLOCK_GETTIME defined(_POSIX_MONOTONIC_CLOCK) \ 7 | && _POSIX_MONOTONIC_CLOCK >= 0 8 | 9 | typedef struct { 10 | #ifdef _WIN32 11 | FILETIME ft0; 12 | FILETIME ft1; 13 | #elif JEMALLOC_CLOCK_GETTIME 14 | struct timespec ts0; 15 | struct timespec ts1; 16 | int clock_id; 17 | #else 18 | struct timeval tv0; 19 | struct timeval tv1; 20 | #endif 21 | } timedelta_t; 22 | 23 | void timer_start(timedelta_t *timer); 24 | void timer_stop(timedelta_t *timer); 25 | uint64_t timer_usec(const timedelta_t *timer); 26 | void timer_ratio(timedelta_t *a, timedelta_t *b, char *buf, size_t buflen); 27 | -------------------------------------------------------------------------------- /deps/jemalloc/test/integration/MALLOCX_ARENA.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #define NTHREADS 10 4 | 5 | static bool have_dss = 6 | #ifdef JEMALLOC_DSS 7 | true 8 | #else 9 | false 10 | #endif 11 | ; 12 | 13 | void * 14 | thd_start(void *arg) 15 | { 16 | unsigned thread_ind = (unsigned)(uintptr_t)arg; 17 | unsigned arena_ind; 18 | void *p; 19 | size_t sz; 20 | 21 | sz = sizeof(arena_ind); 22 | assert_d_eq(mallctl("arenas.extend", &arena_ind, &sz, NULL, 0), 0, 23 | "Error in arenas.extend"); 24 | 25 | if (thread_ind % 4 != 3) { 26 | size_t mib[3]; 27 | size_t miblen = sizeof(mib) / sizeof(size_t); 28 | const char *dss_precs[] = {"disabled", "primary", "secondary"}; 29 | unsigned prec_ind = thread_ind % 30 | (sizeof(dss_precs)/sizeof(char*)); 31 | const char *dss = dss_precs[prec_ind]; 32 | int expected_err = (have_dss || prec_ind == 0) ? 0 : EFAULT; 33 | assert_d_eq(mallctlnametomib("arena.0.dss", mib, &miblen), 0, 34 | "Error in mallctlnametomib()"); 35 | mib[1] = arena_ind; 36 | assert_d_eq(mallctlbymib(mib, miblen, NULL, NULL, (void *)&dss, 37 | sizeof(const char *)), expected_err, 38 | "Error in mallctlbymib()"); 39 | } 40 | 41 | p = mallocx(1, MALLOCX_ARENA(arena_ind)); 42 | assert_ptr_not_null(p, "Unexpected mallocx() error"); 43 | dallocx(p, 0); 44 | 45 | return (NULL); 46 | } 47 | 48 | TEST_BEGIN(test_MALLOCX_ARENA) 49 | { 50 | thd_t thds[NTHREADS]; 51 | unsigned i; 52 | 53 | for (i = 0; i < NTHREADS; i++) { 54 | thd_create(&thds[i], thd_start, 55 | (void *)(uintptr_t)i); 56 | } 57 | 58 | for (i = 0; i < NTHREADS; i++) 59 | thd_join(thds[i], NULL); 60 | } 61 | TEST_END 62 | 63 | int 64 | main(void) 65 | { 66 | 67 | return (test( 68 | test_MALLOCX_ARENA)); 69 | } 70 | -------------------------------------------------------------------------------- /deps/jemalloc/test/integration/aligned_alloc.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #define CHUNK 0x400000 4 | /* #define MAXALIGN ((size_t)UINT64_C(0x80000000000)) */ 5 | #define MAXALIGN ((size_t)0x2000000LU) 6 | #define NITER 4 7 | 8 | TEST_BEGIN(test_alignment_errors) 9 | { 10 | size_t alignment; 11 | void *p; 12 | 13 | alignment = 0; 14 | set_errno(0); 15 | p = aligned_alloc(alignment, 1); 16 | assert_false(p != NULL || get_errno() != EINVAL, 17 | "Expected error for invalid alignment %zu", alignment); 18 | 19 | for (alignment = sizeof(size_t); alignment < MAXALIGN; 20 | alignment <<= 1) { 21 | set_errno(0); 22 | p = aligned_alloc(alignment + 1, 1); 23 | assert_false(p != NULL || get_errno() != EINVAL, 24 | "Expected error for invalid alignment %zu", 25 | alignment + 1); 26 | } 27 | } 28 | TEST_END 29 | 30 | TEST_BEGIN(test_oom_errors) 31 | { 32 | size_t alignment, size; 33 | void *p; 34 | 35 | #if LG_SIZEOF_PTR == 3 36 | alignment = UINT64_C(0x8000000000000000); 37 | size = UINT64_C(0x8000000000000000); 38 | #else 39 | alignment = 0x80000000LU; 40 | size = 0x80000000LU; 41 | #endif 42 | set_errno(0); 43 | p = aligned_alloc(alignment, size); 44 | assert_false(p != NULL || get_errno() != ENOMEM, 45 | "Expected error for aligned_alloc(%zu, %zu)", 46 | alignment, size); 47 | 48 | #if LG_SIZEOF_PTR == 3 49 | alignment = UINT64_C(0x4000000000000000); 50 | size = UINT64_C(0xc000000000000001); 51 | #else 52 | alignment = 0x40000000LU; 53 | size = 0xc0000001LU; 54 | #endif 55 | set_errno(0); 56 | p = aligned_alloc(alignment, size); 57 | assert_false(p != NULL || get_errno() != ENOMEM, 58 | "Expected error for aligned_alloc(%zu, %zu)", 59 | alignment, size); 60 | 61 | alignment = 0x10LU; 62 | #if LG_SIZEOF_PTR == 3 63 | size = UINT64_C(0xfffffffffffffff0); 64 | #else 65 | size = 0xfffffff0LU; 66 | #endif 67 | set_errno(0); 68 | p = aligned_alloc(alignment, size); 69 | assert_false(p != NULL || get_errno() != ENOMEM, 70 | "Expected error for aligned_alloc(&p, %zu, %zu)", 71 | alignment, size); 72 | } 73 | TEST_END 74 | 75 | TEST_BEGIN(test_alignment_and_size) 76 | { 77 | size_t alignment, size, total; 78 | unsigned i; 79 | void *ps[NITER]; 80 | 81 | for (i = 0; i < NITER; i++) 82 | ps[i] = NULL; 83 | 84 | for (alignment = 8; 85 | alignment <= MAXALIGN; 86 | alignment <<= 1) { 87 | total = 0; 88 | for (size = 1; 89 | size < 3 * alignment && size < (1U << 31); 90 | size += (alignment >> (LG_SIZEOF_PTR-1)) - 1) { 91 | for (i = 0; i < NITER; i++) { 92 | ps[i] = aligned_alloc(alignment, size); 93 | if (ps[i] == NULL) { 94 | char buf[BUFERROR_BUF]; 95 | 96 | buferror(get_errno(), buf, sizeof(buf)); 97 | test_fail( 98 | "Error for alignment=%zu, " 99 | "size=%zu (%#zx): %s", 100 | alignment, size, size, buf); 101 | } 102 | total += malloc_usable_size(ps[i]); 103 | if (total >= (MAXALIGN << 1)) 104 | break; 105 | } 106 | for (i = 0; i < NITER; i++) { 107 | if (ps[i] != NULL) { 108 | free(ps[i]); 109 | ps[i] = NULL; 110 | } 111 | } 112 | } 113 | } 114 | } 115 | TEST_END 116 | 117 | int 118 | main(void) 119 | { 120 | 121 | return (test( 122 | test_alignment_errors, 123 | test_oom_errors, 124 | test_alignment_and_size)); 125 | } 126 | -------------------------------------------------------------------------------- /deps/jemalloc/test/integration/overflow.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | TEST_BEGIN(test_overflow) 4 | { 5 | unsigned nhchunks; 6 | size_t mib[4]; 7 | size_t sz, miblen, max_size_class; 8 | void *p; 9 | 10 | sz = sizeof(unsigned); 11 | assert_d_eq(mallctl("arenas.nhchunks", &nhchunks, &sz, NULL, 0), 0, 12 | "Unexpected mallctl() error"); 13 | 14 | miblen = sizeof(mib) / sizeof(size_t); 15 | assert_d_eq(mallctlnametomib("arenas.hchunk.0.size", mib, &miblen), 0, 16 | "Unexpected mallctlnametomib() error"); 17 | mib[2] = nhchunks - 1; 18 | 19 | sz = sizeof(size_t); 20 | assert_d_eq(mallctlbymib(mib, miblen, &max_size_class, &sz, NULL, 0), 0, 21 | "Unexpected mallctlbymib() error"); 22 | 23 | assert_ptr_null(malloc(max_size_class + 1), 24 | "Expected OOM due to over-sized allocation request"); 25 | assert_ptr_null(malloc(SIZE_T_MAX), 26 | "Expected OOM due to over-sized allocation request"); 27 | 28 | assert_ptr_null(calloc(1, max_size_class + 1), 29 | "Expected OOM due to over-sized allocation request"); 30 | assert_ptr_null(calloc(1, SIZE_T_MAX), 31 | "Expected OOM due to over-sized allocation request"); 32 | 33 | p = malloc(1); 34 | assert_ptr_not_null(p, "Unexpected malloc() OOM"); 35 | assert_ptr_null(realloc(p, max_size_class + 1), 36 | "Expected OOM due to over-sized allocation request"); 37 | assert_ptr_null(realloc(p, SIZE_T_MAX), 38 | "Expected OOM due to over-sized allocation request"); 39 | free(p); 40 | } 41 | TEST_END 42 | 43 | int 44 | main(void) 45 | { 46 | 47 | return (test( 48 | test_overflow)); 49 | } 50 | -------------------------------------------------------------------------------- /deps/jemalloc/test/integration/posix_memalign.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #define CHUNK 0x400000 4 | /* #define MAXALIGN ((size_t)UINT64_C(0x80000000000)) */ 5 | #define MAXALIGN ((size_t)0x2000000LU) 6 | #define NITER 4 7 | 8 | TEST_BEGIN(test_alignment_errors) 9 | { 10 | size_t alignment; 11 | void *p; 12 | 13 | for (alignment = 0; alignment < sizeof(void *); alignment++) { 14 | assert_d_eq(posix_memalign(&p, alignment, 1), EINVAL, 15 | "Expected error for invalid alignment %zu", 16 | alignment); 17 | } 18 | 19 | for (alignment = sizeof(size_t); alignment < MAXALIGN; 20 | alignment <<= 1) { 21 | assert_d_ne(posix_memalign(&p, alignment + 1, 1), 0, 22 | "Expected error for invalid alignment %zu", 23 | alignment + 1); 24 | } 25 | } 26 | TEST_END 27 | 28 | TEST_BEGIN(test_oom_errors) 29 | { 30 | size_t alignment, size; 31 | void *p; 32 | 33 | #if LG_SIZEOF_PTR == 3 34 | alignment = UINT64_C(0x8000000000000000); 35 | size = UINT64_C(0x8000000000000000); 36 | #else 37 | alignment = 0x80000000LU; 38 | size = 0x80000000LU; 39 | #endif 40 | assert_d_ne(posix_memalign(&p, alignment, size), 0, 41 | "Expected error for posix_memalign(&p, %zu, %zu)", 42 | alignment, size); 43 | 44 | #if LG_SIZEOF_PTR == 3 45 | alignment = UINT64_C(0x4000000000000000); 46 | size = UINT64_C(0xc000000000000001); 47 | #else 48 | alignment = 0x40000000LU; 49 | size = 0xc0000001LU; 50 | #endif 51 | assert_d_ne(posix_memalign(&p, alignment, size), 0, 52 | "Expected error for posix_memalign(&p, %zu, %zu)", 53 | alignment, size); 54 | 55 | alignment = 0x10LU; 56 | #if LG_SIZEOF_PTR == 3 57 | size = UINT64_C(0xfffffffffffffff0); 58 | #else 59 | size = 0xfffffff0LU; 60 | #endif 61 | assert_d_ne(posix_memalign(&p, alignment, size), 0, 62 | "Expected error for posix_memalign(&p, %zu, %zu)", 63 | alignment, size); 64 | } 65 | TEST_END 66 | 67 | TEST_BEGIN(test_alignment_and_size) 68 | { 69 | size_t alignment, size, total; 70 | unsigned i; 71 | int err; 72 | void *ps[NITER]; 73 | 74 | for (i = 0; i < NITER; i++) 75 | ps[i] = NULL; 76 | 77 | for (alignment = 8; 78 | alignment <= MAXALIGN; 79 | alignment <<= 1) { 80 | total = 0; 81 | for (size = 1; 82 | size < 3 * alignment && size < (1U << 31); 83 | size += (alignment >> (LG_SIZEOF_PTR-1)) - 1) { 84 | for (i = 0; i < NITER; i++) { 85 | err = posix_memalign(&ps[i], 86 | alignment, size); 87 | if (err) { 88 | char buf[BUFERROR_BUF]; 89 | 90 | buferror(get_errno(), buf, sizeof(buf)); 91 | test_fail( 92 | "Error for alignment=%zu, " 93 | "size=%zu (%#zx): %s", 94 | alignment, size, size, buf); 95 | } 96 | total += malloc_usable_size(ps[i]); 97 | if (total >= (MAXALIGN << 1)) 98 | break; 99 | } 100 | for (i = 0; i < NITER; i++) { 101 | if (ps[i] != NULL) { 102 | free(ps[i]); 103 | ps[i] = NULL; 104 | } 105 | } 106 | } 107 | } 108 | } 109 | TEST_END 110 | 111 | int 112 | main(void) 113 | { 114 | 115 | return (test( 116 | test_alignment_errors, 117 | test_oom_errors, 118 | test_alignment_and_size)); 119 | } 120 | -------------------------------------------------------------------------------- /deps/jemalloc/test/integration/sdallocx.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #define MAXALIGN (((size_t)1) << 25) 4 | #define NITER 4 5 | 6 | TEST_BEGIN(test_basic) 7 | { 8 | void *ptr = mallocx(64, 0); 9 | sdallocx(ptr, 64, 0); 10 | } 11 | TEST_END 12 | 13 | TEST_BEGIN(test_alignment_and_size) 14 | { 15 | size_t nsz, sz, alignment, total; 16 | unsigned i; 17 | void *ps[NITER]; 18 | 19 | for (i = 0; i < NITER; i++) 20 | ps[i] = NULL; 21 | 22 | for (alignment = 8; 23 | alignment <= MAXALIGN; 24 | alignment <<= 1) { 25 | total = 0; 26 | for (sz = 1; 27 | sz < 3 * alignment && sz < (1U << 31); 28 | sz += (alignment >> (LG_SIZEOF_PTR-1)) - 1) { 29 | for (i = 0; i < NITER; i++) { 30 | nsz = nallocx(sz, MALLOCX_ALIGN(alignment) | 31 | MALLOCX_ZERO); 32 | ps[i] = mallocx(sz, MALLOCX_ALIGN(alignment) | 33 | MALLOCX_ZERO); 34 | total += nsz; 35 | if (total >= (MAXALIGN << 1)) 36 | break; 37 | } 38 | for (i = 0; i < NITER; i++) { 39 | if (ps[i] != NULL) { 40 | sdallocx(ps[i], sz, 41 | MALLOCX_ALIGN(alignment)); 42 | ps[i] = NULL; 43 | } 44 | } 45 | } 46 | } 47 | } 48 | TEST_END 49 | 50 | int 51 | main(void) 52 | { 53 | 54 | return (test( 55 | test_basic, 56 | test_alignment_and_size)); 57 | } 58 | -------------------------------------------------------------------------------- /deps/jemalloc/test/integration/thread_arena.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #define NTHREADS 10 4 | 5 | void * 6 | thd_start(void *arg) 7 | { 8 | unsigned main_arena_ind = *(unsigned *)arg; 9 | void *p; 10 | unsigned arena_ind; 11 | size_t size; 12 | int err; 13 | 14 | p = malloc(1); 15 | assert_ptr_not_null(p, "Error in malloc()"); 16 | free(p); 17 | 18 | size = sizeof(arena_ind); 19 | if ((err = mallctl("thread.arena", &arena_ind, &size, &main_arena_ind, 20 | sizeof(main_arena_ind)))) { 21 | char buf[BUFERROR_BUF]; 22 | 23 | buferror(err, buf, sizeof(buf)); 24 | test_fail("Error in mallctl(): %s", buf); 25 | } 26 | 27 | size = sizeof(arena_ind); 28 | if ((err = mallctl("thread.arena", &arena_ind, &size, NULL, 0))) { 29 | char buf[BUFERROR_BUF]; 30 | 31 | buferror(err, buf, sizeof(buf)); 32 | test_fail("Error in mallctl(): %s", buf); 33 | } 34 | assert_u_eq(arena_ind, main_arena_ind, 35 | "Arena index should be same as for main thread"); 36 | 37 | return (NULL); 38 | } 39 | 40 | TEST_BEGIN(test_thread_arena) 41 | { 42 | void *p; 43 | unsigned arena_ind; 44 | size_t size; 45 | int err; 46 | thd_t thds[NTHREADS]; 47 | unsigned i; 48 | 49 | p = malloc(1); 50 | assert_ptr_not_null(p, "Error in malloc()"); 51 | 52 | size = sizeof(arena_ind); 53 | if ((err = mallctl("thread.arena", &arena_ind, &size, NULL, 0))) { 54 | char buf[BUFERROR_BUF]; 55 | 56 | buferror(err, buf, sizeof(buf)); 57 | test_fail("Error in mallctl(): %s", buf); 58 | } 59 | 60 | for (i = 0; i < NTHREADS; i++) { 61 | thd_create(&thds[i], thd_start, 62 | (void *)&arena_ind); 63 | } 64 | 65 | for (i = 0; i < NTHREADS; i++) { 66 | intptr_t join_ret; 67 | thd_join(thds[i], (void *)&join_ret); 68 | assert_zd_eq(join_ret, 0, "Unexpected thread join error"); 69 | } 70 | } 71 | TEST_END 72 | 73 | int 74 | main(void) 75 | { 76 | 77 | return (test( 78 | test_thread_arena)); 79 | } 80 | -------------------------------------------------------------------------------- /deps/jemalloc/test/integration/thread_tcache_enabled.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | static const bool config_tcache = 4 | #ifdef JEMALLOC_TCACHE 5 | true 6 | #else 7 | false 8 | #endif 9 | ; 10 | 11 | void * 12 | thd_start(void *arg) 13 | { 14 | int err; 15 | size_t sz; 16 | bool e0, e1; 17 | 18 | sz = sizeof(bool); 19 | if ((err = mallctl("thread.tcache.enabled", &e0, &sz, NULL, 0))) { 20 | if (err == ENOENT) { 21 | assert_false(config_tcache, 22 | "ENOENT should only be returned if tcache is " 23 | "disabled"); 24 | } 25 | goto label_ENOENT; 26 | } 27 | 28 | if (e0) { 29 | e1 = false; 30 | assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), 31 | 0, "Unexpected mallctl() error"); 32 | assert_true(e0, "tcache should be enabled"); 33 | } 34 | 35 | e1 = true; 36 | assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), 0, 37 | "Unexpected mallctl() error"); 38 | assert_false(e0, "tcache should be disabled"); 39 | 40 | e1 = true; 41 | assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), 0, 42 | "Unexpected mallctl() error"); 43 | assert_true(e0, "tcache should be enabled"); 44 | 45 | e1 = false; 46 | assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), 0, 47 | "Unexpected mallctl() error"); 48 | assert_true(e0, "tcache should be enabled"); 49 | 50 | e1 = false; 51 | assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), 0, 52 | "Unexpected mallctl() error"); 53 | assert_false(e0, "tcache should be disabled"); 54 | 55 | free(malloc(1)); 56 | e1 = true; 57 | assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), 0, 58 | "Unexpected mallctl() error"); 59 | assert_false(e0, "tcache should be disabled"); 60 | 61 | free(malloc(1)); 62 | e1 = true; 63 | assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), 0, 64 | "Unexpected mallctl() error"); 65 | assert_true(e0, "tcache should be enabled"); 66 | 67 | free(malloc(1)); 68 | e1 = false; 69 | assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), 0, 70 | "Unexpected mallctl() error"); 71 | assert_true(e0, "tcache should be enabled"); 72 | 73 | free(malloc(1)); 74 | e1 = false; 75 | assert_d_eq(mallctl("thread.tcache.enabled", &e0, &sz, &e1, sz), 0, 76 | "Unexpected mallctl() error"); 77 | assert_false(e0, "tcache should be disabled"); 78 | 79 | free(malloc(1)); 80 | return (NULL); 81 | label_ENOENT: 82 | test_skip("\"thread.tcache.enabled\" mallctl not available"); 83 | return (NULL); 84 | } 85 | 86 | TEST_BEGIN(test_main_thread) 87 | { 88 | 89 | thd_start(NULL); 90 | } 91 | TEST_END 92 | 93 | TEST_BEGIN(test_subthread) 94 | { 95 | thd_t thd; 96 | 97 | thd_create(&thd, thd_start, NULL); 98 | thd_join(thd, NULL); 99 | } 100 | TEST_END 101 | 102 | int 103 | main(void) 104 | { 105 | 106 | /* Run tests multiple times to check for bad interactions. */ 107 | return (test( 108 | test_main_thread, 109 | test_subthread, 110 | test_main_thread, 111 | test_subthread, 112 | test_main_thread)); 113 | } 114 | -------------------------------------------------------------------------------- /deps/jemalloc/test/src/btalloc.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | void * 4 | btalloc(size_t size, unsigned bits) 5 | { 6 | 7 | return (btalloc_0(size, bits)); 8 | } 9 | -------------------------------------------------------------------------------- /deps/jemalloc/test/src/btalloc_0.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | btalloc_n_gen(0) 4 | -------------------------------------------------------------------------------- /deps/jemalloc/test/src/btalloc_1.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | btalloc_n_gen(1) 4 | -------------------------------------------------------------------------------- /deps/jemalloc/test/src/math.c: -------------------------------------------------------------------------------- 1 | #define MATH_C_ 2 | #include "test/jemalloc_test.h" 3 | -------------------------------------------------------------------------------- /deps/jemalloc/test/src/mq.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | /* 4 | * Sleep for approximately ns nanoseconds. No lower *nor* upper bound on sleep 5 | * time is guaranteed. 6 | */ 7 | void 8 | mq_nanosleep(unsigned ns) 9 | { 10 | 11 | assert(ns <= 1000*1000*1000); 12 | 13 | #ifdef _WIN32 14 | Sleep(ns / 1000); 15 | #else 16 | { 17 | struct timespec timeout; 18 | 19 | if (ns < 1000*1000*1000) { 20 | timeout.tv_sec = 0; 21 | timeout.tv_nsec = ns; 22 | } else { 23 | timeout.tv_sec = 1; 24 | timeout.tv_nsec = 0; 25 | } 26 | nanosleep(&timeout, NULL); 27 | } 28 | #endif 29 | } 30 | -------------------------------------------------------------------------------- /deps/jemalloc/test/src/mtx.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #ifndef _CRT_SPINCOUNT 4 | #define _CRT_SPINCOUNT 4000 5 | #endif 6 | 7 | bool 8 | mtx_init(mtx_t *mtx) 9 | { 10 | 11 | #ifdef _WIN32 12 | if (!InitializeCriticalSectionAndSpinCount(&mtx->lock, _CRT_SPINCOUNT)) 13 | return (true); 14 | #elif (defined(JEMALLOC_OSSPIN)) 15 | mtx->lock = 0; 16 | #else 17 | pthread_mutexattr_t attr; 18 | 19 | if (pthread_mutexattr_init(&attr) != 0) 20 | return (true); 21 | pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_DEFAULT); 22 | if (pthread_mutex_init(&mtx->lock, &attr) != 0) { 23 | pthread_mutexattr_destroy(&attr); 24 | return (true); 25 | } 26 | pthread_mutexattr_destroy(&attr); 27 | #endif 28 | return (false); 29 | } 30 | 31 | void 32 | mtx_fini(mtx_t *mtx) 33 | { 34 | 35 | #ifdef _WIN32 36 | #elif (defined(JEMALLOC_OSSPIN)) 37 | #else 38 | pthread_mutex_destroy(&mtx->lock); 39 | #endif 40 | } 41 | 42 | void 43 | mtx_lock(mtx_t *mtx) 44 | { 45 | 46 | #ifdef _WIN32 47 | EnterCriticalSection(&mtx->lock); 48 | #elif (defined(JEMALLOC_OSSPIN)) 49 | OSSpinLockLock(&mtx->lock); 50 | #else 51 | pthread_mutex_lock(&mtx->lock); 52 | #endif 53 | } 54 | 55 | void 56 | mtx_unlock(mtx_t *mtx) 57 | { 58 | 59 | #ifdef _WIN32 60 | LeaveCriticalSection(&mtx->lock); 61 | #elif (defined(JEMALLOC_OSSPIN)) 62 | OSSpinLockUnlock(&mtx->lock); 63 | #else 64 | pthread_mutex_unlock(&mtx->lock); 65 | #endif 66 | } 67 | -------------------------------------------------------------------------------- /deps/jemalloc/test/src/test.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | static unsigned test_count = 0; 4 | static test_status_t test_counts[test_status_count] = {0, 0, 0}; 5 | static test_status_t test_status = test_status_pass; 6 | static const char * test_name = ""; 7 | 8 | JEMALLOC_FORMAT_PRINTF(1, 2) 9 | void 10 | test_skip(const char *format, ...) 11 | { 12 | va_list ap; 13 | 14 | va_start(ap, format); 15 | malloc_vcprintf(NULL, NULL, format, ap); 16 | va_end(ap); 17 | malloc_printf("\n"); 18 | test_status = test_status_skip; 19 | } 20 | 21 | JEMALLOC_FORMAT_PRINTF(1, 2) 22 | void 23 | test_fail(const char *format, ...) 24 | { 25 | va_list ap; 26 | 27 | va_start(ap, format); 28 | malloc_vcprintf(NULL, NULL, format, ap); 29 | va_end(ap); 30 | malloc_printf("\n"); 31 | test_status = test_status_fail; 32 | } 33 | 34 | static const char * 35 | test_status_string(test_status_t test_status) 36 | { 37 | 38 | switch (test_status) { 39 | case test_status_pass: return "pass"; 40 | case test_status_skip: return "skip"; 41 | case test_status_fail: return "fail"; 42 | default: not_reached(); 43 | } 44 | } 45 | 46 | void 47 | p_test_init(const char *name) 48 | { 49 | 50 | test_count++; 51 | test_status = test_status_pass; 52 | test_name = name; 53 | } 54 | 55 | void 56 | p_test_fini(void) 57 | { 58 | 59 | test_counts[test_status]++; 60 | malloc_printf("%s: %s\n", test_name, test_status_string(test_status)); 61 | } 62 | 63 | test_status_t 64 | p_test(test_t *t, ...) 65 | { 66 | test_status_t ret; 67 | va_list ap; 68 | 69 | /* 70 | * Make sure initialization occurs prior to running tests. Tests are 71 | * special because they may use internal facilities prior to triggering 72 | * initialization as a side effect of calling into the public API. This 73 | * is a final safety that works even if jemalloc_constructor() doesn't 74 | * run, as for MSVC builds. 75 | */ 76 | if (nallocx(1, 0) == 0) { 77 | malloc_printf("Initialization error"); 78 | return (test_status_fail); 79 | } 80 | 81 | ret = test_status_pass; 82 | va_start(ap, t); 83 | for (; t != NULL; t = va_arg(ap, test_t *)) { 84 | t(); 85 | if (test_status > ret) 86 | ret = test_status; 87 | } 88 | va_end(ap); 89 | 90 | malloc_printf("--- %s: %u/%u, %s: %u/%u, %s: %u/%u ---\n", 91 | test_status_string(test_status_pass), 92 | test_counts[test_status_pass], test_count, 93 | test_status_string(test_status_skip), 94 | test_counts[test_status_skip], test_count, 95 | test_status_string(test_status_fail), 96 | test_counts[test_status_fail], test_count); 97 | 98 | return (ret); 99 | } 100 | 101 | void 102 | p_test_fail(const char *prefix, const char *message) 103 | { 104 | 105 | malloc_cprintf(NULL, NULL, "%s%s\n", prefix, message); 106 | test_status = test_status_fail; 107 | } 108 | -------------------------------------------------------------------------------- /deps/jemalloc/test/src/thd.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #ifdef _WIN32 4 | void 5 | thd_create(thd_t *thd, void *(*proc)(void *), void *arg) 6 | { 7 | LPTHREAD_START_ROUTINE routine = (LPTHREAD_START_ROUTINE)proc; 8 | *thd = CreateThread(NULL, 0, routine, arg, 0, NULL); 9 | if (*thd == NULL) 10 | test_fail("Error in CreateThread()\n"); 11 | } 12 | 13 | void 14 | thd_join(thd_t thd, void **ret) 15 | { 16 | 17 | if (WaitForSingleObject(thd, INFINITE) == WAIT_OBJECT_0 && ret) { 18 | DWORD exit_code; 19 | GetExitCodeThread(thd, (LPDWORD) &exit_code); 20 | *ret = (void *)(uintptr_t)exit_code; 21 | } 22 | } 23 | 24 | #else 25 | void 26 | thd_create(thd_t *thd, void *(*proc)(void *), void *arg) 27 | { 28 | 29 | if (pthread_create(thd, NULL, proc, arg) != 0) 30 | test_fail("Error in pthread_create()\n"); 31 | } 32 | 33 | void 34 | thd_join(thd_t thd, void **ret) 35 | { 36 | 37 | pthread_join(thd, ret); 38 | } 39 | #endif 40 | -------------------------------------------------------------------------------- /deps/jemalloc/test/src/timer.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | void 4 | timer_start(timedelta_t *timer) 5 | { 6 | 7 | #ifdef _WIN32 8 | GetSystemTimeAsFileTime(&timer->ft0); 9 | #elif JEMALLOC_CLOCK_GETTIME 10 | if (sysconf(_SC_MONOTONIC_CLOCK) <= 0) 11 | timer->clock_id = CLOCK_REALTIME; 12 | else 13 | timer->clock_id = CLOCK_MONOTONIC; 14 | clock_gettime(timer->clock_id, &timer->ts0); 15 | #else 16 | gettimeofday(&timer->tv0, NULL); 17 | #endif 18 | } 19 | 20 | void 21 | timer_stop(timedelta_t *timer) 22 | { 23 | 24 | #ifdef _WIN32 25 | GetSystemTimeAsFileTime(&timer->ft0); 26 | #elif JEMALLOC_CLOCK_GETTIME 27 | clock_gettime(timer->clock_id, &timer->ts1); 28 | #else 29 | gettimeofday(&timer->tv1, NULL); 30 | #endif 31 | } 32 | 33 | uint64_t 34 | timer_usec(const timedelta_t *timer) 35 | { 36 | 37 | #ifdef _WIN32 38 | uint64_t t0, t1; 39 | t0 = (((uint64_t)timer->ft0.dwHighDateTime) << 32) | 40 | timer->ft0.dwLowDateTime; 41 | t1 = (((uint64_t)timer->ft1.dwHighDateTime) << 32) | 42 | timer->ft1.dwLowDateTime; 43 | return ((t1 - t0) / 10); 44 | #elif JEMALLOC_CLOCK_GETTIME 45 | return (((timer->ts1.tv_sec - timer->ts0.tv_sec) * 1000000) + 46 | (timer->ts1.tv_nsec - timer->ts0.tv_nsec) / 1000); 47 | #else 48 | return (((timer->tv1.tv_sec - timer->tv0.tv_sec) * 1000000) + 49 | timer->tv1.tv_usec - timer->tv0.tv_usec); 50 | #endif 51 | } 52 | 53 | void 54 | timer_ratio(timedelta_t *a, timedelta_t *b, char *buf, size_t buflen) 55 | { 56 | uint64_t t0 = timer_usec(a); 57 | uint64_t t1 = timer_usec(b); 58 | uint64_t mult; 59 | unsigned i = 0; 60 | unsigned j; 61 | int n; 62 | 63 | /* Whole. */ 64 | n = malloc_snprintf(&buf[i], buflen-i, "%"FMTu64, t0 / t1); 65 | i += n; 66 | if (i >= buflen) 67 | return; 68 | mult = 1; 69 | for (j = 0; j < n; j++) 70 | mult *= 10; 71 | 72 | /* Decimal. */ 73 | n = malloc_snprintf(&buf[i], buflen-i, "."); 74 | i += n; 75 | 76 | /* Fraction. */ 77 | while (i < buflen-1) { 78 | uint64_t round = (i+1 == buflen-1 && ((t0 * mult * 10 / t1) % 10 79 | >= 5)) ? 1 : 0; 80 | n = malloc_snprintf(&buf[i], buflen-i, 81 | "%"FMTu64, (t0 * mult / t1) % 10 + round); 82 | i += n; 83 | mult *= 10; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /deps/jemalloc/test/test.sh.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | case @abi@ in 4 | macho) 5 | export DYLD_FALLBACK_LIBRARY_PATH="@objroot@lib" 6 | ;; 7 | pecoff) 8 | export PATH="${PATH}:@objroot@lib" 9 | ;; 10 | *) 11 | ;; 12 | esac 13 | 14 | # Corresponds to test_status_t. 15 | pass_code=0 16 | skip_code=1 17 | fail_code=2 18 | 19 | pass_count=0 20 | skip_count=0 21 | fail_count=0 22 | for t in $@; do 23 | if [ $pass_count -ne 0 -o $skip_count -ne 0 -o $fail_count != 0 ] ; then 24 | echo 25 | fi 26 | echo "=== ${t} ===" 27 | ${t}@exe@ @abs_srcroot@ @abs_objroot@ 28 | result_code=$? 29 | case ${result_code} in 30 | ${pass_code}) 31 | pass_count=$((pass_count+1)) 32 | ;; 33 | ${skip_code}) 34 | skip_count=$((skip_count+1)) 35 | ;; 36 | ${fail_code}) 37 | fail_count=$((fail_count+1)) 38 | ;; 39 | *) 40 | echo "Test harness error" 1>&2 41 | exit 1 42 | esac 43 | done 44 | 45 | total_count=`expr ${pass_count} + ${skip_count} + ${fail_count}` 46 | echo 47 | echo "Test suite summary: pass: ${pass_count}/${total_count}, skip: ${skip_count}/${total_count}, fail: ${fail_count}/${total_count}" 48 | 49 | if [ ${fail_count} -eq 0 ] ; then 50 | exit 0 51 | else 52 | exit 1 53 | fi 54 | -------------------------------------------------------------------------------- /deps/jemalloc/test/unit/junk_alloc.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_TEST_JUNK_OPT "junk:alloc" 2 | #include "junk.c" 3 | #undef JEMALLOC_TEST_JUNK_OPT 4 | -------------------------------------------------------------------------------- /deps/jemalloc/test/unit/junk_free.c: -------------------------------------------------------------------------------- 1 | #define JEMALLOC_TEST_JUNK_OPT "junk:free" 2 | #include "junk.c" 3 | #undef JEMALLOC_TEST_JUNK_OPT 4 | -------------------------------------------------------------------------------- /deps/jemalloc/test/unit/lg_chunk.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | /* 4 | * Make sure that opt.lg_chunk clamping is sufficient. In practice, this test 5 | * program will fail a debug assertion during initialization and abort (rather 6 | * than the test soft-failing) if clamping is insufficient. 7 | */ 8 | const char *malloc_conf = "lg_chunk:0"; 9 | 10 | TEST_BEGIN(test_lg_chunk_clamp) 11 | { 12 | void *p; 13 | 14 | p = mallocx(1, 0); 15 | assert_ptr_not_null(p, "Unexpected mallocx() failure"); 16 | dallocx(p, 0); 17 | } 18 | TEST_END 19 | 20 | int 21 | main(void) 22 | { 23 | 24 | return (test( 25 | test_lg_chunk_clamp)); 26 | } 27 | -------------------------------------------------------------------------------- /deps/jemalloc/test/unit/mq.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #define NSENDERS 3 4 | #define NMSGS 100000 5 | 6 | typedef struct mq_msg_s mq_msg_t; 7 | struct mq_msg_s { 8 | mq_msg(mq_msg_t) link; 9 | }; 10 | mq_gen(static, mq_, mq_t, mq_msg_t, link) 11 | 12 | TEST_BEGIN(test_mq_basic) 13 | { 14 | mq_t mq; 15 | mq_msg_t msg; 16 | 17 | assert_false(mq_init(&mq), "Unexpected mq_init() failure"); 18 | assert_u_eq(mq_count(&mq), 0, "mq should be empty"); 19 | assert_ptr_null(mq_tryget(&mq), 20 | "mq_tryget() should fail when the queue is empty"); 21 | 22 | mq_put(&mq, &msg); 23 | assert_u_eq(mq_count(&mq), 1, "mq should contain one message"); 24 | assert_ptr_eq(mq_tryget(&mq), &msg, "mq_tryget() should return msg"); 25 | 26 | mq_put(&mq, &msg); 27 | assert_ptr_eq(mq_get(&mq), &msg, "mq_get() should return msg"); 28 | 29 | mq_fini(&mq); 30 | } 31 | TEST_END 32 | 33 | static void * 34 | thd_receiver_start(void *arg) 35 | { 36 | mq_t *mq = (mq_t *)arg; 37 | unsigned i; 38 | 39 | for (i = 0; i < (NSENDERS * NMSGS); i++) { 40 | mq_msg_t *msg = mq_get(mq); 41 | assert_ptr_not_null(msg, "mq_get() should never return NULL"); 42 | dallocx(msg, 0); 43 | } 44 | return (NULL); 45 | } 46 | 47 | static void * 48 | thd_sender_start(void *arg) 49 | { 50 | mq_t *mq = (mq_t *)arg; 51 | unsigned i; 52 | 53 | for (i = 0; i < NMSGS; i++) { 54 | mq_msg_t *msg; 55 | void *p; 56 | p = mallocx(sizeof(mq_msg_t), 0); 57 | assert_ptr_not_null(p, "Unexpected mallocx() failure"); 58 | msg = (mq_msg_t *)p; 59 | mq_put(mq, msg); 60 | } 61 | return (NULL); 62 | } 63 | 64 | TEST_BEGIN(test_mq_threaded) 65 | { 66 | mq_t mq; 67 | thd_t receiver; 68 | thd_t senders[NSENDERS]; 69 | unsigned i; 70 | 71 | assert_false(mq_init(&mq), "Unexpected mq_init() failure"); 72 | 73 | thd_create(&receiver, thd_receiver_start, (void *)&mq); 74 | for (i = 0; i < NSENDERS; i++) 75 | thd_create(&senders[i], thd_sender_start, (void *)&mq); 76 | 77 | thd_join(receiver, NULL); 78 | for (i = 0; i < NSENDERS; i++) 79 | thd_join(senders[i], NULL); 80 | 81 | mq_fini(&mq); 82 | } 83 | TEST_END 84 | 85 | int 86 | main(void) 87 | { 88 | 89 | return (test( 90 | test_mq_basic, 91 | test_mq_threaded)); 92 | } 93 | 94 | -------------------------------------------------------------------------------- /deps/jemalloc/test/unit/mtx.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #define NTHREADS 2 4 | #define NINCRS 2000000 5 | 6 | TEST_BEGIN(test_mtx_basic) 7 | { 8 | mtx_t mtx; 9 | 10 | assert_false(mtx_init(&mtx), "Unexpected mtx_init() failure"); 11 | mtx_lock(&mtx); 12 | mtx_unlock(&mtx); 13 | mtx_fini(&mtx); 14 | } 15 | TEST_END 16 | 17 | typedef struct { 18 | mtx_t mtx; 19 | unsigned x; 20 | } thd_start_arg_t; 21 | 22 | static void * 23 | thd_start(void *varg) 24 | { 25 | thd_start_arg_t *arg = (thd_start_arg_t *)varg; 26 | unsigned i; 27 | 28 | for (i = 0; i < NINCRS; i++) { 29 | mtx_lock(&arg->mtx); 30 | arg->x++; 31 | mtx_unlock(&arg->mtx); 32 | } 33 | return (NULL); 34 | } 35 | 36 | TEST_BEGIN(test_mtx_race) 37 | { 38 | thd_start_arg_t arg; 39 | thd_t thds[NTHREADS]; 40 | unsigned i; 41 | 42 | assert_false(mtx_init(&arg.mtx), "Unexpected mtx_init() failure"); 43 | arg.x = 0; 44 | for (i = 0; i < NTHREADS; i++) 45 | thd_create(&thds[i], thd_start, (void *)&arg); 46 | for (i = 0; i < NTHREADS; i++) 47 | thd_join(thds[i], NULL); 48 | assert_u_eq(arg.x, NTHREADS * NINCRS, 49 | "Race-related counter corruption"); 50 | } 51 | TEST_END 52 | 53 | int 54 | main(void) 55 | { 56 | 57 | return (test( 58 | test_mtx_basic, 59 | test_mtx_race)); 60 | } 61 | -------------------------------------------------------------------------------- /deps/jemalloc/test/unit/prof_accum.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #define NTHREADS 4 4 | #define NALLOCS_PER_THREAD 50 5 | #define DUMP_INTERVAL 1 6 | #define BT_COUNT_CHECK_INTERVAL 5 7 | 8 | #ifdef JEMALLOC_PROF 9 | const char *malloc_conf = 10 | "prof:true,prof_accum:true,prof_active:false,lg_prof_sample:0"; 11 | #endif 12 | 13 | static int 14 | prof_dump_open_intercept(bool propagate_err, const char *filename) 15 | { 16 | int fd; 17 | 18 | fd = open("/dev/null", O_WRONLY); 19 | assert_d_ne(fd, -1, "Unexpected open() failure"); 20 | 21 | return (fd); 22 | } 23 | 24 | static void * 25 | alloc_from_permuted_backtrace(unsigned thd_ind, unsigned iteration) 26 | { 27 | 28 | return (btalloc(1, thd_ind*NALLOCS_PER_THREAD + iteration)); 29 | } 30 | 31 | static void * 32 | thd_start(void *varg) 33 | { 34 | unsigned thd_ind = *(unsigned *)varg; 35 | size_t bt_count_prev, bt_count; 36 | unsigned i_prev, i; 37 | 38 | i_prev = 0; 39 | bt_count_prev = 0; 40 | for (i = 0; i < NALLOCS_PER_THREAD; i++) { 41 | void *p = alloc_from_permuted_backtrace(thd_ind, i); 42 | dallocx(p, 0); 43 | if (i % DUMP_INTERVAL == 0) { 44 | assert_d_eq(mallctl("prof.dump", NULL, NULL, NULL, 0), 45 | 0, "Unexpected error while dumping heap profile"); 46 | } 47 | 48 | if (i % BT_COUNT_CHECK_INTERVAL == 0 || 49 | i+1 == NALLOCS_PER_THREAD) { 50 | bt_count = prof_bt_count(); 51 | assert_zu_le(bt_count_prev+(i-i_prev), bt_count, 52 | "Expected larger backtrace count increase"); 53 | i_prev = i; 54 | bt_count_prev = bt_count; 55 | } 56 | } 57 | 58 | return (NULL); 59 | } 60 | 61 | TEST_BEGIN(test_idump) 62 | { 63 | bool active; 64 | thd_t thds[NTHREADS]; 65 | unsigned thd_args[NTHREADS]; 66 | unsigned i; 67 | 68 | test_skip_if(!config_prof); 69 | 70 | active = true; 71 | assert_d_eq(mallctl("prof.active", NULL, NULL, &active, sizeof(active)), 72 | 0, "Unexpected mallctl failure while activating profiling"); 73 | 74 | prof_dump_open = prof_dump_open_intercept; 75 | 76 | for (i = 0; i < NTHREADS; i++) { 77 | thd_args[i] = i; 78 | thd_create(&thds[i], thd_start, (void *)&thd_args[i]); 79 | } 80 | for (i = 0; i < NTHREADS; i++) 81 | thd_join(thds[i], NULL); 82 | } 83 | TEST_END 84 | 85 | int 86 | main(void) 87 | { 88 | 89 | return (test( 90 | test_idump)); 91 | } 92 | -------------------------------------------------------------------------------- /deps/jemalloc/test/unit/prof_gdump.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #ifdef JEMALLOC_PROF 4 | const char *malloc_conf = "prof:true,prof_active:false,prof_gdump:true"; 5 | #endif 6 | 7 | static bool did_prof_dump_open; 8 | 9 | static int 10 | prof_dump_open_intercept(bool propagate_err, const char *filename) 11 | { 12 | int fd; 13 | 14 | did_prof_dump_open = true; 15 | 16 | fd = open("/dev/null", O_WRONLY); 17 | assert_d_ne(fd, -1, "Unexpected open() failure"); 18 | 19 | return (fd); 20 | } 21 | 22 | TEST_BEGIN(test_gdump) 23 | { 24 | bool active, gdump, gdump_old; 25 | void *p, *q, *r, *s; 26 | size_t sz; 27 | 28 | test_skip_if(!config_prof); 29 | 30 | active = true; 31 | assert_d_eq(mallctl("prof.active", NULL, NULL, &active, sizeof(active)), 32 | 0, "Unexpected mallctl failure while activating profiling"); 33 | 34 | prof_dump_open = prof_dump_open_intercept; 35 | 36 | did_prof_dump_open = false; 37 | p = mallocx(chunksize, 0); 38 | assert_ptr_not_null(p, "Unexpected mallocx() failure"); 39 | assert_true(did_prof_dump_open, "Expected a profile dump"); 40 | 41 | did_prof_dump_open = false; 42 | q = mallocx(chunksize, 0); 43 | assert_ptr_not_null(q, "Unexpected mallocx() failure"); 44 | assert_true(did_prof_dump_open, "Expected a profile dump"); 45 | 46 | gdump = false; 47 | sz = sizeof(gdump_old); 48 | assert_d_eq(mallctl("prof.gdump", &gdump_old, &sz, &gdump, 49 | sizeof(gdump)), 0, 50 | "Unexpected mallctl failure while disabling prof.gdump"); 51 | assert(gdump_old); 52 | did_prof_dump_open = false; 53 | r = mallocx(chunksize, 0); 54 | assert_ptr_not_null(q, "Unexpected mallocx() failure"); 55 | assert_false(did_prof_dump_open, "Unexpected profile dump"); 56 | 57 | gdump = true; 58 | sz = sizeof(gdump_old); 59 | assert_d_eq(mallctl("prof.gdump", &gdump_old, &sz, &gdump, 60 | sizeof(gdump)), 0, 61 | "Unexpected mallctl failure while enabling prof.gdump"); 62 | assert(!gdump_old); 63 | did_prof_dump_open = false; 64 | s = mallocx(chunksize, 0); 65 | assert_ptr_not_null(q, "Unexpected mallocx() failure"); 66 | assert_true(did_prof_dump_open, "Expected a profile dump"); 67 | 68 | dallocx(p, 0); 69 | dallocx(q, 0); 70 | dallocx(r, 0); 71 | dallocx(s, 0); 72 | } 73 | TEST_END 74 | 75 | int 76 | main(void) 77 | { 78 | 79 | return (test( 80 | test_gdump)); 81 | } 82 | -------------------------------------------------------------------------------- /deps/jemalloc/test/unit/prof_idump.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #ifdef JEMALLOC_PROF 4 | const char *malloc_conf = 5 | "prof:true,prof_accum:true,prof_active:false,lg_prof_sample:0," 6 | "lg_prof_interval:0"; 7 | #endif 8 | 9 | static bool did_prof_dump_open; 10 | 11 | static int 12 | prof_dump_open_intercept(bool propagate_err, const char *filename) 13 | { 14 | int fd; 15 | 16 | did_prof_dump_open = true; 17 | 18 | fd = open("/dev/null", O_WRONLY); 19 | assert_d_ne(fd, -1, "Unexpected open() failure"); 20 | 21 | return (fd); 22 | } 23 | 24 | TEST_BEGIN(test_idump) 25 | { 26 | bool active; 27 | void *p; 28 | 29 | test_skip_if(!config_prof); 30 | 31 | active = true; 32 | assert_d_eq(mallctl("prof.active", NULL, NULL, &active, sizeof(active)), 33 | 0, "Unexpected mallctl failure while activating profiling"); 34 | 35 | prof_dump_open = prof_dump_open_intercept; 36 | 37 | did_prof_dump_open = false; 38 | p = mallocx(1, 0); 39 | assert_ptr_not_null(p, "Unexpected mallocx() failure"); 40 | dallocx(p, 0); 41 | assert_true(did_prof_dump_open, "Expected a profile dump"); 42 | } 43 | TEST_END 44 | 45 | int 46 | main(void) 47 | { 48 | 49 | return (test( 50 | test_idump)); 51 | } 52 | -------------------------------------------------------------------------------- /deps/jemalloc/test/unit/quarantine.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #define QUARANTINE_SIZE 8192 4 | #define STRINGIFY_HELPER(x) #x 5 | #define STRINGIFY(x) STRINGIFY_HELPER(x) 6 | 7 | #ifdef JEMALLOC_FILL 8 | const char *malloc_conf = "abort:false,junk:true,redzone:true,quarantine:" 9 | STRINGIFY(QUARANTINE_SIZE); 10 | #endif 11 | 12 | void 13 | quarantine_clear(void) 14 | { 15 | void *p; 16 | 17 | p = mallocx(QUARANTINE_SIZE*2, 0); 18 | assert_ptr_not_null(p, "Unexpected mallocx() failure"); 19 | dallocx(p, 0); 20 | } 21 | 22 | TEST_BEGIN(test_quarantine) 23 | { 24 | #define SZ ZU(256) 25 | #define NQUARANTINED (QUARANTINE_SIZE/SZ) 26 | void *quarantined[NQUARANTINED+1]; 27 | size_t i, j; 28 | 29 | test_skip_if(!config_fill); 30 | 31 | assert_zu_eq(nallocx(SZ, 0), SZ, 32 | "SZ=%zu does not precisely equal a size class", SZ); 33 | 34 | quarantine_clear(); 35 | 36 | /* 37 | * Allocate enough regions to completely fill the quarantine, plus one 38 | * more. The last iteration occurs with a completely full quarantine, 39 | * but no regions should be drained from the quarantine until the last 40 | * deallocation occurs. Therefore no region recycling should occur 41 | * until after this loop completes. 42 | */ 43 | for (i = 0; i < NQUARANTINED+1; i++) { 44 | void *p = mallocx(SZ, 0); 45 | assert_ptr_not_null(p, "Unexpected mallocx() failure"); 46 | quarantined[i] = p; 47 | dallocx(p, 0); 48 | for (j = 0; j < i; j++) { 49 | assert_ptr_ne(p, quarantined[j], 50 | "Quarantined region recycled too early; " 51 | "i=%zu, j=%zu", i, j); 52 | } 53 | } 54 | #undef NQUARANTINED 55 | #undef SZ 56 | } 57 | TEST_END 58 | 59 | static bool detected_redzone_corruption; 60 | 61 | static void 62 | arena_redzone_corruption_replacement(void *ptr, size_t usize, bool after, 63 | size_t offset, uint8_t byte) 64 | { 65 | 66 | detected_redzone_corruption = true; 67 | } 68 | 69 | TEST_BEGIN(test_quarantine_redzone) 70 | { 71 | char *s; 72 | arena_redzone_corruption_t *arena_redzone_corruption_orig; 73 | 74 | test_skip_if(!config_fill); 75 | 76 | arena_redzone_corruption_orig = arena_redzone_corruption; 77 | arena_redzone_corruption = arena_redzone_corruption_replacement; 78 | 79 | /* Test underflow. */ 80 | detected_redzone_corruption = false; 81 | s = (char *)mallocx(1, 0); 82 | assert_ptr_not_null((void *)s, "Unexpected mallocx() failure"); 83 | s[-1] = 0xbb; 84 | dallocx(s, 0); 85 | assert_true(detected_redzone_corruption, 86 | "Did not detect redzone corruption"); 87 | 88 | /* Test overflow. */ 89 | detected_redzone_corruption = false; 90 | s = (char *)mallocx(1, 0); 91 | assert_ptr_not_null((void *)s, "Unexpected mallocx() failure"); 92 | s[sallocx(s, 0)] = 0xbb; 93 | dallocx(s, 0); 94 | assert_true(detected_redzone_corruption, 95 | "Did not detect redzone corruption"); 96 | 97 | arena_redzone_corruption = arena_redzone_corruption_orig; 98 | } 99 | TEST_END 100 | 101 | int 102 | main(void) 103 | { 104 | 105 | return (test( 106 | test_quarantine, 107 | test_quarantine_redzone)); 108 | } 109 | -------------------------------------------------------------------------------- /deps/jemalloc/test/unit/size_classes.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | static size_t 4 | get_max_size_class(void) 5 | { 6 | unsigned nhchunks; 7 | size_t mib[4]; 8 | size_t sz, miblen, max_size_class; 9 | 10 | sz = sizeof(unsigned); 11 | assert_d_eq(mallctl("arenas.nhchunks", &nhchunks, &sz, NULL, 0), 0, 12 | "Unexpected mallctl() error"); 13 | 14 | miblen = sizeof(mib) / sizeof(size_t); 15 | assert_d_eq(mallctlnametomib("arenas.hchunk.0.size", mib, &miblen), 0, 16 | "Unexpected mallctlnametomib() error"); 17 | mib[2] = nhchunks - 1; 18 | 19 | sz = sizeof(size_t); 20 | assert_d_eq(mallctlbymib(mib, miblen, &max_size_class, &sz, NULL, 0), 0, 21 | "Unexpected mallctlbymib() error"); 22 | 23 | return (max_size_class); 24 | } 25 | 26 | TEST_BEGIN(test_size_classes) 27 | { 28 | size_t size_class, max_size_class; 29 | szind_t index, max_index; 30 | 31 | max_size_class = get_max_size_class(); 32 | max_index = size2index(max_size_class); 33 | 34 | for (index = 0, size_class = index2size(index); index < max_index || 35 | size_class < max_size_class; index++, size_class = 36 | index2size(index)) { 37 | assert_true(index < max_index, 38 | "Loop conditionals should be equivalent; index=%u, " 39 | "size_class=%zu (%#zx)", index, size_class, size_class); 40 | assert_true(size_class < max_size_class, 41 | "Loop conditionals should be equivalent; index=%u, " 42 | "size_class=%zu (%#zx)", index, size_class, size_class); 43 | 44 | assert_u_eq(index, size2index(size_class), 45 | "size2index() does not reverse index2size(): index=%u -->" 46 | " size_class=%zu --> index=%u --> size_class=%zu", index, 47 | size_class, size2index(size_class), 48 | index2size(size2index(size_class))); 49 | assert_zu_eq(size_class, index2size(size2index(size_class)), 50 | "index2size() does not reverse size2index(): index=%u -->" 51 | " size_class=%zu --> index=%u --> size_class=%zu", index, 52 | size_class, size2index(size_class), 53 | index2size(size2index(size_class))); 54 | 55 | assert_u_eq(index+1, size2index(size_class+1), 56 | "Next size_class does not round up properly"); 57 | 58 | assert_zu_eq(size_class, (index > 0) ? 59 | s2u(index2size(index-1)+1) : s2u(1), 60 | "s2u() does not round up to size class"); 61 | assert_zu_eq(size_class, s2u(size_class-1), 62 | "s2u() does not round up to size class"); 63 | assert_zu_eq(size_class, s2u(size_class), 64 | "s2u() does not compute same size class"); 65 | assert_zu_eq(s2u(size_class+1), index2size(index+1), 66 | "s2u() does not round up to next size class"); 67 | } 68 | 69 | assert_u_eq(index, size2index(index2size(index)), 70 | "size2index() does not reverse index2size()"); 71 | assert_zu_eq(max_size_class, index2size(size2index(max_size_class)), 72 | "index2size() does not reverse size2index()"); 73 | 74 | assert_zu_eq(size_class, s2u(index2size(index-1)+1), 75 | "s2u() does not round up to size class"); 76 | assert_zu_eq(size_class, s2u(size_class-1), 77 | "s2u() does not round up to size class"); 78 | assert_zu_eq(size_class, s2u(size_class), 79 | "s2u() does not compute same size class"); 80 | } 81 | TEST_END 82 | 83 | int 84 | main(void) 85 | { 86 | 87 | return (test( 88 | test_size_classes)); 89 | } 90 | -------------------------------------------------------------------------------- /deps/jemalloc/test/unit/tsd.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #define THREAD_DATA 0x72b65c10 4 | 5 | typedef unsigned int data_t; 6 | 7 | static bool data_cleanup_executed; 8 | 9 | malloc_tsd_types(data_, data_t) 10 | malloc_tsd_protos(, data_, data_t) 11 | 12 | void 13 | data_cleanup(void *arg) 14 | { 15 | data_t *data = (data_t *)arg; 16 | 17 | if (!data_cleanup_executed) { 18 | assert_x_eq(*data, THREAD_DATA, 19 | "Argument passed into cleanup function should match tsd " 20 | "value"); 21 | } 22 | data_cleanup_executed = true; 23 | 24 | /* 25 | * Allocate during cleanup for two rounds, in order to assure that 26 | * jemalloc's internal tsd reinitialization happens. 27 | */ 28 | switch (*data) { 29 | case THREAD_DATA: 30 | *data = 1; 31 | data_tsd_set(data); 32 | break; 33 | case 1: 34 | *data = 2; 35 | data_tsd_set(data); 36 | break; 37 | case 2: 38 | return; 39 | default: 40 | not_reached(); 41 | } 42 | 43 | { 44 | void *p = mallocx(1, 0); 45 | assert_ptr_not_null(p, "Unexpeced mallocx() failure"); 46 | dallocx(p, 0); 47 | } 48 | } 49 | 50 | malloc_tsd_externs(data_, data_t) 51 | #define DATA_INIT 0x12345678 52 | malloc_tsd_data(, data_, data_t, DATA_INIT) 53 | malloc_tsd_funcs(, data_, data_t, DATA_INIT, data_cleanup) 54 | 55 | static void * 56 | thd_start(void *arg) 57 | { 58 | data_t d = (data_t)(uintptr_t)arg; 59 | void *p; 60 | 61 | assert_x_eq(*data_tsd_get(), DATA_INIT, 62 | "Initial tsd get should return initialization value"); 63 | 64 | p = malloc(1); 65 | assert_ptr_not_null(p, "Unexpected malloc() failure"); 66 | 67 | data_tsd_set(&d); 68 | assert_x_eq(*data_tsd_get(), d, 69 | "After tsd set, tsd get should return value that was set"); 70 | 71 | d = 0; 72 | assert_x_eq(*data_tsd_get(), (data_t)(uintptr_t)arg, 73 | "Resetting local data should have no effect on tsd"); 74 | 75 | free(p); 76 | return (NULL); 77 | } 78 | 79 | TEST_BEGIN(test_tsd_main_thread) 80 | { 81 | 82 | thd_start((void *) 0xa5f3e329); 83 | } 84 | TEST_END 85 | 86 | TEST_BEGIN(test_tsd_sub_thread) 87 | { 88 | thd_t thd; 89 | 90 | data_cleanup_executed = false; 91 | thd_create(&thd, thd_start, (void *)THREAD_DATA); 92 | thd_join(thd, NULL); 93 | assert_true(data_cleanup_executed, 94 | "Cleanup function should have executed"); 95 | } 96 | TEST_END 97 | 98 | int 99 | main(void) 100 | { 101 | 102 | data_tsd_boot(); 103 | 104 | return (test( 105 | test_tsd_main_thread, 106 | test_tsd_sub_thread)); 107 | } 108 | -------------------------------------------------------------------------------- /deps/jemalloc/test/unit/zero.c: -------------------------------------------------------------------------------- 1 | #include "test/jemalloc_test.h" 2 | 3 | #ifdef JEMALLOC_FILL 4 | const char *malloc_conf = 5 | "abort:false,junk:false,zero:true,redzone:false,quarantine:0"; 6 | #endif 7 | 8 | static void 9 | test_zero(size_t sz_min, size_t sz_max) 10 | { 11 | char *s; 12 | size_t sz_prev, sz, i; 13 | 14 | sz_prev = 0; 15 | s = (char *)mallocx(sz_min, 0); 16 | assert_ptr_not_null((void *)s, "Unexpected mallocx() failure"); 17 | 18 | for (sz = sallocx(s, 0); sz <= sz_max; 19 | sz_prev = sz, sz = sallocx(s, 0)) { 20 | if (sz_prev > 0) { 21 | assert_c_eq(s[0], 'a', 22 | "Previously allocated byte %zu/%zu is corrupted", 23 | ZU(0), sz_prev); 24 | assert_c_eq(s[sz_prev-1], 'a', 25 | "Previously allocated byte %zu/%zu is corrupted", 26 | sz_prev-1, sz_prev); 27 | } 28 | 29 | for (i = sz_prev; i < sz; i++) { 30 | assert_c_eq(s[i], 0x0, 31 | "Newly allocated byte %zu/%zu isn't zero-filled", 32 | i, sz); 33 | s[i] = 'a'; 34 | } 35 | 36 | if (xallocx(s, sz+1, 0, 0) == sz) { 37 | s = (char *)rallocx(s, sz+1, 0); 38 | assert_ptr_not_null((void *)s, 39 | "Unexpected rallocx() failure"); 40 | } 41 | } 42 | 43 | dallocx(s, 0); 44 | } 45 | 46 | TEST_BEGIN(test_zero_small) 47 | { 48 | 49 | test_skip_if(!config_fill); 50 | test_zero(1, SMALL_MAXCLASS-1); 51 | } 52 | TEST_END 53 | 54 | TEST_BEGIN(test_zero_large) 55 | { 56 | 57 | test_skip_if(!config_fill); 58 | test_zero(SMALL_MAXCLASS+1, large_maxclass); 59 | } 60 | TEST_END 61 | 62 | TEST_BEGIN(test_zero_huge) 63 | { 64 | 65 | test_skip_if(!config_fill); 66 | test_zero(large_maxclass+1, chunksize*2); 67 | } 68 | TEST_END 69 | 70 | int 71 | main(void) 72 | { 73 | 74 | return (test( 75 | test_zero_small, 76 | test_zero_large, 77 | test_zero_huge)); 78 | } 79 | -------------------------------------------------------------------------------- /deps/linenoise/.gitignore: -------------------------------------------------------------------------------- 1 | linenoise_example 2 | *.dSYM 3 | history.txt 4 | -------------------------------------------------------------------------------- /deps/linenoise/Makefile: -------------------------------------------------------------------------------- 1 | STD= 2 | WARN= -Wall 3 | OPT= -Os 4 | 5 | R_CFLAGS= $(STD) $(WARN) $(OPT) $(DEBUG) $(CFLAGS) 6 | R_LDFLAGS= $(LDFLAGS) 7 | DEBUG= -g 8 | 9 | R_CC=$(CC) $(R_CFLAGS) 10 | R_LD=$(CC) $(R_LDFLAGS) 11 | 12 | linenoise.o: linenoise.h linenoise.c 13 | 14 | linenoise_example: linenoise.o example.o 15 | $(R_LD) -o $@ $^ 16 | 17 | .c.o: 18 | $(R_CC) -c $< 19 | 20 | clean: 21 | rm -f linenoise_example *.o 22 | -------------------------------------------------------------------------------- /deps/linenoise/README.markdown: -------------------------------------------------------------------------------- 1 | # Linenoise 2 | 3 | A minimal, zero-config, BSD licensed, readline replacement used in Redis, 4 | MongoDB, and Android. 5 | 6 | * Single and multi line editing mode with the usual key bindings implemented. 7 | * History handling. 8 | * Completion. 9 | * About 1,100 lines of BSD license source code. 10 | * Only uses a subset of VT100 escapes (ANSI.SYS compatible). 11 | 12 | ## Can a line editing library be 20k lines of code? 13 | 14 | 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? 15 | 16 | So what usually happens is either: 17 | 18 | * 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 (Real world example of this problem: Tclsh). 19 | * Smaller programs not using a configure script not supporting line editing at all (A problem we had with Redis-cli for instance). 20 | 21 | The result is a pollution of binaries without line editing support. 22 | 23 | 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. 24 | 25 | ## Terminals, in 2010. 26 | 27 | Apparently almost every terminal you can happen to use today has some kind of support for basic VT100 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, and now can work even on ANSI.SYS compatible terminals, since no 28 | VT220 specific sequences are used anymore. 29 | 30 | The library is currently about 1100 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. 31 | 32 | ## Tested with... 33 | 34 | * Linux text only console ($TERM = linux) 35 | * Linux KDE terminal application ($TERM = xterm) 36 | * Linux xterm ($TERM = xterm) 37 | * Linux Buildroot ($TERM = vt100) 38 | * Mac OS X iTerm ($TERM = xterm) 39 | * Mac OS X default Terminal.app ($TERM = xterm) 40 | * OpenBSD 4.5 through an OSX Terminal.app ($TERM = screen) 41 | * IBM AIX 6.1 42 | * FreeBSD xterm ($TERM = xterm) 43 | * ANSI.SYS 44 | 45 | Please test it everywhere you can and report back! 46 | 47 | ## Let's push this forward! 48 | 49 | Patches should be provided in the respect of linenoise sensibility for small 50 | easy to understand code. 51 | 52 | Send feedbacks to antirez at gmail 53 | -------------------------------------------------------------------------------- /deps/linenoise/example.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "linenoise.h" 5 | 6 | 7 | void completion(const char *buf, linenoiseCompletions *lc) { 8 | if (buf[0] == 'h') { 9 | linenoiseAddCompletion(lc,"hello"); 10 | linenoiseAddCompletion(lc,"hello there"); 11 | } 12 | } 13 | 14 | int main(int argc, char **argv) { 15 | char *line; 16 | char *prgname = argv[0]; 17 | 18 | /* Parse options, with --multiline we enable multi line editing. */ 19 | while(argc > 1) { 20 | argc--; 21 | argv++; 22 | if (!strcmp(*argv,"--multiline")) { 23 | linenoiseSetMultiLine(1); 24 | printf("Multi-line mode enabled.\n"); 25 | } else if (!strcmp(*argv,"--keycodes")) { 26 | linenoisePrintKeyCodes(); 27 | exit(0); 28 | } else { 29 | fprintf(stderr, "Usage: %s [--multiline] [--keycodes]\n", prgname); 30 | exit(1); 31 | } 32 | } 33 | 34 | /* Set the completion callback. This will be called every time the 35 | * user uses the key. */ 36 | linenoiseSetCompletionCallback(completion); 37 | 38 | /* Load history from file. The history file is just a plain text file 39 | * where entries are separated by newlines. */ 40 | linenoiseHistoryLoad("history.txt"); /* Load the history at startup */ 41 | 42 | /* Now this is the main loop of the typical linenoise-based application. 43 | * The call to linenoise() will block as long as the user types something 44 | * and presses enter. 45 | * 46 | * The typed string is returned as a malloc() allocated string by 47 | * linenoise, so the user needs to free() it. */ 48 | while((line = linenoise("hello> ")) != NULL) { 49 | /* Do something with the string. */ 50 | if (line[0] != '\0' && line[0] != '/') { 51 | printf("echo: '%s'\n", line); 52 | linenoiseHistoryAdd(line); /* Add to the history. */ 53 | linenoiseHistorySave("history.txt"); /* Save the history on disk. */ 54 | } else if (!strncmp(line,"/historylen",11)) { 55 | /* The "/historylen" command will change the history len. */ 56 | int len = atoi(line+11); 57 | linenoiseHistorySetMaxLen(len); 58 | } else if (line[0] == '/') { 59 | printf("Unreconized command: %s\n", line); 60 | } 61 | free(line); 62 | } 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /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 | * ------------------------------------------------------------------------ 7 | * 8 | * Copyright (c) 2010, Salvatore Sanfilippo 9 | * Copyright (c) 2010, Pieter Noordhuis 10 | * 11 | * All rights reserved. 12 | * 13 | * Redistribution and use in source and binary forms, with or without 14 | * modification, are permitted provided that the following conditions are 15 | * met: 16 | * 17 | * * Redistributions of source code must retain the above copyright 18 | * notice, this list of conditions and the following disclaimer. 19 | * 20 | * * Redistributions in binary form must reproduce the above copyright 21 | * notice, this list of conditions and the following disclaimer in the 22 | * documentation and/or other materials provided with the distribution. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 27 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 28 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 29 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 30 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 31 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 34 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | #ifndef __LINENOISE_H 38 | #define __LINENOISE_H 39 | 40 | #ifdef __cplusplus 41 | extern "C" { 42 | #endif 43 | 44 | typedef struct linenoiseCompletions { 45 | size_t len; 46 | char **cvec; 47 | } linenoiseCompletions; 48 | 49 | typedef void(linenoiseCompletionCallback)(const char *, linenoiseCompletions *); 50 | void linenoiseSetCompletionCallback(linenoiseCompletionCallback *); 51 | void linenoiseAddCompletion(linenoiseCompletions *, const char *); 52 | 53 | char *linenoise(const char *prompt); 54 | int linenoiseHistoryAdd(const char *line); 55 | int linenoiseHistorySetMaxLen(int len); 56 | int linenoiseHistorySave(const char *filename); 57 | int linenoiseHistoryLoad(const char *filename); 58 | void linenoiseClearScreen(void); 59 | void linenoiseSetMultiLine(int ml); 60 | void linenoisePrintKeyCodes(void); 61 | 62 | #ifdef __cplusplus 63 | } 64 | #endif 65 | 66 | #endif /* __LINENOISE_H */ 67 | -------------------------------------------------------------------------------- /deps/update-jemalloc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | VER=$1 3 | URL="http://www.canonware.com/download/jemalloc/jemalloc-${VER}.tar.bz2" 4 | echo "Downloading $URL" 5 | curl $URL > /tmp/jemalloc.tar.bz2 6 | tar xvjf /tmp/jemalloc.tar.bz2 7 | rm -rf jemalloc 8 | mv jemalloc-${VER} jemalloc 9 | echo "Use git status, add all files and commit changes." 10 | -------------------------------------------------------------------------------- /runtest: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ./runtest-unit 3 | if [ $? -eq 0 ]; then 4 | ./runtest-cluster 5 | fi 6 | -------------------------------------------------------------------------------- /runtest-cluster: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | TCL_VERSIONS="8.5 8.6" 3 | TCLSH="" 4 | 5 | for VERSION in $TCL_VERSIONS; do 6 | TCL=`which tclsh$VERSION 2>/dev/null` && TCLSH=$TCL 7 | done 8 | 9 | if [ -z $TCLSH ] 10 | then 11 | echo "You need tcl 8.5 or newer in order to run the Discnt test" 12 | exit 1 13 | fi 14 | $TCLSH tests/cluster/run.tcl $* 15 | -------------------------------------------------------------------------------- /runtest-unit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | TCL_VERSIONS="8.5 8.6" 3 | TCLSH="" 4 | 5 | for VERSION in $TCL_VERSIONS; do 6 | TCL=`which tclsh$VERSION 2>/dev/null` && TCLSH=$TCL 7 | done 8 | 9 | if [ -z $TCLSH ] 10 | then 11 | echo "You need tcl 8.5 or newer in order to run the Discnt test" 12 | exit 1 13 | fi 14 | $TCLSH tests/test_helper.tcl $* 15 | -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | *.gcda 2 | *.gcno 3 | *.gcov 4 | lcov-html 5 | -------------------------------------------------------------------------------- /src/asciilogo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2015, Erik Dubbelboer 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 Discnt 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 | char *ascii_logo = 31 | " _ Discnt %s (%s/%d) %s bit\n" 32 | " __|_\\__ \n" 33 | " =O__.-.__) Port: %d\n" 34 | " /_/ PID: %ld\n" 35 | " \n\n"; 36 | 37 | -------------------------------------------------------------------------------- /src/bio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2012, 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 Discnt 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 | /* Exported API */ 31 | void bioInit(void); 32 | void bioCreateBackgroundJob(int type, void *arg1, void *arg2, void *arg3); 33 | unsigned long long bioPendingJobsOfType(int type); 34 | unsigned long long bioWaitStepOfType(int type); 35 | time_t bioOlderJobOfType(int type); 36 | void bioKillThreads(void); 37 | 38 | /* Background job opcodes */ 39 | #define BIO_CLOSE_FILE 0 /* Deferred close(2) syscall. */ 40 | #define BIO_AOF_FSYNC 1 /* Deferred AOF fsync. */ 41 | #define BIO_NUM_OPS 2 42 | -------------------------------------------------------------------------------- /src/crc64.h: -------------------------------------------------------------------------------- 1 | #ifndef CRC64_H 2 | #define CRC64_H 3 | 4 | #include 5 | 6 | uint64_t crc64(uint64_t crc, const unsigned char *s, uint64_t l); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /src/ddb.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2015, Erik Dubbelboer 3 | * Copyright (c) 2009-2012, 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 __DDB_H 32 | #define __DDB_H 33 | 34 | #include 35 | #include "rio.h" 36 | 37 | /* TBD: include only necessary headers. */ 38 | #include "server.h" 39 | 40 | /* The current DDB version. When the format changes in a way that is no longer 41 | * backward compatible this number gets incremented. */ 42 | #define DDB_VERSION 1 43 | 44 | #define DDB_LENERR UINT_MAX 45 | 46 | #define DDB_TYPE_COUNTER 0 47 | 48 | /* Special DDB opcodes (saved/loaded with ddbSaveType/ddbLoadType). */ 49 | #define DDB_OPCODE_RESIZEDB 251 50 | #define DDB_OPCODE_EOF 255 51 | 52 | int ddbLoad(char *filename); 53 | int ddbSaveBackground(char *filename); 54 | void ddbRemoveTempFile(pid_t childpid); 55 | int ddbSave(char *filename); 56 | void backgroundSaveDoneHandler(int exitcode, int bysignal); 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /src/discntassert.h: -------------------------------------------------------------------------------- 1 | /* discntassert.h -- Drop in replacemnet assert.h that prints the stack trace 2 | * in the Discnt logs. 3 | * 4 | * This file should be included instead of "assert.h" inside libraries used by 5 | * Discnt that are using assertions, so instead of Discnt disappearing with 6 | * SIGABORT, we get the details and stack trace inside the log file. 7 | * 8 | * ---------------------------------------------------------------------------- 9 | * 10 | * Copyright (c) 2006-2012, Salvatore Sanfilippo 11 | * All rights reserved. 12 | * 13 | * Redistribution and use in source and binary forms, with or without 14 | * modification, are permitted provided that the following conditions are met: 15 | * 16 | * * Redistributions of source code must retain the above copyright notice, 17 | * this list of conditions and the following disclaimer. 18 | * * Redistributions in binary form must reproduce the above copyright 19 | * notice, this list of conditions and the following disclaimer in the 20 | * documentation and/or other materials provided with the distribution. 21 | * * Neither the name of Discnt nor the names of its contributors may be used 22 | * to endorse or promote products derived from this software without 23 | * specific prior written permission. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 26 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 29 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 | * POSSIBILITY OF SUCH DAMAGE. 36 | */ 37 | 38 | #ifndef __DISCNT_ASSERT_H__ 39 | #define __DISCNT_ASSERT_H__ 40 | 41 | #include /* for _exit() */ 42 | 43 | #define assert(_e) ((_e)?(void)0 : (_serverAssert(#_e,__FILE__,__LINE__),_exit(1))) 44 | 45 | void _serverAssert(char *estr, char *file, int line); 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /src/endianconv.h: -------------------------------------------------------------------------------- 1 | /* See endianconv.c top comments for more information 2 | * 3 | * ---------------------------------------------------------------------------- 4 | * 5 | * Copyright (c) 2014-2015, Erik Dubbelboer 6 | * Copyright (c) 2011-2012, Salvatore Sanfilippo 7 | * All rights reserved. 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions are met: 11 | * 12 | * * Redistributions of source code must retain the above copyright notice, 13 | * this list of conditions and the following disclaimer. 14 | * * Redistributions in binary form must reproduce the above copyright 15 | * notice, this list of conditions and the following disclaimer in the 16 | * documentation and/or other materials provided with the distribution. 17 | * * Neither the name of Discnt nor the names of its contributors may be used 18 | * to endorse or promote products derived from this software without 19 | * specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 25 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | * POSSIBILITY OF SUCH DAMAGE. 32 | */ 33 | 34 | #ifndef __ENDIANCONV_H 35 | #define __ENDIANCONV_H 36 | 37 | #include "config.h" 38 | #include 39 | 40 | void memrev16(void *p); 41 | void memrev32(void *p); 42 | void memrev64(void *p); 43 | uint16_t intrev16(uint16_t v); 44 | uint32_t intrev32(uint32_t v); 45 | uint64_t intrev64(uint64_t v); 46 | 47 | /* variants of the function doing the actual convertion only if the target 48 | * host is big endian */ 49 | #if (BYTE_ORDER == LITTLE_ENDIAN) 50 | #define memrev16ifbe(p) 51 | #define memrev32ifbe(p) 52 | #define memrev64ifbe(p) 53 | #define intrev16ifbe(v) (v) 54 | #define intrev32ifbe(v) (v) 55 | #define intrev64ifbe(v) (v) 56 | #else 57 | #define memrev16ifbe(p) memrev16(p) 58 | #define memrev32ifbe(p) memrev32(p) 59 | #define memrev64ifbe(p) memrev64(p) 60 | #define intrev16ifbe(v) intrev16(v) 61 | #define intrev32ifbe(v) intrev32(v) 62 | #define intrev64ifbe(v) intrev64(v) 63 | #endif 64 | 65 | /* The functions htonu64() and ntohu64() convert the specified value to 66 | * network byte ordering and back. In big endian systems they are no-ops. */ 67 | #if (BYTE_ORDER == BIG_ENDIAN) 68 | #define htonu64(v) (v) 69 | #define ntohu64(v) (v) 70 | #else 71 | #define htonu64(v) intrev64(v) 72 | #define ntohu64(v) intrev64(v) 73 | #endif 74 | 75 | uint64_t pack754(long double f, unsigned bits, unsigned expbits); 76 | long double unpack754(uint64_t i, unsigned bits, unsigned expbits); 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /src/fmacros.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2012, 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 Discnt 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 _DISCNT_FMACRO_H 31 | #define _DISCNT_FMACRO_H 32 | 33 | #define _BSD_SOURCE 34 | 35 | #if defined(__linux__) 36 | #define _GNU_SOURCE 37 | #define _DEFAULT_SOURCE 38 | #endif 39 | 40 | #if defined(_AIX) 41 | #define _ALL_SOURCE 42 | #endif 43 | 44 | #if defined(__linux__) || defined(__OpenBSD__) 45 | #define _XOPEN_SOURCE 700 46 | /* 47 | * On NetBSD, _XOPEN_SOURCE undefines _NETBSD_SOURCE and 48 | * thus hides inet_aton etc. 49 | */ 50 | #elif !defined(__NetBSD__) 51 | #define _XOPEN_SOURCE 52 | #endif 53 | 54 | #if defined(__sun) 55 | #define _POSIX_C_SOURCE 199506L 56 | #endif 57 | 58 | #define _LARGEFILE_SOURCE 59 | #define _FILE_OFFSET_BITS 64 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /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 --no-ext-diff 2> /dev/null | wc -l` 4 | BUILD_ID=`uname -n`"-"`date +%s` 5 | test -f release.h || touch release.h 6 | (cat release.h | grep SHA1 | grep $GIT_SHA1) && \ 7 | (cat release.h | grep DIRTY | grep $GIT_DIRTY) && exit 0 # Already up-to-date 8 | echo "#define DISCNT_GIT_SHA1 \"$GIT_SHA1\"" > release.h 9 | echo "#define DISCNT_GIT_DIRTY \"$GIT_DIRTY\"" >> release.h 10 | echo "#define DISCNT_BUILD_ID \"$BUILD_ID\"" >> release.h 11 | touch release.c # Force recompile of release.c 12 | -------------------------------------------------------------------------------- /src/release.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2012, 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 Discnt 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 | /* Every time the Discnt Git SHA1 or Dirty status changes only this small 31 | * file is recompiled, as we access this information in all the other 32 | * files using this functions. */ 33 | 34 | #include 35 | 36 | #include "release.h" 37 | #include "version.h" 38 | #include "crc64.h" 39 | 40 | char *discntGitSHA1(void) { 41 | return DISCNT_GIT_SHA1; 42 | } 43 | 44 | char *discntGitDirty(void) { 45 | return DISCNT_GIT_DIRTY; 46 | } 47 | 48 | uint64_t discntBuildId(void) { 49 | char *buildid = DISCNT_VERSION DISCNT_BUILD_ID DISCNT_GIT_DIRTY DISCNT_GIT_SHA1; 50 | 51 | return crc64(0,(unsigned char*)buildid,strlen(buildid)); 52 | } 53 | -------------------------------------------------------------------------------- /src/sdsalloc.h: -------------------------------------------------------------------------------- 1 | /* SDSLib 2.0 -- A C dynamic strings library 2 | * 3 | * Copyright (c) 2006-2015, Salvatore Sanfilippo 4 | * Copyright (c) 2015, Redis Labs, Inc 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions are met: 9 | * 10 | * * Redistributions of source code must retain the above copyright notice, 11 | * this list of conditions and the following disclaimer. 12 | * * Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * * Neither the name of Redis nor the names of its contributors may be used 16 | * to endorse or promote products derived from this software without 17 | * specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 | * POSSIBILITY OF SUCH DAMAGE. 30 | */ 31 | 32 | /* SDS allocator selection. 33 | * 34 | * This file is used in order to change the SDS allocator at compile time. 35 | * Just define the following defines to what you want to use. Also add 36 | * the include of your alternate allocator if needed (not needed in order 37 | * to use the default libc allocator). */ 38 | 39 | #include "zmalloc.h" 40 | #define s_malloc zmalloc 41 | #define s_realloc zrealloc 42 | #define s_free zfree 43 | -------------------------------------------------------------------------------- /src/sha1.h: -------------------------------------------------------------------------------- 1 | /* ================ sha1.h ================ */ 2 | /* 3 | SHA-1 in C 4 | By Steve Reid 5 | 100% Public Domain 6 | */ 7 | 8 | typedef struct { 9 | uint32_t state[5]; 10 | uint32_t count[2]; 11 | unsigned char buffer[64]; 12 | } SHA1_CTX; 13 | 14 | void SHA1Transform(uint32_t state[5], const unsigned char buffer[64]); 15 | void SHA1Init(SHA1_CTX* context); 16 | void SHA1Update(SHA1_CTX* context, const unsigned char* data, uint32_t len); 17 | void SHA1Final(unsigned char digest[20], SHA1_CTX* context); 18 | -------------------------------------------------------------------------------- /src/solarisfixes.h: -------------------------------------------------------------------------------- 1 | /* Solaris specific fixes. 2 | * 3 | * Copyright (c) 2009-2012, 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 Discnt 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 | #if defined(__sun) 32 | 33 | #if defined(__GNUC__) 34 | #include 35 | #undef isnan 36 | #define isnan(x) \ 37 | __extension__({ __typeof (x) __x_a = (x); \ 38 | __builtin_expect(__x_a != __x_a, 0); }) 39 | 40 | #undef isfinite 41 | #define isfinite(x) \ 42 | __extension__ ({ __typeof (x) __x_f = (x); \ 43 | __builtin_expect(!isnan(__x_f - __x_f), 1); }) 44 | 45 | #undef isinf 46 | #define isinf(x) \ 47 | __extension__ ({ __typeof (x) __x_i = (x); \ 48 | __builtin_expect(!isnan(__x_i) && !isfinite(__x_i), 0); }) 49 | 50 | #define u_int uint 51 | #define u_int32_t uint32_t 52 | #endif /* __GNUC__ */ 53 | 54 | #endif /* __sun */ 55 | -------------------------------------------------------------------------------- /src/sparkline.h: -------------------------------------------------------------------------------- 1 | /* sparkline.h -- ASCII Sparklines header file 2 | * 3 | * --------------------------------------------------------------------------- 4 | * 5 | * Copyright(C) 2011-2014 Salvatore Sanfilippo 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 | * 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 __SPARKLINE_H 31 | #define __SPARKLINE_H 32 | 33 | /* A sequence is represented of many "samples" */ 34 | struct sample { 35 | double value; 36 | char *label; 37 | }; 38 | 39 | struct sequence { 40 | int length; 41 | int labels; 42 | struct sample *samples; 43 | double min, max; 44 | }; 45 | 46 | #define SPARKLINE_NO_FLAGS 0 47 | #define SPARKLINE_FILL 1 /* Fill the area under the curve. */ 48 | #define SPARKLINE_LOG_SCALE 2 /* Use logarithmic scale. */ 49 | 50 | struct sequence *createSparklineSequence(void); 51 | void sparklineSequenceAddSample(struct sequence *seq, double value, char *label); 52 | void freeSparklineSequence(struct sequence *seq); 53 | sds sparklineRenderRange(sds output, struct sequence *seq, int rows, int offset, int len, int flags); 54 | sds sparklineRender(sds output, struct sequence *seq, int columns, int rows, int flags); 55 | 56 | #endif /* __SPARKLINE_H */ 57 | -------------------------------------------------------------------------------- /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 | * ---------------------------------------------------------------------------- 10 | * 11 | * Copyright (c) 2010-2012, Salvatore Sanfilippo 12 | * All rights reserved. 13 | * 14 | * Redistribution and use in source and binary forms, with or without 15 | * modification, are permitted provided that the following conditions are met: 16 | * 17 | * * Redistributions of source code must retain the above copyright notice, 18 | * this list of conditions and the following disclaimer. 19 | * * Redistributions in binary form must reproduce the above copyright 20 | * notice, this list of conditions and the following disclaimer in the 21 | * documentation and/or other materials provided with the distribution. 22 | * * Neither the name of Discnt nor the names of its contributors may be used 23 | * to endorse or promote products derived from this software without 24 | * specific prior written permission. 25 | * 26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 27 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 30 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 | * POSSIBILITY OF SUCH DAMAGE. 37 | */ 38 | 39 | #ifndef __TESTHELP_H 40 | #define __TESTHELP_H 41 | 42 | int __failed_tests = 0; 43 | int __test_num = 0; 44 | #define test_cond(descr,_c) do { \ 45 | __test_num++; printf("%d - %s: ", __test_num, descr); \ 46 | if(_c) printf("PASSED\n"); else {printf("FAILED\n"); __failed_tests++;} \ 47 | } while(0); 48 | #define test_report() do { \ 49 | printf("%d tests, %d passed, %d failed\n", __test_num, \ 50 | __test_num-__failed_tests, __failed_tests); \ 51 | if (__failed_tests) { \ 52 | printf("=== WARNING === We have failed tests here...\n"); \ 53 | exit(1); \ 54 | } \ 55 | } while(0); 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /src/util.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009-2012, 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 Disque 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 __DISQUE_UTIL_H 31 | #define __DISQUE_UTIL_H 32 | 33 | #include 34 | #include "sds.h" 35 | 36 | int stringmatchlen(const char *p, int plen, const char *s, int slen, int nocase); 37 | int stringmatch(const char *p, const char *s, int nocase); 38 | long long memtoll(const char *p, int *err); 39 | uint32_t digits10(uint64_t v); 40 | uint32_t sdigits10(int64_t v); 41 | int ll2string(char *s, size_t len, long long value); 42 | int string2ll(const char *s, size_t slen, long long *value); 43 | int string2l(const char *s, size_t slen, long *value); 44 | int d2string(char *buf, size_t len, double value); 45 | sds getAbsolutePath(char *filename); 46 | int pathIsBaseName(char *path); 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /src/valgrind.sup: -------------------------------------------------------------------------------- 1 | { 2 | 3 | Memcheck:Cond 4 | fun:lzf_compress 5 | } 6 | 7 | { 8 | 9 | Memcheck:Value4 10 | fun:lzf_compress 11 | } 12 | 13 | { 14 | 15 | Memcheck:Value8 16 | fun:lzf_compress 17 | } 18 | -------------------------------------------------------------------------------- /src/version.h: -------------------------------------------------------------------------------- 1 | #define DISCNT_VERSION "1.1.0" 2 | -------------------------------------------------------------------------------- /tests/assets/default.conf: -------------------------------------------------------------------------------- 1 | # Discnt configuration for testing. 2 | 3 | daemonize no 4 | pidfile /var/run/discnt.pid 5 | port 5262 6 | timeout 0 7 | bind 127.0.0.1 8 | loglevel verbose 9 | logfile '' 10 | latency-monitor-threshold 1 11 | 12 | save 900 1 13 | save 300 10 14 | save 60 10000 15 | 16 | ddbchecksum yes 17 | dbfilename dump.ddb 18 | dir ./ 19 | 20 | activerehashing yes 21 | -------------------------------------------------------------------------------- /tests/cluster/cluster.tcl: -------------------------------------------------------------------------------- 1 | # Cluster-specific test functions. 2 | # 3 | # Copyright (C) 2014 Salvatore Sanfilippo antirez@gmail.com 4 | # This software is released under the BSD License. See the COPYING file for 5 | # more information. 6 | 7 | # Returns a parsed CLUSTER NODES output as a list of dictionaries. 8 | proc get_cluster_nodes id { 9 | set lines [split [D $id cluster nodes] "\r\n"] 10 | set nodes {} 11 | foreach l $lines { 12 | set l [string trim $l] 13 | if {$l eq {}} continue 14 | set args [split $l] 15 | set node [dict create \ 16 | id [lindex $args 0] \ 17 | addr [lindex $args 1] \ 18 | flags [split [lindex $args 2] ,] \ 19 | ping_sent [lindex $args 3] \ 20 | pong_recv [lindex $args 4] \ 21 | linkstate [lindex $args 5] 22 | ] 23 | lappend nodes $node 24 | } 25 | return $nodes 26 | } 27 | 28 | # Test node for flag. 29 | proc has_flag {node flag} { 30 | expr {[lsearch -exact [dict get $node flags] $flag] != -1} 31 | } 32 | 33 | # Return the number of instances having the specified flag set from the 34 | # POV of the instance 'id'. 35 | proc count_cluster_nodes_with_flag {id flag} { 36 | set count 0 37 | foreach node [get_cluster_nodes $id] { 38 | if {[has_flag $node $flag]} {incr count} 39 | } 40 | return $count 41 | } 42 | 43 | # Returns the parsed myself node entry as a dictionary. 44 | proc get_myself id { 45 | set nodes [get_cluster_nodes $id] 46 | foreach n $nodes { 47 | if {[has_flag $n myself]} {return $n} 48 | } 49 | return {} 50 | } 51 | 52 | # Return the value of the specified CLUSTER INFO field. 53 | proc CI {n field} { 54 | get_info_field [D $n cluster info] $field 55 | } 56 | 57 | # Set the cluster node-timeout to all the reachalbe nodes. 58 | proc set_cluster_node_timeout {to} { 59 | foreach_discnt_id id { 60 | catch {D $id CONFIG SET cluster-node-timeout $to} 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /tests/cluster/run.tcl: -------------------------------------------------------------------------------- 1 | # Cluster test suite. Copyright (C) 2014 Salvatore Sanfilippo antirez@gmail.com 2 | # This software is released under the BSD License. See the COPYING file for 3 | # more information. 4 | 5 | cd tests/cluster 6 | source cluster.tcl 7 | source ../instances.tcl 8 | source ../../support/cluster.tcl ; # Redis Cluster client. 9 | 10 | set ::instances_count 7; # How many instances we use at max. 11 | 12 | proc main {} { 13 | parse_options 14 | spawn_instance discnt $::discnt_base_port $::instances_count { 15 | "loglevel notice" 16 | } 17 | run_tests 18 | cleanup 19 | } 20 | 21 | if {[catch main e]} { 22 | puts $::errorInfo 23 | if {$::pause_on_error} pause_on_error 24 | cleanup 25 | exit 1 26 | } 27 | -------------------------------------------------------------------------------- /tests/cluster/tests/00-base.tcl: -------------------------------------------------------------------------------- 1 | source "../tests/includes/init-tests.tcl" 2 | 3 | if {$::simulate_error} { 4 | test "This test will fail" { 5 | fail "Simulated error" 6 | } 7 | } 8 | 9 | test "Different nodes have different IDs" { 10 | set ids {} 11 | set numnodes 0 12 | foreach_discnt_id id { 13 | incr numnodes 14 | # Every node should just know itself. 15 | set nodeid [dict get [get_myself $id] id] 16 | assert {$nodeid ne {}} 17 | lappend ids $nodeid 18 | } 19 | set numids [llength [lsort -unique $ids]] 20 | assert {$numids == $numnodes} 21 | } 22 | -------------------------------------------------------------------------------- /tests/cluster/tests/01-faildet.tcl: -------------------------------------------------------------------------------- 1 | source "../tests/includes/init-tests.tcl" 2 | 3 | test "Killing two nodes" { 4 | kill_instance discnt 5 5 | kill_instance discnt 6 6 | } 7 | 8 | test "Nodes should be flagged with the FAIL flag" { 9 | wait_for_condition { 10 | [count_cluster_nodes_with_flag 0 fail] == 2 11 | } else { 12 | fail "Killed nodes not flagged with FAIL flag after some time" 13 | } 14 | } 15 | 16 | test "Restarting two nodes" { 17 | restart_instance discnt 5 18 | restart_instance discnt 6 19 | } 20 | 21 | test "Nodes FAIL flag should be cleared" { 22 | wait_for_condition { 23 | [count_cluster_nodes_with_flag 0 fail] == 0 24 | } else { 25 | fail "Restarted nodes FAIL flag not cleared after some time" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tests/cluster/tests/02-sync.tcl: -------------------------------------------------------------------------------- 1 | source "../tests/includes/init-tests.tcl" 2 | 3 | test "INCR should propagate" { 4 | D 0 incrby test1 2 5 | D 0 set test2 2 6 | 7 | # Wait for one sync round. 8 | after 1100 9 | 10 | set v [D 1 get test1] 11 | assert {$v <= 4} 12 | assert {$v >= 2} 13 | 14 | set v [D 1 get test2] 15 | assert {$v == 2} 16 | } 17 | 18 | test "DECR should propagate" { 19 | D 0 decrby test1 4.0 20 | D 0 set test2 1 21 | 22 | # Wait for one sync round. 23 | after 1100 24 | 25 | set v [D 1 get test1] 26 | assert {$v <= 0} 27 | assert {$v >= -3} 28 | 29 | set v [D 1 get test2] 30 | assert {$v == 1} 31 | } 32 | 33 | -------------------------------------------------------------------------------- /tests/cluster/tests/03-state.tcl: -------------------------------------------------------------------------------- 1 | source "../tests/includes/init-tests.tcl" 2 | 3 | test "Killing a node" { 4 | D 1 set test 1 5 | 6 | kill_instance discnt 2 7 | 8 | wait_for_condition { 9 | [count_cluster_nodes_with_flag 0 fail] == 1 10 | } else { 11 | fail "Killed nodes not flagged with FAIL flag after some time" 12 | } 13 | 14 | # State is updated every 100ms so wait a bit. 15 | after 200 16 | } 17 | 18 | test "State should be inconsistent" { 19 | set v [D 1 get test state] 20 | assert {$v == "1 INCONSISTENT"} 21 | 22 | set v [D 1 get nonexistent state] 23 | assert {$v == "0 INCONSISTENT"} 24 | } 25 | 26 | test "Restarting node" { 27 | restart_instance discnt 2 28 | 29 | wait_for_condition { 30 | [count_cluster_nodes_with_flag 0 fail] == 0 31 | } else { 32 | fail "Restarted nodes FAIL flag not cleared after some time" 33 | } 34 | 35 | # State is updated every 100ms so wait a bit. 36 | after 200 37 | } 38 | 39 | test "State should be consistent" { 40 | set v [D 1 get test state] 41 | assert {$v == "1 CONSISTENT"} 42 | 43 | set v [D 1 get nonexistent state] 44 | assert {$v == "0 CONSISTENT"} 45 | } 46 | -------------------------------------------------------------------------------- /tests/cluster/tests/04-ack.tcl: -------------------------------------------------------------------------------- 1 | source "../tests/includes/init-tests.tcl" 2 | 3 | test "Killing a node" { 4 | kill_instance discnt 2 5 | } 6 | 7 | test "Predictions will not ack" { 8 | wait_for_condition { 9 | [count_cluster_nodes_with_flag 0 fail] == 1 10 | } else { 11 | fail "Killed nodes not flagged with FAIL flag after some time" 12 | } 13 | 14 | D 1 incr test1 15 | D 1 set test2 2 16 | } 17 | 18 | test "Restarting node" { 19 | restart_instance discnt 2 20 | } 21 | 22 | test "Prediction should be resend" { 23 | wait_for_condition { 24 | [count_cluster_nodes_with_flag 0 fail] == 0 25 | } else { 26 | fail "Restarted nodes FAIL flag not cleared after some time" 27 | } 28 | 29 | # If we don't receive an ack for a prediction we wait 30 | # 5 seconds before we send it again. So wait at last this time. 31 | after 6100 32 | 33 | set v [D 2 get test1] 34 | assert {$v <= 4} 35 | assert {$v >= 1} 36 | 37 | set v [D 2 get test2] 38 | assert {$v == 2} 39 | } 40 | -------------------------------------------------------------------------------- /tests/cluster/tests/05-history.tcl: -------------------------------------------------------------------------------- 1 | source "../tests/includes/init-tests.tcl" 2 | 3 | test "Big counters should be accurate after a full history" { 4 | D 1 incrby big 10 5 | D 2 incrby big 20 6 | 7 | # Wait for a full history + one sync + 1 second tolerance. 8 | after 6000 9 | 10 | set v [expr {round([D 3 debug prediction big])}] 11 | assert {$v == 0} 12 | 13 | # After a full history of no change the counter 14 | # should exactly match. 15 | set v [D 3 get big] 16 | assert {$v == 30} 17 | } 18 | 19 | test "Small counters should be accurate after a while" { 20 | D 1 incrby small 0.8 21 | 22 | # It takes 1/(0.8/4)= 5 seconds before the counter's prediction 23 | # will be 1 off from the actual value. 24 | # Add 2 extra seconds of tolarance for the prediction updates 25 | # and syncs. 26 | after 7000 27 | 28 | set v [expr {round([D 3 debug prediction small])}] 29 | assert {$v == 0} 30 | 31 | # After a full history of no change the counter 32 | # should exactly match because the difference between 33 | # 1 and 0 is equal to what we allow as change. 34 | set v [expr {double(round([D 3 get small]*10))/10}] 35 | assert {$v == 0.8} 36 | } 37 | 38 | test "Test for issue #1" { 39 | D 1 incrby issue1 0.0001 40 | after 5100 41 | set v [expr {double(round([D 2 get issue1]*10000))}] 42 | assert {$v == 1.0} 43 | D 1 incrby issue1 0.0001 44 | after 5100 45 | set v [expr {double(round([D 2 get issue1]*10000))}] 46 | assert {$v == 2.0} 47 | } 48 | 49 | -------------------------------------------------------------------------------- /tests/cluster/tests/06-reset.tcl: -------------------------------------------------------------------------------- 1 | source "../tests/includes/init-tests.tcl" 2 | 3 | test "Reset should reset" { 4 | D 1 set test 1 5 | D 2 incrby test 10 6 | 7 | after 5000 8 | 9 | D 3 debug reset 10 | 11 | after 1000 12 | 13 | for {set i 0} {$i < $::instances_count} {incr i} { 14 | set v [D $i keys *] 15 | assert {$v == {}} 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tests/cluster/tests/07-unused.tcl: -------------------------------------------------------------------------------- 1 | source "../tests/includes/init-tests.tcl" 2 | 3 | test "0 counters should be deleted" { 4 | D 0 incrby test1 1 5 | D 0 set test1 0 6 | 7 | # Wait for one sync+delete round. 8 | after 4100 9 | 10 | for {set i 0} {$i < $::instances_count} {incr i} { 11 | set v [D $i exists test1] 12 | assert {$v == 0} 13 | set v [D $i get test1 state] 14 | assert {$v == "0 CONSISTENT"} 15 | } 16 | } 17 | 18 | test "0 shards should be deleted" { 19 | D 0 set test2 1 20 | # Wait for one sync round. 21 | after 1100 22 | D 1 set test2 0 23 | # Wait for one sync round. 24 | after 1100 25 | D 2 set test2 1 26 | # Wait for one sync round. 27 | after 1100 28 | 29 | # 0 = 1 30 | # 1 = -1 31 | # 2 = 1 32 | # so the counter value = 1 33 | 34 | set v [D 1 debug counter test2] 35 | assert {[llength [lindex $v 0]] == 3} 36 | 37 | D 0 set test2 0 38 | 39 | # Wait for one sync+delete round. 40 | after 5100 41 | 42 | for {set i 0} {$i < $::instances_count} {incr i} { 43 | set v [D $i debug counter test2] 44 | assert {[llength [lindex $v 0]] == 2} 45 | } 46 | } 47 | 48 | test "delete with subscribers" { 49 | D 0 set test3 1 50 | 51 | D 1 deferred 1 52 | D 1 subscribe test3 53 | D 1 read; # Read the subscribe reply 54 | 55 | # Wait for one sync round. 56 | after 1100 57 | 58 | D 0 set test3 0 59 | 60 | # Wait for one sync+delete round. 61 | after 4100 62 | 63 | set v0 [D 0 exists test3] 64 | assert {$v0 == 0} 65 | 66 | D 1 read; # Read the change to 1 67 | D 1 read; # Read the change to 0 68 | 69 | D 1 unsubscribe test3 70 | D 1 read; # Read the unsubscribe reply 71 | D 1 deferred 0 72 | set v1 [D 1 exists test3] 73 | assert {$v1 == 1} 74 | } 75 | -------------------------------------------------------------------------------- /tests/cluster/tests/98-random.tcl: -------------------------------------------------------------------------------- 1 | source "../tests/includes/init-tests.tcl" 2 | 3 | test "Random for 10 minutes" { 4 | if {false} { 5 | for {set i 0} {$i < [expr {(10*60*1000)/10}]} {incr i} { 6 | after 10 7 | set n [expr {int(rand()*$::instances_count)}] 8 | set k [format "test:%d" [expr {int(rand()*100)}]] 9 | set v [expr {0.5 - rand()}] 10 | if {rand() < 0.1} { 11 | if {rand() < 0.1} { 12 | D $n set $k 0 13 | } else { 14 | D $n set $k $v 15 | } 16 | } else { 17 | D $n incrby $k $v 18 | } 19 | } 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /tests/cluster/tests/99-oneminute.tcl: -------------------------------------------------------------------------------- 1 | source "../tests/includes/init-tests.tcl" 2 | 3 | test "Increment for 1 minute" { 4 | # 10 seconds 5 | for {set i 0} {$i < 100} {incr i} { 6 | after 100 7 | D 0 incrby test0 0.01 8 | D 1 incrby test1 0.1 9 | D 2 incrby test2 1.0 10 | D 3 incrby test3 0.8 11 | D 4 incrby test3 1.0 12 | D 5 incrby test3 -1.2 13 | } 14 | 15 | kill_instance discnt 6 16 | 17 | # 20 seconds 18 | for {set i 0} {$i < 200} {incr i} { 19 | after 100 20 | D 0 incrby test0 0.01 21 | D 1 incrby test1 0.1 22 | D 2 incrby test2 1.0 23 | D 3 incrby test3 0.8 24 | D 4 incrby test3 1.0 25 | D 5 incrby test3 -1.2 26 | } 27 | 28 | restart_instance discnt 6 29 | 30 | # 30 seconds 31 | for {set i 0} {$i < 300} {incr i} { 32 | after 100 33 | D 0 incrby test0 0.01 34 | D 1 incrby test1 0.1 35 | D 2 incrby test2 1.0 36 | D 3 incrby test3 0.8 37 | D 4 incrby test3 1.0 38 | D 5 incrby test3 -1.2 39 | } 40 | } 41 | 42 | test "Accurate counters" { 43 | set v [expr {round([D 0 get test0])}] 44 | assert {$v == 6} ; # 6 = 600 * 0.01 45 | 46 | set v [expr {round([D 1 get test1])}] 47 | assert {$v == 60} 48 | 49 | set v [expr {round([D 2 get test2])}] 50 | assert {$v == 600} 51 | } 52 | 53 | test "Waiting for history" { 54 | # It takes 1/(0.8/4)= 5 seconds before test3 on instance 3's 55 | # prediction will be 1 off from the actual value. 56 | # Add 2 extra seconds of tolarance for the prediction updates 57 | # and syncs. 58 | after 7000 59 | } 60 | 61 | for {set i 0} {$i < $::instances_count} {incr i} { 62 | test "Counters on insance $i" { 63 | set v [expr {round([D $i get test0])}] 64 | # Use a tolerance of 1 instead of the actual really low value. 65 | # If we have to wait for a counter with this low increment to 66 | # be accurate we have to wait a long time. 67 | assert {$v >= 5} ; # 5 = 600*0.01 - 1 68 | assert {$v <= 7} ; # 7 = 600*0.01 + 1 69 | 70 | set v [expr {round([D $i get test1])}] 71 | assert {$v >= 59} 72 | assert {$v <= 71} 73 | 74 | set v [expr {round([D $i get test2])}] 75 | assert {$v >= 590} 76 | assert {$v <= 710} 77 | 78 | set v [expr {round([D $i get test3])}] 79 | assert {$v >= 357} ; # 357 = 600*(0.8+1.0-1.2) + -1-1-1 80 | assert {$v <= 363} ; # 363 = 600*(0.1+0.2-0.01) + 1+1+1 81 | } 82 | } 83 | 84 | for {set i 0} {$i < $::instances_count} {incr i} { 85 | test "Instance $i \[Hits, Misses\]" { 86 | set h [DI $i hits] 87 | set m [DI $i misses] 88 | puts -nonewline "\[$h, $m\] " 89 | } 90 | } 91 | 92 | -------------------------------------------------------------------------------- /tests/cluster/tests/includes/init-tests.tcl: -------------------------------------------------------------------------------- 1 | # Initialization tests -- most units will start including this. 2 | 3 | test "(init) Restart killed instances" { 4 | foreach type {discnt} { 5 | foreach_${type}_id id { 6 | if {[get_instance_attrib $type $id pid] == -1} { 7 | puts -nonewline "$type/$id " 8 | flush stdout 9 | restart_instance $type $id 10 | } 11 | } 12 | } 13 | } 14 | 15 | test "Cluster nodes are reachable" { 16 | foreach_discnt_id id { 17 | # Every node should be reachable. 18 | wait_for_condition { 19 | ([catch {D $id ping} ping_reply] == 0) && 20 | ($ping_reply eq {PONG}) 21 | } else { 22 | catch {D $id ping} err 23 | fail "Node #$id keeps replying '$err' to PING." 24 | } 25 | } 26 | } 27 | 28 | test "Cluster nodes hard reset" { 29 | foreach_discnt_id id { 30 | D $id cluster reset hard 31 | D $id config set cluster-node-timeout 2000 32 | D $id config rewrite 33 | } 34 | } 35 | 36 | test "Cluster Join and auto-discovery test" { 37 | # Join node 0 with 1, 1 with 2, ... and so forth. 38 | # If auto-discovery works all nodes will know every other node 39 | # eventually. 40 | set ids {} 41 | foreach_discnt_id id {lappend ids $id} 42 | for {set j 0} {$j < [expr [llength $ids]-1]} {incr j} { 43 | set a [lindex $ids $j] 44 | set b [lindex $ids [expr $j+1]] 45 | set b_port [get_instance_attrib discnt $b port] 46 | D $a cluster meet 127.0.0.1 $b_port 47 | } 48 | 49 | foreach_discnt_id id { 50 | wait_for_condition { 51 | [CI $id cluster_reachable_nodes]+1 == [llength $ids] 52 | } else { 53 | fail "Cluster failed to join into a full mesh." 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /tests/cluster/tmp/.gitignore: -------------------------------------------------------------------------------- 1 | discnt_* 2 | -------------------------------------------------------------------------------- /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 incr foo} err 16 | set _ $err 17 | } {NOAUTH*} 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 incrby foo 100 25 | r incr foo 26 | } {101} 27 | } 28 | -------------------------------------------------------------------------------- /tests/unit/counters.tcl: -------------------------------------------------------------------------------- 1 | start_server {tags {"counters"}} { 2 | test {INCR a counter} { 3 | r incr test 4 | r incrby test 2 5 | } {3} 6 | 7 | test {GET a counter} { 8 | r get test 9 | } {3} 10 | 11 | test {GET with STATE} { 12 | r get test state 13 | } {3 CONSISTENT} 14 | 15 | test {GET on non existent counter should return 0} { 16 | r get doesnotexist 17 | } {0} 18 | 19 | test {MGET} { 20 | r incr test2 21 | r mget test doesnotexist test2 22 | } {3 0 1} 23 | 24 | test {KEYS should return all counters} { 25 | lsort [r keys *] 26 | } {test test2} 27 | 28 | test {PRECISION on none existing counter} { 29 | r precision nonexisting 30 | } {1} 31 | 32 | test {PRECISION} { 33 | r precision test 2.2 34 | set _ [expr {round([r precision test] * 10)}] 35 | } {22} 36 | 37 | test {CONFIG SET default-precision} { 38 | r config set default-precision 0.1 39 | set _ [expr {round([r precision test3] * 10)}] 40 | } {1} 41 | 42 | test {SET} { 43 | r set test 1 44 | } {1} 45 | 46 | test {GET after SET} { 47 | r get test 48 | } {1} 49 | 50 | # The following test can only be executed if we don't use Valgrind, and if 51 | # we are using x86_64 architecture, because: 52 | # 53 | # 1) Valgrind has floating point limitations, no support for 80 bits math. 54 | # 2) Other archs may have the same limits. 55 | # 56 | # 1.23 cannot be represented correctly with 64 bit doubles, so we skip 57 | # the test, since we are only testing pretty printing here and is not 58 | # a bug if the program outputs things like 1.299999... 59 | if {!$::valgrind || ![string match *x86_64* [exec uname -a]]} { 60 | test {Test counters for correct float representation} { 61 | assert {[r incrbyfloat test3 1.23] eq {1.23}} 62 | assert {[r incrbyfloat test3 0.77] eq {2}} 63 | assert {[r incrbyfloat test3 -0.1] eq {1.9}} 64 | } 65 | } 66 | 67 | test {EXISTS} { 68 | r exists test test2 69 | } {2} 70 | 71 | test {MINCRBY counters} { 72 | r set test4 1 73 | r mincrby 1 test4 test5 test6 74 | } {2 1 1} 75 | } 76 | -------------------------------------------------------------------------------- /tests/unit/introspection.tcl: -------------------------------------------------------------------------------- 1 | start_server {tags {"introspection"}} { 2 | test {CLIENT LIST} { 3 | r client list 4 | } {id=* addr=*:* fd=* name=* age=* idle=* flags=N sub=0 qbuf=0 qbuf-free=* obl=0 oll=0 omem=0 events=r cmd=client*} 5 | 6 | test {MONITOR can log executed commands} { 7 | set rd [redis_deferring_client] 8 | $rd monitor 9 | assert_match {*OK*} [$rd read] 10 | r set foo 1 11 | r get foo 12 | list [$rd read] [$rd read] 13 | } {*"set" "foo"*"get" "foo"*} 14 | 15 | test {CLIENT GETNAME should return NIL if name is not assigned} { 16 | r client getname 17 | } {} 18 | 19 | test {CLIENT LIST shows empty fields for unassigned names} { 20 | r client list 21 | } {*name= *} 22 | 23 | test {CLIENT SETNAME does not accept spaces} { 24 | catch {r client setname "foo bar"} e 25 | set e 26 | } {ERR*} 27 | 28 | test {CLIENT SETNAME can assign a name to this connection} { 29 | assert_equal [r client setname myname] {OK} 30 | r client list 31 | } {*name=myname*} 32 | 33 | test {CLIENT SETNAME can change the name of an existing connection} { 34 | assert_equal [r client setname someothername] {OK} 35 | r client list 36 | } {*name=someothername*} 37 | 38 | test {After CLIENT SETNAME, connection can still be closed} { 39 | set rd [redis_deferring_client] 40 | $rd client setname foobar 41 | assert_equal [$rd read] "OK" 42 | assert_match {*foobar*} [r client list] 43 | $rd close 44 | # Now the client should no longer be listed 45 | wait_for_condition { 46 | [string match {*foobar*} [r client list]] == 0 47 | } else { 48 | fail "Client still listed in CLIENT LIST after SETNAME." 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /tests/unit/latency-monitor.tcl: -------------------------------------------------------------------------------- 1 | start_server {tags {"latency-monitor"}} { 2 | # Set a threshold high enough to avoid spurious latency events. 3 | r config set latency-monitor-threshold 200 4 | r latency reset 5 | 6 | test {Test latency events logging} { 7 | r debug sleep 0.3 8 | after 1100 9 | r debug sleep 0.4 10 | after 1100 11 | r debug sleep 0.5 12 | assert {[r latency history command] >= 3} 13 | } 14 | 15 | test {LATENCY HISTORY output is ok} { 16 | set min 250 17 | set max 450 18 | foreach event [r latency history command] { 19 | lassign $event time latency 20 | assert {$latency >= $min && $latency <= $max} 21 | incr min 100 22 | incr max 100 23 | set last_time $time ; # Used in the next test 24 | } 25 | } 26 | 27 | test {LATENCY LATEST output is ok} { 28 | foreach event [r latency latest] { 29 | lassign $event eventname time latency max 30 | assert {$eventname eq "command"} 31 | assert {$max >= 450 & $max <= 650} 32 | assert {$time == $last_time} 33 | break 34 | } 35 | } 36 | 37 | test {LATENCY HISTORY / RESET with wrong event name is fine} { 38 | assert {[llength [r latency history blabla]] == 0} 39 | assert {[r latency reset blabla] == 0} 40 | } 41 | 42 | test {LATENCY DOCTOR produces some output} { 43 | assert {[string length [r latency doctor]] > 0} 44 | } 45 | 46 | test {LATENCY RESET is able to reset events} { 47 | assert {[r latency reset] > 0} 48 | assert {[r latency latest] eq {}} 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tests/unit/limits.tcl: -------------------------------------------------------------------------------- 1 | start_server {tags {"limits"} overrides {maxclients 10}} { 2 | test {Check if maxclients works refusing connections} { 3 | set c 0 4 | catch { 5 | while {$c < 50} { 6 | incr c 7 | set rd [redis_deferring_client] 8 | $rd ping 9 | $rd read 10 | after 100 11 | } 12 | } e 13 | assert {$c > 8 && $c <= 10} 14 | set e 15 | } {*ERR max*reached*} 16 | } 17 | -------------------------------------------------------------------------------- /tests/unit/other.tcl: -------------------------------------------------------------------------------- 1 | start_server {tags {"other"}} { 2 | if {$::force_failure} { 3 | # This is used just for test suite development purposes. 4 | test {Failing test} { 5 | format err 6 | } {ok} 7 | } 8 | 9 | test {BGSAVE} { 10 | r debug flushall 11 | r save 12 | r incrby x 10 13 | r bgsave 14 | waitForBgsave r 15 | r debug reload 16 | r get x 17 | } {10} 18 | 19 | test {Perform a final SAVE to leave a clean DB on disk} { 20 | r debug flushall 21 | waitForBgsave r 22 | r save 23 | } {OK} 24 | } 25 | -------------------------------------------------------------------------------- /tests/unit/printver.tcl: -------------------------------------------------------------------------------- 1 | start_server {} { 2 | set i [r info] 3 | regexp {discnt_version:(.*?)\r\n} $i - version 4 | regexp {discnt_git_sha1:(.*?)\r\n} $i - sha1 5 | puts "Testing Discnt 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 | test "Unbalanced number of quotes" { 64 | reconnect 65 | r write "set \"\"\"test-key\"\"\" test-value\r\n" 66 | r write "ping\r\n" 67 | r flush 68 | assert_error "*unbalanced*" {r read} 69 | } 70 | 71 | set c 0 72 | foreach seq [list "\x00" "*\x00" "$\x00"] { 73 | incr c 74 | test "Protocol desync regression test #$c" { 75 | set s [socket [srv 0 host] [srv 0 port]] 76 | puts -nonewline $s $seq 77 | set payload [string repeat A 1024]"\n" 78 | set test_start [clock seconds] 79 | set test_time_limit 30 80 | while 1 { 81 | if {[catch { 82 | puts -nonewline $s payload 83 | flush $s 84 | incr payload_size [string length $payload] 85 | }]} { 86 | set retval [gets $s] 87 | close $s 88 | break 89 | } else { 90 | set elapsed [expr {[clock seconds]-$test_start}] 91 | if {$elapsed > $test_time_limit} { 92 | close $s 93 | error "assertion:Redis did not closed connection after protocol desync" 94 | } 95 | } 96 | } 97 | set retval 98 | } {*Protocol error*} 99 | } 100 | unset c 101 | } 102 | 103 | -------------------------------------------------------------------------------- /utils/discnt_init_script: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # Simple Discnt init.d script conceived to work on Linux systems 4 | # as it does use of the /proc filesystem. 5 | 6 | DISCNTPORT=6379 7 | EXEC=/usr/local/bin/discnt-server 8 | CLIEXEC=/usr/local/bin/discnt-cli 9 | 10 | PIDFILE=/var/run/discnt_${DISCNTPORT}.pid 11 | CONF="/etc/discnt/${DISCNTPORT}.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 Discnt 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 $DISCNTPORT shutdown 31 | while [ -x /proc/${PID} ] 32 | do 33 | echo "Waiting for Discnt to shutdown ..." 34 | sleep 1 35 | done 36 | echo "Discnt stopped" 37 | fi 38 | ;; 39 | *) 40 | echo "Please use start or stop as first argument" 41 | ;; 42 | esac 43 | -------------------------------------------------------------------------------- /utils/discnt_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 Discnt server..." 9 | touch $PIDFILE 10 | chown $DISCNTUSER $PIDFILE 11 | sudo -u $DISCNTUSER $EXEC $CONF 12 | fi 13 | ;; 14 | stop) 15 | if [ ! -f $PIDFILE ] 16 | then 17 | echo "$PIDFILE does not exist, process is not running" 18 | else 19 | PID=$(cat $PIDFILE) 20 | echo "Stopping ..." 21 | $CLIEXEC -p $DISCNTPORT shutdown 22 | while [ -x /proc/${PID} ] 23 | do 24 | echo "Waiting for Discnt to shutdown ..." 25 | sleep 1 26 | done 27 | rm $PIDFILE 28 | echo "Discnt stopped" 29 | fi 30 | ;; 31 | status) 32 | PID=$(cat $PIDFILE) 33 | if [ ! -x /proc/${PID} ] 34 | then 35 | echo 'Discnt is not running' 36 | else 37 | echo "Discnt is running ($PID)" 38 | fi 39 | ;; 40 | restart) 41 | $0 stop 42 | $0 start 43 | ;; 44 | *) 45 | echo "Please use start, stop, restart or status as first argument" 46 | ;; 47 | esac 48 | -------------------------------------------------------------------------------- /utils/replay.tcl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env tclsh8.5 2 | # Copyright (C) 2015 Erik Dubbelboer 3 | # Released under the BSD license like Discnt itself 4 | # 5 | # Reply output from MONITOR passed on stdin. 6 | 7 | source "../tests/support/redis.tcl" 8 | 9 | set ::host "127.0.0.1" 10 | set ::port 5262 11 | set ::verbose 0 12 | 13 | proc main {} { 14 | set r [redis $::host $::port] 15 | 16 | while 1 { 17 | set l [gets stdin] 18 | if {[eof stdin]} { 19 | break 20 | } 21 | # MONITOR output always starts with an OK. 22 | if {$l == "OK"} { 23 | continue 24 | } 25 | 26 | set l [string map {"\"" ""} $l] 27 | 28 | set c [split $l] 29 | set c [lreplace $c 0 1] 30 | 31 | if {$::verbose} { 32 | puts $c 33 | } 34 | set v [$r {*}$c] 35 | if {$::verbose} { 36 | puts $v 37 | } 38 | } 39 | } 40 | 41 | proc help {} { 42 | puts "Usage: ./replay.tcl \[OPTIONS\]" 43 | puts " -h Server hostname (default: 127.0.0.1)." 44 | puts " -p Server port (default: 5262)." 45 | puts " --help Output this help and exit." 46 | puts "" 47 | puts "Examples:" 48 | puts " discnt-cli monitor | ./replay.tcl -p 1234" 49 | exit 0 50 | } 51 | 52 | # Force the user to run the script from the 'utils' directory. 53 | if {![file exists replay.tcl]} { 54 | puts "Please make sure to run replay.tcl while inside /utils." 55 | puts "Example: cd ~/discnt/utils; ./replay.tcl < ~/monitor.out" 56 | exit 1 57 | } 58 | 59 | for {set j 0} {$j < [llength $argv]} {incr j} { 60 | set opt [lindex $argv $j] 61 | set arg [lindex $argv [expr $j+1]] 62 | if {$opt eq {-h}} { 63 | if {$arg == ""} { 64 | help 65 | } 66 | set ::host $arg 67 | incr j 68 | } elseif {$opt eq {-p}} { 69 | set ::port $arg 70 | incr j 71 | } elseif {$opt eq {-v}} { 72 | set ::verbose 1 73 | } elseif {$opt eq {--help}} { 74 | help 75 | } else { 76 | puts "Wrong argument: $opt" 77 | exit 1 78 | } 79 | } 80 | 81 | main 82 | --------------------------------------------------------------------------------