Compare commits

..
487 Commits
Author SHA1 Message Date
antirez e74fe10b00 Redis 2.4.13 2012-05-02 12:14:48 +02:00
Pieter Noordhuisandantirez f2ffb59294 Use safe dictionary iterator from KEYS
Every matched key in a KEYS call is checked for expiration. When the key
is set to expire, the call to `getExpire` will assert that the key also
exists in the main dictionary. This in turn causes a rehashing step to
be executed. Rehashing a dictionary when there is an iterator active may
result in the iterator emitting duplicate entries, or not emitting some
entries at all. By using a safe iterator, the rehash step is omitted.
2012-05-01 10:52:27 +02:00
antirez 9cb09c4d2c Redis 2.4.12 2012-04-30 12:27:50 +02:00
antirez fc7ea2f7cd Properly wait the slave to sync with master in BRPOPLPUSH test. 2012-04-30 11:50:42 +02:00
antirez fb38fd3c89 A more lightweight implementation of issue 141 regression test. 2012-04-30 11:48:32 +02:00
antirez 9e066ae051 Redis test: More reliable BRPOPLPUSH replication test.
Now it uses the new wait_for_condition testing primitive.
Also wait_for_condition implementation was fixed in this commit to properly
escape the expr command and its argument.
2012-04-30 11:48:16 +02:00
antirez 28500d193f Testing framework fixes and improvements backported from 2.6. 2012-04-30 11:47:47 +02:00
antirez 63bae7c553 A few compiler warnings suppressed. 2012-04-29 17:20:56 +02:00
antirez 379ac85eed memtest.c fixed to actually use v1 and v2 in memtest_fill_value(). 2012-04-29 17:17:44 +02:00
antirez df10c797e0 Limit memory used by big SLOWLOG entries.
Two limits are added:

1) Up to SLOWLOG_ENTRY_MAX_ARGV arguments are logged.
2) Up to SLOWLOG_ENTRY_MAX_STRING bytes per argument are logged.
3) slowlog-max-len is set to 128 by default (was 1024).

The number of remaining arguments / bytes is logged in the entry
so that the user can understand better the nature of the logged command.
2012-04-21 21:50:25 +02:00
antirez f743cacc85 Redis 2.4.11 2012-04-19 14:56:16 +02:00
antirez 922283b553 New redis-cli backported from unstable. 2012-04-18 21:20:35 +02:00
antirez 32fef1566a Marginally cleaner lookupKeyByPattern() implementation.
just fieldobj itself as sentinel of the fact a field object is used or
not, instead of using the filed length, that may be confusing both for
people and for the compiler emitting a warning.
2012-04-18 11:40:48 +02:00
antirez 8e5e8f0eca lookupKeyByPattern() used by SORT GET/BY rewritten. Fixes issue #460.
lookupKeyByPattern() was implemented with a trick to speedup the lookup
process allocating two fake Redis obejcts on the stack. However now that
we propagate expires to the slave as DEL operations the lookup of the
key may result into a call to expireIfNeeded() having the stack
allocated object as argument, that may in turn use it to create the
protocol to send to the slave. But since this fake obejcts are
inherently read-only this is a problem.

As a side effect of this fix there are no longer size limits in the
pattern to be used with GET/BY option of SORT.

See https://github.com/antirez/redis/issues/460 for bug details.
2012-04-17 18:27:18 +02:00
jokeaandantirez 7b4dc9b979 implement aeWait using poll(2). Fixes issue #267. 2012-04-06 11:49:40 +02:00
antirez 95c6a1a5b8 Structure field controlling the INFO field master_link_down_since_seconds initialized correctly to avoid strange INFO output at startup when a slave has yet to connect to its master. 2012-04-04 18:31:37 +02:00
antirez 1fa954a558 Redis 2.4.10 2012-03-30 13:07:18 +02:00
antirez 06665b7191 Useless GCC warning suppressed. 2012-03-30 13:02:08 +02:00
Salvatore Sanfilippo 3c38b0876e Merge pull request #417 from josephjang/e95ca1db21b2dbe82f39a3f7f6390cb5f58dafae
a memory leak with replication on two or more dbs including >= db10
2012-03-30 01:28:58 -07:00
Joseph Jang e95ca1db21 Fixed a memory leak with replication
occurs when two or more dbs are replicated and at least one of them is >db10
2012-03-30 02:17:21 +09:00
antirez 6938960b66 Fix for slaves chains. Force resync of slaves (simply disconnecting them) when SLAVEOF turns a master into a slave. 2012-03-29 09:31:39 +02:00
antirez 9a5cbf9f7e Memory addressing test implemented. 2012-03-19 14:03:00 +01:00
antirez 1dfe75a09b Redis 2.4.9 2012-03-18 22:14:28 +01:00
antirez 8122954b9a Memory test feature backported into 2.4. 2012-03-18 22:08:44 +01:00
antirez f5f95b35d5 More memory tests implemented. Default number of iterations lowered to a more acceptable value of 50. 2012-03-18 22:00:08 +01:00
antirez 015dba6adb Fixed typo. 2012-03-18 22:00:04 +01:00
antirez 83f0c677f8 Number of iteration of --test-memory is now 300 (several minutes per gigabyte). Memtest86 and Memtester links are also displayed while running the test. 2012-03-18 21:59:59 +01:00
antirez a7e66f8048 On crash suggest to give --test-memory a try. 2012-03-18 21:59:52 +01:00
antirez ae92e6dc15 Memory test function now less boring thanks to screen-wide progress bar. 2012-03-18 21:58:40 +01:00
antirez e306e99029 Hem... actual memtest.c file added. 2012-03-18 21:58:35 +01:00
antirez 9c3bc7529d First implementation of --test-memory. Still a work in progress. 2012-03-18 21:58:24 +01:00
antirez 7961d7ea0d redis-benchmark: backported the more capable version from the unstable branch (pipelining,run selected tests,fixes) 2012-02-26 11:41:44 +01:00
antirez a3b580c0c5 The universe is 80 columns wide, accept it. 2012-02-22 17:23:13 +01:00
Brad Vothandantirez 660a1277be updated utils/install_server.sh to support chkconfig boxes (redhat/
centos) as well as debian/ubuntu
2012-02-22 17:23:07 +01:00
antirez b805430a9e Fix for issue #306, thanks to tchajed (on github) for the pull request. The original patch was reworked a bit. 2012-02-22 16:09:01 +01:00
antirez a8a3275566 Redis-cli should accept help command even if there is no connection to the server. 2012-02-22 15:16:26 +01:00
antirez bd624d0fc3 Redis version 2.4.8 2012-02-22 14:23:43 +01:00
antirez f1654434de zzlIsInRange() now is capable of handling empty sorted sets that may end inside the data set when loading very old RDB files produced by early-stage versions of Redis. 2012-02-22 09:52:39 +01:00
Salvatore Sanfilippo 9f50ce0d8d Merge pull request #346 from pietern/2.4-segv
Force SIGSEGV without HAVE_BACKTRACE (2.4)
2012-02-21 10:29:34 -08:00
Pieter Noordhuis c39b869460 Solaris has backtrace(3) 2012-02-21 10:11:20 -08:00
Pieter Noordhuis a0dc1e6969 Also force SIGSEGV without HAVE_BACKTRACE 2012-02-21 10:05:46 -08:00
antirez 246c4c2322 Fixed undefined behavior in *INCR style functions overflow detection. Sorry clang! 2012-02-21 18:25:49 +01:00
antirez 2b0d9c5ac6 Added an unstalbe-alike distclean target to 2.4 Makefile. 2012-02-21 10:16:00 +01:00
antirez 19fb7404a4 Fix 32bit build of hiredis 2012-02-21 10:12:02 +01:00
antirez 11f0a23caf Applied a few modifications to hiredis to tune it for speed (redis-benchmark) and ability to read more deeply nested replies (redis-cli). 2012-02-21 10:11:47 +01:00
antirez 6887744245 The hiredis lib shipped with Redis was updated to latest version. 2012-02-21 10:11:37 +01:00
antirez 68897a5bbe bzero -> memset 2012-02-21 10:07:06 +01:00
antirez cf7d3f9d3d Merge branch '2.4-issue327' into 2.4 2012-02-20 17:30:35 +01:00
antirez f0c3b249cb Issue #330 regression test. 2012-02-16 16:15:13 +01:00
antirez da8bcd28a5 Now HINCRBY can detect overflows too. Fix for issue #330. 2012-02-16 16:09:25 +01:00
antirez b3a86b8209 Fixed a few broken stuff introduced while merging issue #327 related code in 2.4 2012-02-15 15:30:29 +01:00
antirez 31f9f987ac more practical maxmemory+slaves hint in redis.conf 2012-02-15 15:26:23 +01:00
antirez 662f25e805 redis.conf updated with new maxmemory semantics 2012-02-15 15:26:19 +01:00
antirez f27d38862d debugging messages removed from freeMemoryIfNeeded() 2012-02-15 15:26:14 +01:00
antirez 4de73b7e0f Fixes to c->reply_bytes computation, and debug messages to closely study the behavior of memory pressure + slaves + maxmemory + blocked slaves. 2012-02-15 15:26:08 +01:00
antirez 8b1829009b Precision of getClientOutputBufferMemoryUsage() greatily improved, see issue #327 for more information. 2012-02-15 15:24:36 +01:00
antirez 35a4761f1d freeMemoryIfNeeded() minor refactoring 2012-02-15 15:22:57 +01:00
antirez 5a7999e66a Also remove size of AOF buffers from used memory when doing the math for freeMemoryIfNeeded() 2012-02-15 15:20:46 +01:00
antirez c63e1b83c4 This fixes issue #327, is a very complex fix (unfortunately), details:
1) sendReplyToClient() now no longer stops transferring data to a single
client in the case we are out of memory (maxmemory-wise).

2) in processCommand() the idea of we being out of memory is no longer
the naive zmalloc_used_memory() > server.maxmemory. To say if we can
accept or not write queries is up to the return value of
freeMemoryIfNeeded(), that has full control about that.

3) freeMemoryIfNeeded() now does its math without considering output
buffers size. But at the same time it can't let the output buffers to
put us too much outside the max memory limit, so at the same time it
makes sure there is enough effort into delivering the output buffers to
the slaves, calling the write handler directly.

This three changes are the result of many tests, I found (partially
empirically) that is the best way to address the problem, but maybe
we'll find better solutions in the future.
2012-02-15 15:20:20 +01:00
antirez 05755f5c40 Initial version of c->reply_bytes implementation backported from unstable to 2.4, in order to apply issue 327 patches. 2012-02-15 15:20:05 +01:00
antirez 02b984c219 redis-check-aof is now large files safe also on 32 bit systems. 2012-02-14 19:57:31 +01:00
antirez 01b302aba4 add -f flag to cp when installing, otherwise stopping the server is
needed when installing a new Redis version. Thanks to Scott Kevill.
Fixes issue #335.
2012-02-14 16:15:42 +01:00
antirez bad380bdb5 Redis 2.4.7 2012-02-02 15:29:24 +01:00
antirez 0b73cbb69f sds.c no longe pre-allocate more than 1MB of free space ahead. This fixes issue #252. 2012-02-02 12:40:44 +01:00
antirez 1cd0cdd523 Set a 3.5 GB maxmemory limit with noeviction policy if a 32 bit instance without user-provided memory limits is detected. 2012-02-02 10:17:21 +01:00
antirez f373061563 Added a server.arch_bits field instead of computing it at runtime for INFO. 2012-02-02 10:02:40 +01:00
antirez 29b3794231 Only incremnet stats for key miss/hit when the key is semantically accessed in read-only. 2012-02-02 09:51:11 +01:00
Salvatore Sanfilippo 58bfbd1fa4 Merge pull request #296 from pietern/2.4-expirefix
Don't expire keys when loading an RDB after a SYNC
2012-01-16 01:18:41 -08:00
Pieter Noordhuis aa794ac06d Don't expire keys when loading an RDB after a SYNC
The cron is responsible for expiring keys. When keys are expired at
load time, it is possible that the snapshot of a master node gets
modified. This can in turn lead to inconsistencies in the data set.

A more concrete example of this behavior follows. A user reported a
slave that would show an monotonically increase input buffer length,
shortly after completing a SYNC. Also, `INFO` output showed a single
blocked client, which could only be the master link. Investigation
showed that indeed the `BRPOP` command was fed by the master. This
command can only end up in the stream of write operations when it did
NOT block, and effectively executed `RPOP`. However, when the key
involved in the `BRPOP` is expired BEFORE the command is executed, the
client executing it will block. The client in this case, is the master
link.
2012-01-13 18:03:33 -08:00
antirez 8b8261edc3 Possible fix for false positives in issue 141 regression test 2012-01-12 16:24:41 +01:00
antirez fbfe656236 On crash print information about the current client (if any), command vector, and object associated to first argument assuming it is a key. 2012-01-12 16:16:23 +01:00
antirez e1849b6456 Redis 2.4.6 2012-01-11 20:30:55 +01:00
antirez d0f37e247c error in comment fixed 2012-01-11 20:25:41 +01:00
antirez 3b67a0f905 show GCC version in INFO output. 2012-01-10 18:39:32 +01:00
antirez 2c2b6159d3 Regression test for the main problem causing issue #141. Minor changes/fixes/additions to the test suite itself needed to write the test. 2012-01-07 12:52:42 +01:00
antirez d4945b253b Redis test: when assertion fails print not just the expression but also expanded values in the error message. 2012-01-07 12:52:32 +01:00
antirez 53785789a0 Regression tests for protocol desync bug related to Issue #141 2012-01-07 12:51:22 +01:00
antirez e7b85b3315 Protections against protocol desyncs, leading to infinite query buffer growing, due to nul-terms in specific bytes of the request or indefinitely long multi bulk or bulk count strings without newlines. This bug is related to Issue #141 as well. 2012-01-07 12:50:44 +01:00
antirez a5045d552c Fixed replication when multiple slaves are attaching at the same time. The output buffer was not copied correctly between slaves. This fixes issue #141. 2012-01-07 12:48:10 +01:00
antirez 8939ff1230 Do not propagate DEBUG LOADAOF 2012-01-07 12:47:10 +01:00
antirez 8b102e041a List connected slaves with ip,port,state information in INFO, as requested by github issue #219 2012-01-07 12:44:27 +01:00
antirez 273f41023d Redis 2.4.5 2011-12-23 09:43:24 +01:00
antirez 5bb2565959 Added regression test for ZUNIONSTORE creating NaN (github issue #264) 2011-12-23 09:34:41 +01:00
antirez 0692d060b3 Prevent NaN scores in sorted sets resulting from calls to ZUNIONSTORE and ZINTERSTORE. 2011-12-23 09:28:51 +01:00
antirez 2e689217d5 Redis test: vaoid two false positives while running under valgrind. 2011-12-20 10:35:33 +01:00
antirez b76088845c Redis test: two redundant tests removed as they tend to create issues when running the test with valgrind. 2011-12-20 10:35:23 +01:00
antirez 8a625029e7 Redis test port allocation fixed. 2011-12-20 10:34:51 +01:00
antirez 8a6b21da61 unit/introspection.tcl added 2011-12-19 10:22:04 +01:00
antirez c08eb8e74d unit/introspection added among tests executed by default 2011-12-19 10:19:12 +01:00
antirez 8b860b36b3 Fixed memleak in CLIENT INFO, added simple test that will work as regression test on mac os x and in the CI when running over valgrind. This fixes issue #256 2011-12-19 10:19:08 +01:00
antirez 61e44f614d added assertion in zslInsert() that ensures the inserted element score is not NaN 2011-12-18 11:13:13 +01:00
antirez bc62bc5eac Fixed SORT bugs (issue #224) with regression tests. 2011-12-01 16:08:30 +01:00
antirez 67d6b29404 Replication bug fixed: now non blocking connect is also forced to follow the configured replication timeout. 2011-11-30 17:13:15 +01:00
antirez 901120f8e6 --quiet option implemented in the Redis test. Output improved a bit. 2011-11-30 09:36:30 +01:00
antirez 54a2934f10 Redis 2.4.4 2011-11-28 11:22:08 +01:00
antirez a675e5b171 two new AOF related INFO fields that can be interesting information for debugging. 2011-11-28 11:11:13 +01:00
antirez 0f2199ec29 show initial querybuf bytes on querybuf overflow. 2011-11-25 17:08:25 +01:00
antirez 241e3cff83 jemalloc gitignore updated to jemalloc 2.2.5 2011-11-25 16:48:07 +01:00
jbergstroemandantirez a9c2f0f28a Update to jemalloc 2.2.5 2011-11-25 16:47:55 +01:00
antirez 7558b1fe4d log client protocol errors for log level >= verbose 2011-11-25 16:09:16 +01:00
antirez fcf5783632 Added regression tests for issue #209 2011-11-25 12:27:00 +01:00
woowenjieandantirez 6532df2e7e clean REDIS_DIRTY_CAS when discard Command runs. otherwise the next MULTI/EXEC may fail in the same RedisClient 2011-11-25 12:13:57 +01:00
antirez 8a82ee0f3c better bug report info on crash (backported from unstable) 2011-11-24 15:53:35 +01:00
antirez f4e2abfcd4 minor refactoring to networking.c adding a separated function to get a string representing the current state of all the connected clients. 2011-11-24 15:47:55 +01:00
antirez 3852e2a831 last executed command in CLIENT LIST output. 2011-11-24 14:56:43 +01:00
antirez 6a252e9498 Redis 2.4.3 2011-11-21 18:47:39 +01:00
antirez 5d5e68a486 Fixed bug in getClientInfoString() that was not rendering the N (no flags) special flag correctly. 2011-11-21 18:37:22 +01:00
antirez a6e4627438 Close client connection and log the event when the client input buffer reaches 1GB. 2011-11-21 18:37:17 +01:00
antirez 93babe4b41 show active events in client file descriptor in CLIENT LIST. 2011-11-21 18:37:05 +01:00
antirez 713b4c5401 new ae.c API to get current events by file descriptor. 2011-11-21 18:37:01 +01:00
antirez 51baa1922b added output list and buffer length, query buffer size, to CLIENT LIST output. 2011-11-21 18:36:56 +01:00
antirez f3ac12aac2 code generating the CLIENT LIST output refactored to have a function that is able to render a single client into a client info string. 2011-11-21 18:36:41 +01:00
antirez 0b1531e50b Added sdscatsds() to sds.c/h 2011-11-21 18:32:29 +01:00
antirez b1b98c64cc Max log message length set to 4k to avoid truncated INFO output in logs on Redis crash. This is just a workaround and it is handled better in the unstable branch. 2011-11-21 18:32:08 +01:00
Chris Lambandantirez cec6b04842 Fix crash on SPARC due to improper alignment of allocated memory
I believe that you should be able to drop 'defined(__sun)' completely
from this clause, as Solaris on x86 hardware probably does not have
strict alignment requirements, but I don't have a way to test that.

Thanks to Jurij Smakov <jurij@wooyd.org>.

Signed-off-by: Chris Lamb <lamby@debian.org>
2011-11-16 18:24:06 +01:00
antirez beb4bacce6 I/O buffer length enlarged 2011-11-11 17:19:57 +01:00
antirez 3fac86ff1d set default client timeout to zero inside redis.h as well 2011-11-11 17:16:03 +01:00
antirez 18fe946f6a use timeout 0 by default, as this is a common source of problems. 2011-10-31 15:43:23 +01:00
antirez 9e68987f53 added more clarifications in redis.conf about ther right value to set as replication timeout. 2011-10-31 11:17:40 +01:00
Salvatore Sanfilippo 7e11ca0ae9 Merge pull request #149 from hgfischer/2.4
repl_ping_slave_period and repl_timeout configs
2011-10-31 03:11:17 -07:00
antirez d1387aa64d It is now possible to disable password authentication via CONFIG SET. Thanks to Jan Oberst. This closes issue #171. 2011-10-31 09:57:18 +01:00
antirez 7d31a020ea Fixed a memory leak in redis-cli.c 2011-10-28 17:43:43 +02:00
antirez cacab3b1c8 sds.c single quotes support 2011-10-28 17:43:39 +02:00
antirez 072a9052c7 Redis 2.4.2 2011-10-26 16:16:33 +02:00
Salvatore Sanfilippo 00af23bcbf Merge pull request #154 from florean/2.4
2.4
2011-10-26 04:01:01 -07:00
antirez 15c9497280 Clear the AOF rewrite scheduled flag once an AOF rewrite is triggered. Fix for issue #161, probably fixing 159 as well. 2011-10-26 12:55:09 +02:00
antirez 45bd4a1853 Better installation info inside README file. 2011-10-23 12:28:31 +02:00
antirez 0327d9b8e9 removed a few entries for gitignore 2011-10-23 12:16:30 +02:00
antirez 1e81d971dc template files for installation script added 2011-10-23 12:15:02 +02:00
antirez 9a3a84bfdf Script to install the server in Ubuntu/Debian added to 2.4 as well. 2011-10-23 11:49:58 +02:00
Nathan Florea 1126d5aa49 Set errno to 0 before calling strtol. 2011-10-20 18:20:58 -07:00
Herbert G. Fischer 1fe4cd5de9 fixed source indenting 2011-10-18 19:03:18 -02:00
Herbert G. Fischer 421f6afd3d fixed typo in comments 2011-10-18 19:01:30 -02:00
Herbert G. Fischer 7c6da7327f Added repl_ping_slave_period and repl_timeout options support 2011-10-18 18:56:10 -02:00
antirez b6fe152b83 Fix to the previous fix for issue #145, make sure to return only after the event was unregistered. 2011-10-18 17:12:16 +02:00
smlyandantirez 1270a13667 Fixed a small memory leak I found with valgrind 2011-10-18 14:13:47 +02:00
antirez 98f5abb6e3 Return from syncWithMaster() ASAP if the event fired but the instance is no longer a slave. This should fix Issue #145. 2011-10-18 11:09:32 +02:00
antirez ab648d973d 2.4.1 release notes. 2011-10-17 10:46:00 +02:00
antirez 5ab72bedb7 version bumped to 2.4.1 2011-10-17 10:43:02 +02:00
antirez 9a83d13fb5 revert version bumping to 2.4.1, put in the previous commit for an error. 2011-10-17 10:42:47 +02:00
antirez 6662806a26 Regression test for issue #142 added 2011-10-17 10:40:11 +02:00
antirez 6e3f1a9e47 FLUSHALL now prevents rdbSave() from resetting the dirty counter, so that the command will get replicated and put inside the AOF. This fixes issue #142 2011-10-17 10:28:57 +02:00
antirez d12f26c231 FLUSHALL will only perform a blocking SAVE if RDB persistence is configured. 2011-10-17 10:25:35 +02:00
antirez a502f48320 2.4.0 Release notes. 2011-10-14 17:54:25 +02:00
antirez 0c71939c05 Version bumped to 2.4.0 2011-10-14 17:49:20 +02:00
antirez a4f46f211c Exit with Fatal error at startup if the RDB file signature or version is wrong.
Ref: issue #103
2011-10-14 17:04:24 +02:00
antirez 8185c2e9f1 redis-check-dump: RDB version 2 now supported. 2011-10-14 16:52:11 +02:00
antirez 71bb31bf16 More informative error when DEBUG RELOAD fails. 2011-10-14 14:30:41 +02:00
antirez c7d23f3ed1 Fix for issue #132. Now AUTH raises an error if no server password is configured. 2011-10-10 22:22:27 +02:00
Nathan Floreaandantirez 09cefcfbb3 Added a config directive for a Unix socket mask
Added a configuration directive to allow a user to specify the
permissions to be granted to the Unix socket file.  I followed
the format Pieter and Salvatore discusses in issue #85 (
https://github.com/antirez/redis/issues/85).
2011-10-10 22:08:11 +02:00
Nathan Floreaandantirez 1ca8deebef Unlink Unix socket file on shutdown 2011-10-10 22:08:03 +02:00
antirez b7f667b553 Issue #131. stime/utime reported in INFO was inverted. Fixed thanks to Didier Spezia. 2011-10-10 15:29:36 +02:00
antirez 067ad37f96 Fix for bug #128 about the RENAME command. 2011-10-10 15:25:28 +02:00
antirez a6e312bf9a Added two new tests for RENAME, currently both will fail because of bug #128. 2011-10-10 15:25:22 +02:00
antirez 0e841b998a CONFIG SET/GET support for loglevel 2011-10-06 15:25:53 +02:00
antirez cd0458470e Redis test ports selection made more robust. This prevents the test from hanging if an already bound port is selected but the TCP server listening to it does not cause a protocol error with a Redis client PING. Also base port moved away from the range near to the Redis Cluster gossip ports. 2011-10-04 10:07:29 +02:00
antirez 678dbc48fd Compilation fixed on OpenBSD making sure that _XOPEN_SOURCE is set to 700 in fmacros.h 2011-09-29 10:20:26 +02:00
Juri M. Vainonenandantirez 3a91aca033 fixed a small bug that caused redis-cli to segfault when given single numeric parameter greater that zero. 2011-09-21 22:33:01 +02:00
antirez 9286ecd767 Release notes for Redis 2.4 RC8 added 2011-09-21 14:05:36 +02:00
antirez 902a656f7a Version bumped to 2.3.11 2011-09-21 13:56:03 +02:00
antirez a58e486d79 no longer valid design documents removed 2011-09-20 11:15:18 +02:00
antirez b0fcf23304 hash zipmap max entries and entry size information removed from INFO command since we have this info and the equivalent info for sets, hashes, zset accessible via the CONFIG GET command. 2011-09-20 11:08:08 +02:00
vamboandantirez 57f611d953 Corrected typo in documentation for R_Zero, R_PosInf, R_NegInf, R_Nan; 2011-09-20 11:01:20 +02:00
Konstantin Tokarevandantirez 20c26321c2 Fixed compilation on Mac/PPC
Applied patch from Issue 119 provided by
pahowes@gmail.com
2011-09-20 10:59:47 +02:00
Konstantin Merenkovandantirez 2017d8baf7 [issue 620] don't segfault if number of arguments is less than 1 2011-09-20 10:56:43 +02:00
antirez a511ce1b49 Include port number in error when can't bind lisetning port on startup. 2011-09-20 10:48:33 +02:00
antirez 1f164f4e1d Fixed comment typo 2011-09-19 17:49:50 +02:00
antirez 9f775040c8 Comment out things in bio.c that are currently not useful but that may be useful in the future. 2011-09-19 17:44:21 +02:00
antirez 6ca793fc21 Emit a log message when AOF fsync is still in progress but we are forced to write from the main thread since two seconds already elapsed. 2011-09-19 17:44:17 +02:00
antirez 01ac844ba2 use aof_fsync wrapper instead of fsync(2) in bio.c 2011-09-19 17:44:11 +02:00
antirez 79b9ec53d1 fixed flushAppendOnlyFile() function prototype to reflect the new implementation, fixing compilation. 2011-09-19 17:43:56 +02:00
antirez 4c2d5f0980 postpone the AOF fsync if policy is everysec and there is a background fsync already going. 2011-09-19 17:43:49 +02:00
antirez 056c2acaea Fixed typo preventing compilation 2011-09-19 17:43:44 +02:00
antirez f85c383b6c Added aof_backgronud_fsync() function, and use it in the bacground rewrite done handler when the fsync policy is everysec. 2011-09-19 17:43:40 +02:00
antirez 3ae56d8458 REDIS_BIO_AOF_FSYNC implemented 2011-09-19 17:43:34 +02:00
antirez 0807f5b9ff fixed a problem in bioOlderJobType() when there are no jobs of the specified type. Now the function returns 0 when this happens. 2011-09-19 17:43:28 +02:00
antirez 2eae7cbc7d some more comment about bio.c design 2011-09-19 17:43:23 +02:00
antirez 693618f1c1 Remove backgroud jobs from the queue only when the processing was completed, and not just started. 2011-09-19 17:43:19 +02:00
antirez c67e8d3bf6 Use a different thread for every different type of background job 2011-09-19 17:43:13 +02:00
antirez 411cb75bcd Better comments for bioWaitPendingJobsLE 2011-09-19 17:43:07 +02:00
antirez 794419192e Background I/O library enhanced so that the main thread can query for the number of pending jobs of the specified type. 2011-09-19 17:43:01 +02:00
antirez 481a05cd23 commenting out aof-race test for now, waiting for a fix to issue #80 2011-09-16 15:43:27 +02:00
Pieter Noordhuisandantirez b9a65682fb Failing test related to AOF rewrite buffers 2011-09-16 11:24:08 +02:00
Pieter Noordhuisandantirez e3d1c8b080 Enforce upper bound for number of requests in redis-benchmark 2011-09-16 11:23:53 +02:00
Pieter Noordhuisandantirez 682b63312e Fix AOF race that may duplicate commands 2011-09-16 11:14:00 +02:00
antirez 6fd1a72712 Fixed a bug in the average latency metering of redis-cli --latency 2011-09-15 19:32:49 +02:00
antirez 2e48ad5422 Implemented --latency in redis-cli 2011-09-15 19:28:24 +02:00
antirez 67f594f9b5 Optimize LRANGE to scan the list starting from the head or the tail in order to traverse the minimal number of elements. Thanks to Didier Spezia for noticing the problem and providing a patch. 2011-09-14 15:17:04 +02:00
antirez b7bf29059e Don't replicate/AOF SAVE 2011-09-14 13:08:19 +02:00
antirez 889d468e51 use bio.c instead of libeio for closing the AOF file in background. Some comment added and other minor changes. 2011-09-14 10:52:07 +02:00
Pieter Noordhuisandantirez 84f48cc401 Asynchronously close old file after BGREWRITEAOF 2011-09-14 10:51:52 +02:00
antirez 44690ab15f make bio_list static as well 2011-09-14 10:50:29 +02:00
antirez a72c0423b4 debug message removed 2011-09-14 10:50:22 +02:00
antirez c8d0013f38 use pthread_cond_signal() to make sure the background thread will process the job. 2011-09-14 10:47:53 +02:00
antirez 5ca75751ed typo fixed in bio.c 2011-09-14 10:47:48 +02:00
antirez af14408e5c add background jobs initialization to Redis main init function 2011-09-14 10:47:31 +02:00
antirez ed56ad5689 bio.c typos fixes to make it compile 2011-09-14 10:47:26 +02:00
antirez c427f5d3c1 bio.o added to redis-server objects 2011-09-14 10:47:19 +02:00
Pieter Noordhuisandantirez 325d2eb8b5 Speed up protocol synthesis for AOF 2011-09-13 12:26:53 +02:00
Pieter Noordhuisandantirez 0fb6212cf4 Re-use AOF buffer when it is small enough 2011-09-13 12:26:49 +02:00
Pieter Noordhuisandantirez f602318349 Fix indent 2011-09-13 12:26:43 +02:00
antirez 2401c3eccb added a newline for code readability 2011-09-13 12:26:38 +02:00
Pieter Noordhuisandantirez 8d9804bf40 Avoid unnecessary calls to time(3) 2011-09-13 12:26:33 +02:00
antirez da30c9e1e3 Version bumped to 2.3.10, changelog updated 2011-09-12 12:13:44 +02:00
antirez 3c51d3b36b Remove the write handler only if there are no longer objects in the output queue AND if the static buffer is empty. This bug was the cause of a possible server-stop-responding-to-client bug under some specific work load. Thanks to Pieter Noordhuis for spotting and fixing it. 2011-09-12 11:06:11 +02:00
antirez 00c7f312cc regression test for bug 593 added 2011-09-12 10:54:43 +02:00
antirez b10913b93d fixed typos in the comments of rpoplpushHandlePush() 2011-09-12 10:05:38 +02:00
Hampus Wessmanandantirez cbf01c0e01 Fix crash when chaining brpoplpush with other blocking commands. 2011-09-12 10:05:32 +02:00
antirez 214cf63730 Version bumped to 2.3.9. Changelog modified accordingly. 2011-08-09 12:04:26 +02:00
antirez 4a4f4cb5ff Auto rewrite integer overflow fixed. Thanks to Gaurav for finding it (see issue 602 on google code), and Pieter Noordhuis for tracing it. 2011-08-09 11:45:57 +02:00
antirez a57bd791e9 243b783fdc 2011-07-29 15:50:15 +02:00
antirez ed9f997ce5 fixed assert proc on Redis test 2011-07-29 15:49:31 +02:00
antirez 55eea93cae Release notes for 2.4.0-RC5 2011-07-29 15:44:21 +02:00
antirez 753e91b6c1 Version bumped to 2.3.8 2011-07-29 15:39:31 +02:00
Pieter Noordhuisandantirez a830d941a7 Fix adding bulk reply when getcwd fails 2011-07-27 16:22:47 +02:00
Pieter Noordhuis 9c3a89853c HDEL: Abort deleting fields when hash is removed 2011-07-27 12:30:35 +02:00
antirez 7ca6672338 version bumped to 2.3.7 2011-07-22 16:26:24 +02:00
antirez 6c68df4f32 Close the listening sockets. Apparently this allows faster restarts. 2011-07-22 12:12:45 +02:00
antirez 8b58723eb2 prepareForShutdown() fixed for correctness regarding what to do with AOF and RDB persistence on exit. 2011-07-22 11:55:34 +02:00
Salvatore Sanfilippo abd4cd7827 Added a 'runtest' script that is responsible to check if Tcl is available and run the test. This is invoked from Makefile as well. 2011-07-15 17:24:44 +02:00
antirez 81c74eb48f version bumped to 2.3.6 2011-07-15 11:30:54 +02:00
antirez a395ce2659 removed --file in test suite execution from Makefile. The option is no longer supported 2011-07-12 10:04:27 +02:00
antirez 3a4afb0473 Manual merge after cherry-pick 2011-07-12 10:03:22 +02:00
antirez 63aed54a27 Take a pointer to the relevant entry of the command table in the client structure. This is generally a more sounding design, simplifies a few functions prototype, and as a side effect fixes a bug related to the conversion of EXPIRE -1 to DEL: before of this fix Redis tried to convert it into an EXPIREAT in the AOF code, regardless of our rewrite of the command. 2011-07-12 10:00:12 +02:00
antirez 64cb15799c don't process EXPIRE with negative TTL or EXPIREAT with time in the past if we are a slave too (see http://groups.google.com/group/redis-db/browse_thread/thread/5a931fefb88b16d5). Also propagate it as DEL. 2011-07-12 09:57:17 +02:00
antirez 19453556d4 dataspace change hook functions backported to 2.4. They are just wrappers at this point but this makes simpler to cherry-pick between branches. 2011-07-12 09:56:41 +02:00
Hampus Wessmanandantirez 91654a40e7 Don't expire keys while loading AOF.
They will be expired (and a DEL will be logged) after the loading is done
instead.
2011-07-12 09:46:17 +02:00
antirez 619174117d new test engine backported to 2.4 2011-07-12 09:40:54 +02:00
antirez 0462d983c2 Ingore jemalloc make distclean error in Makefile, caused by make clean against a tree that never compiled jemalloc. 2011-07-05 13:27:37 +02:00
antirez 847fc09855 Fixed typo in redis.conf related to slow log parameters 2011-07-03 15:50:07 +02:00
antirez d229160e18 childrens -> children in INFO output field names. This is a backward incompatible change, but really a minimal one. 2011-07-02 10:51:35 +02:00
antirez 5dc2a4885d no more allocation stats info in INFO, useless now that we have jemalloc. 2011-07-02 10:25:35 +02:00
antirez 30b345ddbb more slow log merge, I forgot to resolve a conflict. 2011-07-02 00:27:10 +02:00
antirez 06966abc66 Makefile deps updated 2011-07-02 00:25:46 +02:00
antirez 99509ab257 slow log merged into 2.4 2011-07-02 00:24:11 +02:00
antirez c755c637c6 Partial fix for a problem with AOF and BRPOP. We have at least a single evidence of an AOF that ended with a BRPOP call against an empty list, causing later issues at run time. Now the problem is detected while loading the AOF at startup, even if it is still to understand how the corrupted AOF was generated. 2011-06-29 16:11:06 +02:00
antirez 1ecfcb9380 Variadic SADD tests 2011-06-20 17:17:10 +02:00
antirez 616da6585a comment lines in config.h capitalized 2011-06-20 11:37:46 +02:00
antirez 5d5fe340e0 new INFO filed master_link_down_since_seconds 2011-06-17 16:13:22 +02:00
antirez b04e800b98 Use a safe iterator while saving the DB, since the getExpire() function will access the iterating dictionary. 2011-06-17 15:40:55 +02:00
antirez f2ac94876d Fixed init script bug, thanks to Henrik Westphal 2011-06-14 17:12:05 +02:00
antirez 13572dc21b useless call removed, thanks to Pieter for spotting this 2011-06-14 16:59:57 +02:00
Pieter Noordhuisandantirez eb48b10738 SETNX regression tests. 2011-06-14 16:59:50 +02:00
antirez 307868e149 DB API refactoring. The changes were designed together with Pieter Noordhuis. 2011-06-14 16:59:45 +02:00
antirez 322ad08697 Better init script 2011-06-14 13:48:49 +02:00
Hampus Wessmanandantirez b90c72c86a Fix automatic rewrite starting too early.
Slight adjustment in growth calculation.
2011-06-14 10:29:24 +02:00
antirez 61751a4dc4 AOF auto rewrite backported to 2.4 2011-06-10 18:31:27 +02:00
Hampus Wessmanandantirez 4dfecf64e1 Fix Makefile colors.
echo with escape sequences isn't portable. Use printf instead.
2011-06-09 16:37:32 +02:00
antirez 7638130d6e Two fixes for replication: Slave performs the AOF rewrite at the right point. Non blocking connect also uses readable handler as with old Linux kernels like 2.6.18 on connection refused the writable even is not fired (kernel bug). 2011-06-09 15:35:18 +02:00
antirez 6c194dae58 VM tests commented out for 2.4 2011-06-09 12:35:56 +02:00
antirez 7a4c4682f2 Warn the user in redis.conf that VM is deprecated and discouraged 2011-06-09 12:31:16 +02:00
antirez 054ed87d85 removed no longer useful files from utils directory 2011-06-09 12:29:05 +02:00
antirez 8dcec3bf25 INSTALL now points the user to the README file 2011-06-09 12:27:54 +02:00
antirez 7dc811b8cb Release notes updated for 2.4 2011-06-09 12:25:21 +02:00
antirez 0f3be53d7d README updated for 2.4 release 2011-06-09 12:00:28 +02:00
antirez 4e5b1d3851 version bumped to 2.3.5 2011-06-08 23:21:09 +02:00
antirez 27c8f84c66 INFO now contains the time (in usecs) needed to fork() in order to persist. The info is available in the stats section of INFO. 2011-06-08 23:20:11 +02:00
antirez 32463852be Add ustime() from unstable into utils.c 2011-06-08 23:13:47 +02:00
antirez 567d575dbe Color make backported to 2.4 2011-06-08 22:53:33 +02:00
antirez a7982fed9e Warn the user that will try to enable VM that VM sucks. But still allows him to enable VM with a special option. 2011-06-06 18:41:54 +02:00
antirez b590cedff1 no more client-libraries directory 2011-06-05 20:51:07 +02:00
antirez 02d71527d8 no more html documentation 2011-06-05 20:50:22 +02:00
antirez 112569d12d touch less pages in decrRefCount 2011-06-02 17:41:42 +02:00
Pieter Noordhuisandantirez 82c6e9c297 Ignore jemalloc build artifacts 2011-06-01 18:37:40 +02:00
antirez fcf862d22b Merge remote branch 'pietern/2.4-bench' into 2.4 2011-06-01 18:17:25 +02:00
antirez 16d227ef2d Removed useless stuff from config.h that are now moved into zmalloc.h 2011-06-01 18:07:40 +02:00
antirez ac1eda60b0 Fixed warning on Linux 2011-06-01 18:06:30 +02:00
antirez 598387b970 encoding agnostic intsets 2011-06-01 18:04:50 +02:00
antirez 8789dc82aa fmacros in utils.c to avoid warning about strcasecmp() 2011-06-01 17:58:20 +02:00
antirez 7f90bcfaee Added -ldl when linking against jemalloc, needed on Linux 2011-06-01 17:56:50 +02:00
antirez 860e3ade2d It is now possible to build with: make 32bit USE_JEMALLOC=yes 2011-06-01 17:08:12 +02:00
antirez 0042a2d737 jemalloc support backported in 2.4 using part of the Pieter Noordhuis and Didier Spezia original implementations 2011-06-01 16:52:53 +02:00
antirez 0811e89c80 jemalloc source added 2011-06-01 16:16:13 +02:00
Pieter Noordhuis fe71355df9 There is no debug mode in benchmark tool 2011-05-31 17:42:48 -07:00
Pieter Noordhuis 33d00ff7d5 Provide custom command to benchmark against via args 2011-05-31 17:42:47 -07:00
Pieter Noordhuis c60a0f588e More const's in redis-benchmark.c 2011-05-31 17:42:47 -07:00
antirez 942354f925 version bumped to 2.3.4 2011-05-31 20:46:38 +02:00
antirez cd7a497164 revert ZADD implementation to 2.4 WATCH API. 2011-05-31 20:40:24 +02:00
antirez 5fca35da3f disabled development test entry, tests moved in the right place 2011-05-31 20:37:59 +02:00
antirez d260b9a499 Variadic ZADD tests 2011-05-31 20:37:52 +02:00
antirez 45df42c9fe Variadic ZADD 2011-05-31 20:37:08 +02:00
antirez 6e326c81dc prepare to cherry pick variadic ZADD without conflicts 2011-05-31 20:36:17 +02:00
antirez 83533b622e ZREM tests 2011-05-31 20:34:02 +02:00
antirez 913090ec63 Variadic ZREM 2011-05-31 20:33:47 +02:00
antirez 51501514e9 Fix for the variadic version of SREM. Regression test added. 2011-05-31 20:15:25 +02:00
antirez 09843df1dd test for the BRPOPLPUSH issue 561 related issues 2011-05-31 12:16:16 +02:00
antirez 4f8cf6a23c use the new rewriteClientCommandVector() function for SPOP -> SREM replication translation as well. 2011-05-31 12:15:55 +02:00
antirez 0d119ad3a3 modified the BRPOPLPUSH target field cleanup strategy to fix it the proper way. 2011-05-31 12:14:26 +02:00
antirez 6a1275bcab Removed a leak in the BRPOPLPUSH unrelated to issue 561 2011-05-31 12:14:13 +02:00
antirez 3769dbd722 Fix for issue 516, rewriting the command vector to correctly repliate BRPOPLPUSH. Still to test everything, especially edge cases 2011-05-31 12:14:07 +02:00
Pieter Noordhuis afc151d3ba Make replication faster (biggest gain for small number of slaves) 2011-05-29 17:55:13 -07:00
antirez 6ac57f16cb Merge remote branch 'pietern/2.4-replnonblock' into 2.4 2011-05-29 14:24:50 +02:00
antirez 61a707af39 version bumped to 2.3.3 2011-05-28 23:04:03 +02:00
antirez 5cb0558e8c 2.4 redis-cli synched with the latest changes into unstable. 2011-05-28 23:02:49 +02:00
antirez e5dbbc20f1 Fix for Pub/Sub system, introduced in Redis 2.2.6 with the new copy-on-write safe iterator semantics. In the hope this is the last bug I introduced this way. 2011-05-25 12:31:32 +02:00
antirez 1f036c6587 Comment typo fixed 2011-05-24 10:43:19 +02:00
antirez 7dd1e95288 Fixed typo in comment 2011-05-24 10:35:48 +02:00
Pieter Noordhuis ecfc0583da Configurable synchronous I/O timeout 2011-05-22 12:57:56 +02:00
Pieter Noordhuis ff8d85885e Minor changes in non-blocking repl. connect 2011-05-22 12:48:10 +02:00
antirez d89db584fa Merge branch '2.4' of github.com:antirez/redis into 2.4 2011-05-20 11:44:38 +02:00
antirez 1f2af715cb Print version info before running the test 2011-05-20 11:44:32 +02:00
Pieter Noordhuis 78c05caf5e Non-blocking connect with master 2011-05-19 18:53:31 +02:00
antirez 10e4b58312 Fix for ZUNIONSTORE bug when there is an empty set among input sets. Regression test added. 2011-05-19 17:59:13 +02:00
antirez de6ba77bc4 Fixed misuse of the new iterator semantics in ZUNIONSTORE 2011-05-15 17:28:22 +02:00
antirez 5d64f21792 Fix for a possible bug related to ZINTER/UNIONSTORE called with the same source set more than one time. 2011-05-15 17:23:59 +02:00
antirez 86277eee4c Fixed SINTER[STORE] problem related to the new copy on write safe iterator 2011-05-15 12:18:56 +02:00
antirezandantirez 24430cb820 Fix for DEBUG DIGEST, key may expire on lookup 2011-05-13 11:44:14 +02:00
antirez 604d26ffde ZINTERSTORE regressiont test with two sets, intset+hashtable 2011-05-12 20:20:25 +02:00
antirez 338e44a6e7 replication with expire test modified to produce no or less false failures 2011-05-12 20:17:07 +02:00
antirez de77addb36 ziplist are now endianess agnostic 2011-05-12 13:26:55 +02:00
antirez 9f517b920e removed assert causing an illegal memory access. This was responsible of crashes during BLPOP and other list blocking operations. 2011-05-11 09:50:43 +02:00
antirez d0f710ea09 RDB version signature bumped to 2, now that direct saving of specially encoded types is implemented 2.2 instances are no longer able to read rdb files produced by 2.4 or unstable. 2011-05-10 11:33:29 +02:00
antirez d0d72c19d3 use safe Dict iteration in DEBUG DIGEST 2011-05-10 10:42:20 +02:00
antirez da49700d5a Introduced a safe iterator interface that can be used to iterate while accessing the dictionary at the same time. Now the default interface is consireded unsafe and should be used only with dictNext() 2011-05-10 10:22:14 +02:00
antirez ba07e1f505 Merge branch '2.4' of github.com:antirez/redis into 2.4 2011-05-07 12:10:11 +02:00
antirez 8ec9d6ef69 when Redis fails accepting a new connection reports the error at WARNING and not VERBOSE error level. Thanks to offby1 for proposing this in the Redis mailing list. #backport-candidate 2011-05-07 12:09:55 +02:00
antirez deff2338fa Merge remote branch 'pietern/2.4-misc' into 2.4 2011-05-05 16:50:28 +02:00
antirez 2ee7dd362c Merge branch '2.4' of github.com:antirez/redis into 2.4 2011-05-05 15:17:31 +02:00
Pieter Noordhuisandantirez fddd64e610 Fix ziplist regression and update stresser 2011-05-05 15:17:13 +02:00
antirez d275513b04 Merge branch '2.4' of github.com:antirez/redis into 2.4 2011-05-01 15:42:53 +02:00
antirez 2618476032 Fixed a problem with string2ll() 2011-05-01 15:40:43 +02:00
antirez c924df8c83 Fixed a bug with replication where SLAVEOF NO ONE caused a slave to close the connection with its slaves 2011-04-29 14:18:45 +02:00
Pieter Noordhuis 01f36192c8 Extra tests for string2ll 2011-04-27 14:38:58 +02:00
Pieter Noordhuis 6e258c76bf Check seplen and len before malloc'ing "tokens" 2011-04-27 14:33:21 +02:00
Pieter Noordhuis 355d8cb0b5 Use correct replacement length in sdscatrepr() 2011-04-27 14:31:18 +02:00
Pieter Noordhuis f1e072c57d Check for \n after finding \r 2011-04-27 14:29:27 +02:00
Pieter Noordhuis a244985d1d Show memory allocator in INFO output 2011-04-27 13:35:49 +02:00
Pieter Noordhuis b83a52c6f8 Use string2ll in ziplist code (faster) 2011-04-27 13:30:32 +02:00
Pieter Noordhuis 20dad91bdf Tests for string2ll; move isObject* to object.c 2011-04-27 13:26:33 +02:00
Pieter Noordhuis d548f3daad Move code 2011-04-27 13:16:23 +02:00
Pieter Noordhuis 992fe21706 Use correct argc/argv for cleanup when loading AOF 2011-04-22 09:42:38 +02:00
Pieter Noordhuis 2f170ad733 Reformat AOF tests 2011-04-22 09:42:38 +02:00
antirez 29a87f23b1 Variadic SREM backported from unstable 2011-04-21 17:31:10 +02:00
antirez 0882fe5e43 addReplyLongLong optimized to return shared objects when the value to reply is 0 or 1 2011-04-21 17:15:47 +02:00
antirez 7e5cf2660c CLIENT KILL implemented 2011-04-21 17:11:24 +02:00
antirez 91867a5ea2 CLIENT LIST implemented 2011-04-21 17:09:46 +02:00
antirez 1c30cad1ab peak mem in INFO backported from unstable branch 2011-04-21 16:55:27 +02:00
antirez bd50301f3e removed check for zmalloc return NULL in createClient(). The check was misplaced, and zmalloc never returns NULL. 2011-04-21 16:44:00 +02:00
antirez 760dec3a6c VM/direct-saving fixes 2011-04-20 17:48:46 +02:00
antirez e8852d782d encoding.c/h added, this new functions make sure that even our in memory represenation of encoded types is endianess agnostic, so we can save this stuff directly on disk without problems when reloading on a different arch. 2011-04-20 15:58:36 +02:00
antirez 1f84b0648b yet more manual backporting from unstable 2011-04-20 15:57:35 +02:00
antirez 73f01b0606 Some manual merging of encoded values direct saving 2011-04-20 15:49:32 +02:00
antirez 552a6fb39d fix type id for specially encoded data types, for direct blob saving of intsets, ziplists and zipmaps 2011-04-20 15:41:13 +02:00
antirez 5045ff843a direct saving of specially encoded types implemented for lists and sets too 2011-04-20 15:41:13 +02:00
antirez c92283770d added new RDB codes for ziplist encoded lists and intset encodeed sets 2011-04-20 15:41:13 +02:00
antirez 44d4b87f1f convert the zipmap into hash in rdb loading if the zipmap has too many elements 2011-04-20 15:41:13 +02:00
antirez cebac46589 API change function name fix 2011-04-20 15:41:13 +02:00
antirez 68495c46fe changed names of APIs to get blob len of special encoded data types 2011-04-20 15:41:13 +02:00
antirez 3dffb8e21e save zipmap encoded hashes as blobs. Work in progress. 2011-04-20 15:41:13 +02:00
Pieter Noordhuisandantirez 1c53928fca Functions to get size of specially encoded value in bytes 2011-04-20 15:32:44 +02:00
Pieter Noordhuisandantirez 660a0cdf02 Don't export unused function 2011-04-20 15:32:44 +02:00
Pieter Noordhuis 01fc59b787 More allocators 2011-04-19 23:54:43 +02:00
Pieter Noordhuis ff8187844a Inline sdslen and sdsavail (thanks to @bitbckt) 2011-04-19 23:10:45 +02:00
Pieter Noordhuis 1dabf116d8 Update hiredis 2011-04-19 23:07:36 +02:00
antirez 5b97a708fc variadic HDEL backported from unstable to 2.4 2011-04-19 17:14:44 +02:00
antirez 17f41d49b4 variadic SADD backported from unstable 2011-04-19 16:41:27 +02:00
antirez 8514f3c035 prepare to cherry pick 2011-04-19 16:35:07 +02:00
Pieter Noordhuis 3fa46ef069 Use custom string2ll and strchr 2011-04-18 21:25:52 +02:00
antirez 3c2fe3f88d version bumped to 2.3.2 after optimized sorted set merge 2011-04-15 17:51:03 +02:00
Pieter Noordhuis 687054849e Merge branch '2.4' into 2.4-zset 2011-04-15 17:47:10 +02:00
antirez 577b084e3c version bumped to 2.3.1 (2.4 unstable) 2011-04-15 17:43:21 +02:00
antirez 6a9764d183 Merge branch '2.2' of github.com:antirez/redis into 2.2 2011-04-15 17:28:03 +02:00
antirez c138dc7da4 variadic LPUSH/RPUSH backported to 2.2 2011-04-15 17:27:20 +02:00
antirez 1b905277bb tests for variadic list push 2011-04-15 17:15:59 +02:00
Pieter Noordhuis cf7a138684 Explicitly zero zval since it is stored on the stack 2011-04-06 16:57:08 +02:00
Pieter Noordhuis edfd6ae76b Test for ENCODING_SKIPLIST instead of ENCODING_RAW 2011-04-06 16:10:40 +02:00
Pieter Noordhuis 408e12dcaa Typo 2011-04-06 15:53:52 +02:00
Pieter Noordhuis dfeb899b2d Merge branch '2.2' into 2.2-zset
Conflicts:
	src/object.c
2011-04-06 15:46:33 +02:00
antirez 2b886275e9 Redis 2.2.4 2011-04-06 15:39:54 +02:00
antirez 93db956e06 make sure that OBJECT ENCODING returns skiplist for sorted sets, and not raw, so that once we will merge specially encoded sorted sets everything will make sense. 2011-04-06 15:38:08 +02:00
antirez 27fc6199ca CHANGELOG updated 2011-04-06 12:46:39 +02:00
antirez 0b01578d2e Merge branch '2.2' of github.com:antirez/redis into 2.2 2011-04-06 12:23:44 +02:00
antirez 920c45b818 version is now 2.2.3 2011-04-06 12:23:16 +02:00
antirez cf6c3f4b04 OBJECT command implemented 2011-04-06 12:22:09 +02:00
antirez fb90934c47 fixed memory leak introduced with the previous commit. Many thanks to Pieter Noordhuis for spotting it in no time 2011-03-31 19:54:08 +02:00
antirez 207ca3cedd Merge branch '2.2' of github.com:antirez/redis into 2.2 2011-03-31 16:45:27 +02:00
antirez 97d3b7dc8d Fixed issue #503. MONITOR + QUIT could crash the server, there are actually other interactions that could have the same effect (for instance Pub/Sub). 2011-03-31 16:45:05 +02:00
antirez abdbfc14c0 Fixed sdssplitargs() handling of hex-style escapes. 2011-03-22 22:49:33 +01:00
Pieter Noordhuis 724376a0df Backport patch: object swappability for encoded sorted sets 2011-03-22 16:35:50 +01:00
Pieter Noordhuis 476f044db6 Backport patch: don't use blob-saving 2011-03-22 16:30:29 +01:00
Pieter Noordhuis 8b2449dca0 Backport patch: signalModifiedKey (unstable) -> touchWatchedKey (2.2) 2011-03-22 16:12:26 +01:00
Pieter Noordhuis 763d6165ea Test that sorted sets are removed when empty 2011-03-22 16:09:22 +01:00
Pieter Noordhuis 2e18193f5b Remove sorted set when empty after ZREMRANGEBY* 2011-03-22 16:09:22 +01:00
Pieter Noordhuis 7f9c973467 Fix DEBUG DIGEST, SORT and AOF rewrite 2011-03-22 16:09:22 +01:00
Pieter Noordhuis 366e872d4d Test both sorted set encodings for every test 2011-03-22 16:09:22 +01:00
Pieter Noordhuis 4d8f13ddc3 Offset should be size_t 2011-03-22 16:09:21 +01:00
Pieter Noordhuis 3e518093b6 Remove unused function 2011-03-22 16:09:21 +01:00
Pieter Noordhuis 99cec798bb Test for empty inner range when looking for elements in range 2011-03-22 16:09:21 +01:00
Pieter Noordhuis ccf96e197b Make zzl API unaware of the robj where the ziplist is stored 2011-03-22 16:09:21 +01:00
Pieter Noordhuis 8f0a41be98 Encode sorted set after loading from dump 2011-03-22 16:09:21 +01:00
Pieter Noordhuis 63b29390b2 Convert encoding of result when in limits 2011-03-22 16:08:42 +01:00
Pieter Noordhuis 46aa0e2472 Remove comment 2011-03-22 16:08:03 +01:00
Pieter Noordhuis 07d9e35637 Generic iterator code for usage in ZUNIONSTORE/ZINTERSTORE 2011-03-22 16:08:03 +01:00
Pieter Noordhuis 2e12082b3e Make zzlLength take a ziplist argument 2011-03-22 16:08:03 +01:00
Pieter Noordhuis 08532b1e99 Add new string to long long function 2011-03-22 16:08:03 +01:00
Pieter Noordhuis 771ea6e1a6 Fix used function in ZCARD 2011-03-22 16:08:03 +01:00
Pieter Noordhuis c5802e3f4a Convert encoding when thresholds overflow 2011-03-22 16:08:03 +01:00
Pieter Noordhuis eab8382d18 Configurable thresholds for encoded sorted sets 2011-03-22 16:08:03 +01:00
Pieter Noordhuis efc77ad91c Persistence code for encoded sorted sets 2011-03-22 16:07:37 +01:00
Pieter Noordhuis a3886e29a6 Support dual encoding for more commands 2011-03-22 16:06:07 +01:00
Pieter Noordhuis db912c5a93 Support dual encoding for ZRANGEBYSCORE et al 2011-03-22 16:06:07 +01:00
Pieter Noordhuis 2165ac5573 Helpers to move around in encoded sorted set 2011-03-22 16:06:07 +01:00
Pieter Noordhuis f8224a4f90 Support dual encoding for ZREMRANGEBYRANK 2011-03-22 16:06:07 +01:00
Pieter Noordhuis 679de7ae2f Support dual encoding for ZRANGE 2011-03-22 16:05:45 +01:00
Pieter Noordhuis efc3f1783d Properly free encoded sorted set 2011-03-22 16:05:45 +01:00
Pieter Noordhuis 0b8c9eac68 Look up and remove elements by range 2011-03-22 16:05:45 +01:00
Pieter Noordhuis 4c36024f51 Typo 2011-03-22 16:05:05 +01:00
Pieter Noordhuis 8e1db6a05f Little less obfuscation 2011-03-22 16:05:05 +01:00
Pieter Noordhuis d3882605c0 Support dual encoding in ZREM 2011-03-22 16:05:05 +01:00
Pieter Noordhuis 3d6eade781 Don't encode element argument when dealing with ziplist 2011-03-22 16:04:33 +01:00
Pieter Noordhuis 6b017e615f Initial work for ziplist backed sorted sets 2011-03-22 16:04:33 +01:00
Pieter Noordhuis 3164869d78 Add function to create ziplist-backed sorted set 2011-03-22 16:03:23 +01:00
Pieter Noordhuis b38c299886 Fast conversion of double when representable as long long 2011-03-22 16:03:23 +01:00
Pieter Noordhuis 5b40d6e656 Rename zset range functions 2011-03-22 16:03:22 +01:00
Pieter Noordhuis 8c3b630561 Test for ranges where min > max 2011-03-22 16:03:22 +01:00
Pieter Noordhuis 4484e3b591 Compiler should decide on inlining 2011-03-22 16:03:22 +01:00
Pieter Noordhuis 453a906fc9 Move logic concerned with zset ranges
This also optimizes ZREVRANGEBYSCORE for pathological cases where a
sorted set contains many elements with the same score. Previously,
it would traverse the list from back to front in such a case.
2011-03-22 16:03:22 +01:00
antirez de5d4be994 Merge remote branch 'pietern/2.2-sigs' into 2.2 2011-03-07 12:21:41 +01:00
Pieter Noordhuis 69bfdcf7d4 Show database number in cli prompt when non-zero 2011-03-06 21:10:50 +01:00
Pieter Noordhuis 699465c31e Store SELECTed database for reconnect (issue #468) 2011-03-06 20:53:13 +01:00
Pieter Noordhuis 45332cc47b Minor memory leak in redis-cli (issue #464) 2011-03-06 20:53:12 +01:00
Pieter Noordhuis 2d2c17b075 Save RDB on SIGTERM (see issue #471) 2011-03-06 17:49:22 +01:00
antirez 048c0f0f37 RELEASE NOTES updated 2011-03-04 16:31:20 +01:00
antirez 3eb3cc9da4 version is now 2.2.2 2011-03-04 16:29:38 +01:00
antirez 74f6ee8dd5 Fixed return value of GETRANGE / SUBSTR 2011-03-04 16:23:18 +01:00
antirez 7a55d72f28 AOF file descriptor leak fixed 2011-03-04 16:14:09 +01:00
antirez 4e4b3b943c Redis 2.1.1, release notes updated 2011-02-23 15:48:24 +01:00
Pieter Noordhuis 61e2547675 Restore argc/argv in EXEC after command is executed 2011-02-23 09:39:29 +01:00
antirez 595b5974f8 fixed client-libraries/README to reflect the new site path instead of google code 2011-02-22 18:22:00 +01:00
antirez 58418d7c3e linenoise updated 2011-02-22 17:40:33 +01:00
antirez c02bda324f fixed color support for test suite. Now colors are shown as long as there is xterm somewhere inside the TERM env var 2011-02-22 16:40:24 +01:00
Paul Gideon Dannandantirez 1afef16d88 Allow port to be 0 in configuration, in order to allow disabling of TCP. 2011-02-22 12:12:30 +01:00
antirez 7377aacd84 seed the random number generator at startup 2011-02-22 00:01:48 +01:00
antirez eece2d528c suppress a Linux warning, for 2.2 sake 2011-02-21 17:50:54 +01:00
antirez eb5aeaf138 check return value of getcwd() 2011-02-21 17:41:25 +01:00
antirez 1a6281f52f version bumped to 2.2.0 and release notes added 2011-02-17 17:15:52 +01:00
antirez c2571b314a CONFIG SET/GET for all the special encoding parameters of sets, lists, hashes 2011-02-17 12:21:22 +01:00
Pieter Noordhuis 97aeda9828 Morph SPOP to SREM for correct behavior on log replay/replication 2011-02-16 00:24:54 +01:00
antirez ca9d961073 CONFIG GET/SET dir implemented 2011-02-14 02:51:49 +01:00
antirez 2446fbb3bb Merge remote branch 'pietern/2.2-brpoplpush' into 2.2 2011-02-07 15:27:45 +01:00
antirez 970e813be2 Fix for the previous port 0 patch, thanks to Pieter for noticing the error 2011-02-07 13:43:55 +01:00
antirez a36d524562 If port zero is specified, Redis will not listen for TCP connections 2011-02-07 12:52:40 +01:00
Pieter Noordhuis bbaf76ea2f Clarify comment 2011-01-31 16:50:17 +01:00
Pieter Noordhuis 669f302e16 Reply with single null bulk for unsuccesful BRPOPLPUSH 2011-01-31 16:50:00 +01:00
antirez 71791e7a8e propagate key eviction to slaves and AOF, like for expires, so that replicas and AOFs are always consistent even in maxmemory mode. 2011-01-27 16:53:23 +01:00
antirez 2f91d7ada4 add tarball script added 2011-01-25 10:45:53 +01:00
antirez 5ef8f9531d other minor README changes 2011-01-25 10:26:00 +01:00
antirez 3ce30a6906 README updated 2011-01-25 10:25:05 +01:00
antirez 65e79a8272 release noted updated, version bumped to 2.1.12 (2.2.0 RC4) 2011-01-25 10:21:13 +01:00
antirez ef8bc13d0d Merge branch '2.2' of github.com:antirez/redis into 2.2 2011-01-24 10:07:18 +01:00
antirez 0ffeadd290 portability fix in redis benchmark, using zu format specified with size_t instead of lu 2011-01-24 10:06:09 +01:00
antirez db0e263b42 Fixed issue #435 and at the same time introduced explicit ping in the master-slave channel that will detect a blocked master or a broken even if apparently connected TCP link. 2011-01-20 18:02:51 +01:00
antirez d526d09e41 Merge branch '2.2' of github.com:antirez/redis into 2.2 2011-01-20 16:50:02 +01:00
antirez 9738e587da Fixed compilation on FreeBSD 2011-01-20 10:59:25 +01:00
antirez da67b5f59a typo fixed in release notes for 2.2.0 RC3 2011-01-17 12:21:59 +01:00
antirez 825d2904d1 release notes updated for 2.2.0 RC3 2011-01-17 12:19:15 +01:00
Pieter Noordhuis 3becef9ee6 Reverse commits changing sorted set code for 2.2 2011-01-17 11:15:50 +01:00
antirez 2ccf6e81a6 version bumped to 2.1.11 2011-01-17 10:12:57 +01:00
Pieter Noordhuis e18b59ae7e Remove client from list of unblocked clients when it is free'd 2011-01-17 10:03:21 +01:00
Pieter Noordhuis 8ff1353766 Merge branch '2.2' of git://github.com/antirez/redis into 2.2 2011-01-17 09:44:12 +01:00
antirez 99677e89d0 default hash encoding settings also fixed in redis.conf 2011-01-15 22:32:34 +01:00
antirez f43502fb0e lame typo causing bad hashes memory characteristic 2011-01-15 22:24:48 +01:00
antirez ebb07fb4bb implemented two new INFO fields showing the size of clients max input and output buffers. 2011-01-14 10:20:35 +01:00
antirez c13c4080e5 useless expression removed in zmalloc.c 2011-01-14 09:57:07 +01:00
antirez 360664c9c8 master-slave replication fixed, it was not listing any key using KEYS command in the slave. 2011-01-14 09:54:41 +01:00
Pieter Noordhuis 7ac1b364fe Merge branch 'zset-range' into 2.2 2011-01-13 16:30:02 +01:00
Pieter Noordhuis 1b2b8cbbde Compiler should decide on inlining 2011-01-13 16:06:03 +01:00
antirez f487bbbfe2 allocation stats in INFO 2011-01-09 15:57:46 +01:00
Pieter Noordhuis 4b2499cf2f Remove newlines for networking errors 2011-01-05 10:50:47 +01:00
Pieter Noordhuis 01a0b09886 Remove glueoutputbuf from redis.conf 2011-01-05 10:44:54 +01:00
Pieter Noordhuis 90419b5681 Remove glueoutputbuf option and broken code 2011-01-05 10:37:23 +01:00
antirez ae7db3fe83 Merge remote branch 'pietern/bench-fix' into 2.2 2010-12-23 13:17:54 +01:00
Pieter Noordhuis 454f4bfd28 Fix compiler warnings on Solaris 2010-12-23 13:02:22 +01:00
Pieter Noordhuis 1408d147e4 limits.h is already included from redis.h 2010-12-23 13:02:22 +01:00
Pieter Noordhuis 78055bd4ca Solaris 10 doesn't know AF_LOCAL 2010-12-23 13:02:22 +01:00
Pieter Noordhuis 736d447380 Solaris doesn't support -rdynamic 2010-12-23 13:02:22 +01:00
Pieter Noordhuis 71b6f64f2a Update hiredis to 0.9.2 2010-12-23 13:02:21 +01:00
antirez c4e93cadfb Merge branch '2.2' of github.com:antirez/redis into 2.2 2010-12-20 13:35:13 +01:00
antirez 0540df22ba version bumped to 2.1.10 2010-12-20 13:34:07 +01:00
antirez 9ac5be2ebe Improved release notes. Added RC2 changes 2010-12-20 13:32:54 +01:00
antirez b902c1413e TODO file just pointing to the master branch TODO file 2010-12-20 13:16:38 +01:00
antirez 54e9f28922 Merge branch '2.2' of github.com:antirez/redis into 2.2 2010-12-20 13:14:36 +01:00
antirez dd889d884f removed some dead code, added evicted keys counter separated from expired keys. 2010-12-19 15:15:33 +01:00
antirez 1443a814d0 overflow detection in INCR family functions 2010-12-19 12:23:35 +01:00
antirez 076ff11c06 fixed typo in release notes 2010-12-15 18:10:15 +01:00
Pieter Noordhuis 4769dc7826 Undo rename of function names where something went wrong 2010-12-09 10:37:35 +01:00
Pieter Noordhuis 039357e471 Move logic concerned with zset ranges
This also optimizes ZREVRANGEBYSCORE for pathological cases where a
sorted set contains many elements with the same score. Previously,
it would traverse the list from back to front in such a case.
2010-12-07 23:21:07 +01:00
514 changed files with 22526 additions and 112851 deletions
+6 -15
View File
@@ -1,14 +1,13 @@
.*.swp
*.o
*.rdb
*.log
dump.rdb
redis-benchmark
redis-check-aof
redis-check-dump
redis-cli
redis-sentinel
redis-server
redis-benchmark
redis-check-dump
redis-check-aof
doc-tools
mkrelease.sh
release
misc/*
src/release.h
@@ -17,12 +16,4 @@ SHORT_TERM_TODO
release.h
src/transfer.sh
src/configs
redis.ds
src/redis.conf
src/nodes.conf
deps/lua/src/lua
deps/lua/src/luac
deps/lua/src/liblua.a
.make-*
.prerequisites
*.dSYM
src/redis-server.dSYM
+246 -11
View File
@@ -1,16 +1,251 @@
Hello! This file is just a placeholder, since this is the "unstable" branch
of Redis, the place where all the development happens.
Redis 2.4 release notes
There is no release notes for this branch, it gets forked into another branch
every time there is a partial feature freeze in order to eventually create
a new stable release.
Migrating from 2.2 to 2.4
=========================
Usually "unstable" is stable enough for you to use it in development environments
however you should never use it in production environments. It is possible
to download the latest stable release here:
Redis 2.2 is mostly a strict subset of 2.4.
The only thing you should be aware is that you can't use .rdb and AOF files
generated with 2.4 into a 2.2 instance.
http://download.redis.io/releases/redis-stable.tar.gz
2.4 slaves can be attached to 2.2 masters, but not the contrary, and only for
the time needed to perform the version upgrade.
More information is available at http://redis.io
From the point of view of the API Redis 2.4 only adds new commands
(other commands now accepts a variable number of arguments) so you don't need
to modify your program in order to use Redis 2.4.
Happy hacking!
---------
CHANGELOG
---------
What's new in Redis 2.4.13
=========================
UPGRADE URGENCY: high for all the users of the KEYS command, otherwise low.
* [BUGFIX] Fix for KEYS command: if the DB contains keys with expires the KEYS
command may return the wrong output, having duplicated or missing
keys. See issue #487 and #488 on github for details.
What's new in Redis 2.4.12
=========================
UPGRADE URGENCY: low if you don't experience any of the fixed problems.
* [BUGFIX] Limit the amount of memory consumed by the slow log.
* [BUGFIX] --test-memory option fixes.
* [BUGFIX] Less false positives in tests.
What's new in Redis 2.4.11
=========================
UPGRADE URGENCY: moderate if you don't experience any of the fixed problems.
* [BUGFIX] Fixed a problem with aeWait() implementation. May cause a crash
under non easy to replicate condiitons. See issue #267 on github.
* [BUGFIX] SORT with GET/BY option fetching expiring keys fixed. Issue #460.
* [BUGFIX] INFO field master_link_down_since_seconds initialized correctly.
* [FEATURE] redis-cli back ported from Redis unstable. Now has support for
--bigkeys (to sample the DB for very large keys), --slave to
simulate a slave instance.
What's new in Redis 2.4.10
==========================
UPGRADE URGENCY: High for users using replication with a DB identifier higher than 9, or chaining replication so that slaves are attached to other slaves. Low for all the other users.
* [FEATURE] Redis --test-meory improved with new test testing addressing.
* [BUGFIX] Fixed a memory leak: happens when replication is used with DB > 9.
* [BUGFIX] Fixed a replication bug that happens in chained replicaiton when a slave is attached to a master that is later turned into a slave. Now the chained slave reconnection is properly forced.
What's new in Redis 2.4.9
=========================
UPGRADE URGENCY: low. Mostly new features and minor bug fixing.
* [FEATURE] Redis server is now able to test your memory for broken RAM.
Usage: ./redis-server --test-memory <megabytes>.
* [FEATURE] redis-benchmark backported from unstable. Pipelining, run selected
tests, and a few more features.
* [BUGFIX] utils/install_server.sh script now works on Redhat / Centos.
* [BUGFIX] Minor fix to redis-cli (github issue #306).
What's new in Redis 2.4.8
=========================
UPGRADE URGENCY: moderate if you don't experience any of the fixed problems.
* [BUGFIX] Make install now uses cp -f to avoid 'text file busy' errors.
* [BUGFIX] redis-check-aof is now large files safe also on 32 bit systems.
* [BUGFIX] Issue #327 fixed: maxmemory and replication now work much better.
* [BUGFIX] Now HINCRBY can detect overflows too. Fix for issue #330.
* [BUGFIX] Fixed compilation with latest clang.
* [BUGFIX] Fixed handling of empty sorted sets produced in RDB by
very old Redis versions (1.2.x).
What's new in Redis 2.4.7
=========================
UPGRADE URGENCY: low/moderate if you don't experience any of the fixed problems.
* [BUGFIX] Fixed false positive in issue #141 regression test.
* [BUGFIX] Slave should not expire keys when loading an RDB after a SYNC.
* [BUGFIX] Don't increment stats for key misses / hits when key is written.
* [BUGFIX] sds.c library now don't allocate more than 1MB ahead.
* 32 bit instances without a maxmemory set now get a default limit of 3.5GB with
maxmemory-policy set to noeviction.
* Better crash report on crash (containing current client and command arguments).
What's new in Redis 2.4.6
=========================
* [BUGFIX] Fixed issue #141 part 1: Possible protocol desyncs when clients send
wrong protocol is now fixed. (See issue 141 for more details)
* [BUGFIX] Fixed issue #141 part 2: Connection of multiple slaves used to result
from time to time into corrupted protocol send to slaves connected
after the first one. (See issue 141 for more details)
* [BUGFIX] Do not propagate DEBUG LOADAOF.
* New INFO contains information such as ip/port/state for every conneced slave.
* Show GCC version in INFO output.
What's new in Redis 2.4.5
=========================
* [BUGFIX] Fixed a ZUNIONSTORE/ZINTERSTORE bug that can cause a NaN to be
inserted as a sorted set element score. This happens when one of the
elements has +inf/-inf score and the weight used is 0.
* [BUGFIX] Fixed memory leak in CLIENT INFO.
* [BUGFIX] Fixed a non critical SORT bug (Issue 224).
* [BUGFIX] Fixed a replication bug: now the timeout configuration is respected
during the connection with the master.
* --quiet option implemented in the Redis test.
What's new in Redis 2.4.4
=========================
* [BUGFIX] jemalloc upgraded to version 2.2.5, previous versions had a
potentially serious issue when allocating big memory areas, something that
Redis actually does. However we never received bug reports that appear
to be caused by jemalloc.
* [BUGFIX] DISCARD now clears DIRTY_CAS flag in the client. Now the next
transaction will not fail if the previous transaction used WATCH and
the key was touched.
* CLIENT LIST output modified to include the last command executed by clients.
* Better bug report on crash.
* Protocol errors are now logged for loglevel >= verbose.
* Two new INFO fields related to AOF, that can be useful when investigating
Redis issues.
What's new in Redis 2.4.3
=========================
* redis-cli now supports 'single quotes' style strings.
* It is possible to disable password auth with CONFIG SET.
* Some section of redis.conf better documented.
* Default timeout for client connections now is 0 (no timeout).
* I/O buffer length modified for better performances with big payloads.
* Fixed crash on SPARC due to improper alighment due to bad assumptions about data types size.
* CLIENT LIST output improved, code refactored.
* [BUGFIX] Max log message length set to 4k to avoid truncation in INFO output written in the log file after a crash.
* [BUGFIX] Close client connection when the query buffer reaches 1GB and log informaiton about the offending client, instead of crashing the instance when the query buffer reaches 2GB (for sds.c string overflow). This is related to issue #141 (github issues) and should fix the effect of this rare bug related to replication, but the cause is still not perfectly clear.
What's new in Redis 2.4.2
=========================
* [BUGFIX] Unix socket creation mask config directive fixed.
* [BUGFIX] Fixed a bug that forced Redis to continously rewrite the AOF file
when a manual BGREWRITEAOF was issued during a BGSAVE was
still in progress.
* [BUGFIX] Fixed a server crash resulting from bad handling of SLAVEOF NO ONE.
* [BUGFIX] Fixed a memory leak in redis-cli.
* Debian/Ubuntu Redis system-wide installation script added under /utils.
What's new in Redis 2.4.1
=========================
* [BUGFIX] FLUSHALL was not replicated nor written into the Append Only File.
* [BUGFIX] FLUSHALL now only performs a sync SAVE if there is at least
one save point configured.
What's new in Redis 2.4.0
=========================
* [BUGFIX] redis-cli segfault with single numerical argument fixed.
* [BUGFIX] OpenBSD compilation problem fixed.
* [BUGFIX] More robust Redis test, with better random port selection.
* [BUGFIX] Fix for bug #128 about the RENAME command.
* [BUGFIX] Fixed Issue #131. stime/utime reported in INFO was inverted.
* [BUGFIX] Unlink Unix socket file on shutdown.
* [BUGFIX] AUTH now returns error if no password is set on the server.
* [BUGFIX] Exit with Fatal error at startup on RDB loading errors.
* redis-check-dump: RDB version 2 now supported.
* More informative error when DEBUG RELOAD fails.
* Added a config directive for a Unix socket mask.
* CONFIG SET/GET for loglevel.
What's new in Redis 2.3.11 (2.4 Release Candidate 8)
====================================================
* [BUGFIX] Fixed a rare but possible AOF race condition that could result into
duplicated commands inside the AOF.
* [BUGFIX] Fixed issue 620, don't segfault on corrupted (by hand) AOF.
* [BUGFIX] Fixed compilation on Mac/PPC.
* [BUGFIX] Don't replicate SAVE.
* LRANGE optimization may drastically improve performances when querying the
final part of a long list.
* redis-cli now implements a --latency mode to monitory Redis delay.
* Hash type settings removed from INFO (same info is available via config GET)
* Include port number on error when can't bind.
* AOF fsync is now performed in background when fsync policy is 'everysec'.
* AOF performances improved moving in background a possibly slow close(2) call.
* AOF protocol synthesis speedup.
What's new in Redis 2.3.10 (2.4 Release Candidate 7)
====================================================
* [BUGFIX] Fixed issue 593 (BRPOPLPUSH related crash).
* [BUGFIX] Fixed an issue with the networking layer that may prevent Redis from sending the whole reply back to client under extreme conditions.
What's new in Redis 2.3.9 (2.4 Release Candidate 6)
===================================================
* [BUGFIX] Fixed a bug with the automatic AOF rewrite causing continuous
rewrites for AOF files bigger than 4 GB.
* New maxmemory tests.
What's new in Redis 2.3.8 (2.4 Release Candidate 5)
===================================================
Compared to Redis 2.3.7 (RC4) there are the following changes:
* [BUGFIX] HDEL: Abort deleting fields when hash is removed.
* [BUGFIX] Fix adding bulk reply when getcwd fails.
WHAT'S NEW IN REDIS 2.4 compared to the 2.2 version?
====================================================
* Specially encoded sorted sets, now small sorted sets will use little memory.
* Native persistence of specially encoded data types (ziplists, zipmaps,
intsets). Many data sets will be saved and loaded an order of magnitude
faster.
* Variadic versions of commands: SADD, HDEL, SREM, ZREM, ZADD, L/RPUSH.
* Jemalloc support (enabled by default for Linux build) in order to
avoid fragmentation issues.
* Reduced memory usage while saving.
* More info fields (peak memory, fork time, ...)
* OBJECT command for objects introspection.
* CLIENT command for clients introspection.
* Non blocking slave -> master connection.
* Better redis-cli connection handling. New redis-cli features.
* Better redis-benchmark, now able to benchmark user provided commands.
* Colorized Make.
* VM deprecated. Still supported but with a big warning... don't use it.
* Many speed optimizations and bug fixes.
Credits: Where not specified the implementation and design are done by
Salvatore Sanfilippo and Pieter Noordhuis. Thanks to VMware for making all
this possible. Also many thanks to all the other contributors and the amazing
community we have.
Cheers,
Salvatore
+1 -1
View File
@@ -1 +1 @@
Please check https://github.com/antirez/redis/issues
Plese check http://code.google.com/p/redis/issues/list
+5 -28
View File
@@ -1,36 +1,13 @@
Note: by contributing code to the Redis project in any form, including sending
a pull request via Github, a code fragment or patch via private email or
public discussion groups, you agree to release your code under the terms
of the BSD license that you can find in the COPYING file included in the Redis
source distribution. You will include BSD license in the COPYING file within
each source file that you contribute.
1. Enter irc.freenode.org #redis and start talking with 'antirez' and/or 'pietern' to check if there is interest for such a feature and to understand the probability of it being merged. We'll try hard to keep Redis simple... so you'll likely encounter an high resistence.
# IMPORTANT: HOW TO USE REDIS GITHUB ISSUES
2. Drop a message to the Redis Google Group with a proposal of semantics/API.
* Github issues SHOULD ONLY BE USED to report bugs, and for DETAILED feature
requests. Everything else belongs to the Redis Google Group.
3. If steps 1 and 2 are ok, use the following procedure to submit a patch:
PLEASE DO NOT POST GENERAL QUESTIONS that are not about bugs or suspected
bugs in the Github issues system. We'll be very happy to help you and provide
all the support in the Redis Google Group.
Redis Google Group address:
https://groups.google.com/forum/?fromgroups#!forum/redis-db
# How to provide a patch for a new feature
1. If it is a major feature or a semantical change, write an RCP (Redis Change Proposal). Check the documentation here: https://github.com/redis/redis-rcp
2. If in step 1 you get an acknowledge from the project leaders, use the
following procedure to submit a patch:
a. Fork Redis on github ( http://help.github.com/fork-a-repo/ )
a. Fork Redis on github
b. Create a topic branch (git checkout -b my_branch)
c. Push to your branch (git push origin my_branch)
d. Initiate a pull request on github ( http://help.github.com/send-pull-requests/ )
d. Create an issue in the Redis google code site with a link to your patch
e. Done :)
For minor fixes just open a pull request on Github.
Thanks!
+1 -1
View File
@@ -1,4 +1,4 @@
Copyright (c) 2006-2014, Salvatore Sanfilippo
Copyright (c) 2006-2009, Salvatore Sanfilippo
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+1 -1
View File
@@ -1 +1 @@
See README
Please check the README file.
-67
View File
@@ -1,67 +0,0 @@
[Note: this is the Redis manifesto, for general information about
installing and running Redis read the README file instead.]
Redis Manifesto
===============
1 - A DSL for Abstract Data Types. Redis is a DSL (Domain Specific Language)
that manipulates abstract data types and implemented as a TCP daemon.
Commands manipulate a key space where keys are binary-safe strings and
values are different kinds of abstract data types. Every data type
represents an abstract version of a fundamental data structure. For instance
Redis Lists are an abstract representation of linked lists. In Redis, the
essence of a data type isn't just the kind of operations that the data types
support, but also the space and time complexity of the data type and the
operations performed upon it.
2 - Memory storage is #1. The Redis data set, composed of defined key-value
pairs, is primarily stored in the computer's memory. The amount of memory in
all kinds of computers, including entry-level servers, is increasing
significantly each year. Memory is fast, and allows Redis to have very
predictable performance. Datasets composed of 10k or 40 millions keys will
perform similarly. Complex data types like Redis Sorted Sets are easy to
implement and manipulate in memory with good performance, making Redis very
simple. Redis will continue to explore alternative options (where data can
be optionally stored on disk, say) but the main goal of the project remains
the development of an in-memory database.
3 - Fundamental data structures for a fundamental API. The Redis API is a direct
consequence of fundamental data structures. APIs can often be arbitrary but
not an API that resembles the nature of fundamental data structures. If we
ever meet intelligent life forms from another part of the universe, they'll
likely know, understand and recognize the same basic data structures we have
in our computer science books. Redis will avoid intermediate layers in API,
so that the complexity is obvious and more complex operations can be
performed as the sum of the basic operations.
4 - Code is like a poem; it's not just something we write to reach some
practical result. Sometimes people that are far from the Redis philosophy
suggest using other code written by other authors (frequently in other
languages) in order to implement something Redis currently lacks. But to us
this is like if Shakespeare decided to end Enrico IV using the Paradiso from
the Divina Commedia. Is using any external code a bad idea? Not at all. Like
in "One Thousand and One Nights" smaller self contained stories are embedded
in a bigger story, we'll be happy to use beautiful self contained libraries
when needed. At the same time, when writing the Redis story we're trying to
write smaller stories that will fit in to other code.
5 - We're against complexity. We believe designing systems is a fight against
complexity. We'll accept to fight the complexity when it's worthwhile but
we'll try hard to recognize when a small feature is not worth 1000s of lines
of code. Most of the time the best way to fight complexity is by not
creating it at all.
6 - Two levels of API. The Redis API has two levels: 1) a subset of the API fits
naturally into a distributed version of Redis and 2) a more complex API that
supports multi-key operations. Both are useful if used judiciously but
there's no way to make the more complex multi-keys API distributed in an
opaque way without violating our other principles. We don't want to provide
the illusion of something that will work magically when actually it can't in
all cases. Instead we'll provide commands to quickly migrate keys from one
instance to another to perform multi-key operations and expose the tradeoffs
to the user.
7 - We optimize for joy. We believe writing code is a lot of hard work, and the
only way it can be worth is by enjoying it. When there is no longer joy in
writing code, the best thing to do is stop. To prevent this, we'll avoid
taking paths that will make Redis less of a joy to develop.
+18 -4
View File
@@ -1,11 +1,25 @@
# Top level makefile, the real shit is at src/Makefile
default: all
TARGETS=32bit noopt test
.DEFAULT:
all:
cd src && $(MAKE) $@
install:
install: dummy
cd src && $(MAKE) $@
.PHONY: install
clean:
cd src && $(MAKE) $@
cd deps/hiredis && $(MAKE) $@
cd deps/linenoise && $(MAKE) $@
-(cd deps/jemalloc && $(MAKE) distclean)
distclean: clean
$(TARGETS):
cd src && $(MAKE) $@
src/help.h:
@./utils/generate-command-help.rb > $@
dummy:
+12 -52
View File
@@ -7,13 +7,6 @@ documentation at http://redis.io
Building Redis
--------------
Redis can be compiled and used on Linux, OSX, OpenBSD, NetBSD, FreeBSD.
We support big endian and little endian architectures.
It may compile on Solaris derived systems (for instance SmartOS) but our
support for this platform is "best effort" and Redis is not guaranteed to
work as well as in Linux, OSX, and *BSD there.
It is as simple as:
% make
@@ -26,37 +19,25 @@ After building Redis is a good idea to test it, using:
% make test
Fixing problems building 32 bit binaries
---------
If after building Redis with a 32 bit target you need to rebuild it
with a 64 bit target, or the other way around, you need to perform a
"make distclean" in the root directory of the Redis distribution.
In case of build errors when trying to build a 32 bit binary of Redis, try
the following steps:
* Install the packages libc6-dev-i386 (also try g++-multilib).
* Try using the following command line instead of "make 32bit":
make CFLAGS="-m32 -march=native" LDFLAGS="-m32"
NOTE: if after building Redis with a 32 bit target you need to rebuild it
with a 64 bit target you need to perform a "make clean" in the root
directory of the Redis distribution.
Allocator
---------
Selecting a non-default memory allocator when building Redis is done by setting
the `MALLOC` environment variable. Redis is compiled and linked against libc
malloc by default, with the exception of jemalloc being the default on Linux
systems. This default was picked because jemalloc has proven to have fewer
fragmentation problems than libc malloc.
By default Redis compiles and links against jemalloc under Linux, since
glibc malloc() has memory fragmentation problems.
To force compiling against libc malloc, use:
To force a libc malloc() build use:
% make MALLOC=libc
% make FORCE_LIBC_MALLOC=yes
To compile against jemalloc on Mac OS X systems, use:
In all the other non Linux systems the libc malloc() is used by default.
% make MALLOC=jemalloc
On Mac OS X you can force a jemalloc based build using the following:
% make USE_JEMALLOC=yes
Verbose build
-------------
@@ -80,15 +61,6 @@ parameter (the path of the configuration file):
% cd src
% ./redis-server /path/to/redis.conf
It is possible to alter the Redis configuration passing parameters directly
as options using the command line. Examples:
% ./redis-server --port 9999 --slaveof 127.0.0.1 6379
% ./redis-server /etc/redis/6379.conf --loglevel debug
All the options in redis.conf are also supported as options using the command
line, with exactly the same name.
Playing with Redis
------------------
@@ -130,7 +102,7 @@ it the proper way for a production system, we have a script doing this
for Ubuntu and Debian systems:
% cd utils
% ./install_server.sh
% ./install_server
The script will ask you a few questions and will setup everything you need
to run Redis properly as a background daemon that will start again on
@@ -139,16 +111,4 @@ system reboots.
You'll be able to stop and start Redis using the script named
/etc/init.d/redis_<portnumber>, for instance /etc/init.d/redis_6379.
Code contributions
---
Note: by contributing code to the Redis project in any form, including sending
a pull request via Github, a code fragment or patch via private email or
public discussion groups, you agree to release your code under the terms
of the BSD license that you can find in the COPYING file included in the Redis
source distribution.
Please see the CONTRIBUTING file in this source distribution for more
information.
Enjoy!
+4
View File
@@ -0,0 +1,4 @@
This is a stable release! No TODO file here.
Please check the TODO file in the master branch on github.
https://github.com/antirez/redis/raw/master/TODO
-83
View File
@@ -1,83 +0,0 @@
# Redis dependency Makefile
uname_S:= $(shell sh -c 'uname -s 2>/dev/null || echo not')
CCCOLOR="\033[34m"
LINKCOLOR="\033[34;1m"
SRCCOLOR="\033[33m"
BINCOLOR="\033[37;1m"
MAKECOLOR="\033[32;1m"
ENDCOLOR="\033[0m"
default:
@echo "Explicit target required"
.PHONY: default
# Prerequisites target
.make-prerequisites:
@touch $@
# Clean everything when CFLAGS is different
ifneq ($(shell sh -c '[ -f .make-cflags ] && cat .make-cflags || echo none'), $(CFLAGS))
.make-cflags: distclean
-(echo "$(CFLAGS)" > .make-cflags)
.make-prerequisites: .make-cflags
endif
# Clean everything when LDFLAGS is different
ifneq ($(shell sh -c '[ -f .make-ldflags ] && cat .make-ldflags || echo none'), $(LDFLAGS))
.make-ldflags: distclean
-(echo "$(LDFLAGS)" > .make-ldflags)
.make-prerequisites: .make-ldflags
endif
distclean:
-(cd hiredis && $(MAKE) clean) > /dev/null || true
-(cd linenoise && $(MAKE) clean) > /dev/null || true
-(cd lua && $(MAKE) clean) > /dev/null || true
-(cd jemalloc && [ -f Makefile ] && $(MAKE) distclean) > /dev/null || true
-(rm -f .make-*)
.PHONY: distclean
hiredis: .make-prerequisites
@printf '%b %b\n' $(MAKECOLOR)MAKE$(ENDCOLOR) $(BINCOLOR)$@$(ENDCOLOR)
cd hiredis && $(MAKE) static
.PHONY: hiredis
linenoise: .make-prerequisites
@printf '%b %b\n' $(MAKECOLOR)MAKE$(ENDCOLOR) $(BINCOLOR)$@$(ENDCOLOR)
cd linenoise && $(MAKE)
.PHONY: linenoise
ifeq ($(uname_S),SunOS)
# Make isinf() available
LUA_CFLAGS= -D__C99FEATURES__=1
endif
LUA_CFLAGS+= -O2 -Wall -DLUA_ANSI -DENABLE_CJSON_GLOBAL -DREDIS_STATIC='' $(CFLAGS)
LUA_LDFLAGS+= $(LDFLAGS)
# lua's Makefile defines AR="ar rcu", which is unusual, and makes it more
# challenging to cross-compile lua (and redis). These defines make it easier
# to fit redis into cross-compilation environments, which typically set AR.
AR=ar
ARFLAGS=rcu
lua: .make-prerequisites
@printf '%b %b\n' $(MAKECOLOR)MAKE$(ENDCOLOR) $(BINCOLOR)$@$(ENDCOLOR)
cd lua/src && $(MAKE) all CFLAGS="$(LUA_CFLAGS)" MYLDFLAGS="$(LUA_LDFLAGS)" AR="$(AR) $(ARFLAGS)"
.PHONY: lua
JEMALLOC_CFLAGS= -std=gnu99 -Wall -pipe -g3 -O3 -funroll-loops $(CFLAGS)
JEMALLOC_LDFLAGS= $(LDFLAGS)
jemalloc: .make-prerequisites
@printf '%b %b\n' $(MAKECOLOR)MAKE$(ENDCOLOR) $(BINCOLOR)$@$(ENDCOLOR)
cd jemalloc && ./configure --with-jemalloc-prefix=je_ --enable-cc-silence CFLAGS="$(JEMALLOC_CFLAGS)" LDFLAGS="$(JEMALLOC_LDFLAGS)"
cd jemalloc && $(MAKE) CFLAGS="$(JEMALLOC_CFLAGS)" LDFLAGS="$(JEMALLOC_LDFLAGS)" lib/libjemalloc.a
.PHONY: jemalloc
+1 -1
View File
@@ -1,5 +1,5 @@
/hiredis-test
/examples/hiredis-example*
/hiredis-example*
/*.o
/*.so
/*.dylib
-6
View File
@@ -1,6 +0,0 @@
language: c
compiler:
- gcc
- clang
script: make && make check
-8
View File
@@ -1,11 +1,3 @@
### 0.11.0
* Increase the maximum multi-bulk reply depth to 7.
* Increase the read buffer size from 2k to 16k.
* Use poll(2) instead of select(2) to support large fds (>= 1024).
### 0.10.1
* Makefile overhaul. Important to check out if you override one or more
+24 -42
View File
@@ -4,24 +4,11 @@
# This file is released under the BSD license, see the COPYING file
OBJ=net.o hiredis.o sds.o async.o
EXAMPLES=hiredis-example hiredis-example-libevent hiredis-example-libev
TESTS=hiredis-test
BINS=hiredis-example hiredis-test
LIBNAME=libhiredis
HIREDIS_MAJOR=0
HIREDIS_MINOR=11
# redis-server configuration used for testing
REDIS_PORT=56379
REDIS_SERVER=redis-server
define REDIS_TEST_CONFIG
daemonize yes
pidfile /tmp/hiredis-test-redis.pid
port $(REDIS_PORT)
bind 127.0.0.1
unixsocket /tmp/hiredis-test-redis.sock
endef
export REDIS_TEST_CONFIG
HIREDIS_MINOR=10
# Fallback to gcc when $CC is not in $PATH.
CC:=$(shell sh -c 'type $(CC) >/dev/null 2>/dev/null && echo $(CC) || echo gcc')
@@ -54,11 +41,12 @@ ifeq ($(uname_S),Darwin)
DYLIB_MAKE_CMD=$(CC) -shared -Wl,-install_name,$(DYLIB_MINOR_NAME) -o $(DYLIBNAME) $(LDFLAGS)
endif
all: $(DYLIBNAME)
all: $(DYLIBNAME) $(BINS)
# Deps (use make dep to generate this)
net.o: net.c fmacros.h net.h hiredis.h
async.o: async.c async.h hiredis.h sds.h dict.c dict.h
example.o: example.c hiredis.h
hiredis.o: hiredis.c fmacros.h hiredis.h net.h sds.h
sds.o: sds.c sds.h
test.o: test.c hiredis.h
@@ -73,44 +61,36 @@ dynamic: $(DYLIBNAME)
static: $(STLIBNAME)
# Binaries:
hiredis-example-libevent: examples/example-libevent.c adapters/libevent.h $(STLIBNAME)
$(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. $< -levent $(STLIBNAME)
hiredis-example-libevent: example-libevent.c adapters/libevent.h $(STLIBNAME)
$(CC) -o $@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -levent example-libevent.c $(STLIBNAME)
hiredis-example-libev: examples/example-libev.c adapters/libev.h $(STLIBNAME)
$(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. $< -lev $(STLIBNAME)
hiredis-example-libev: example-libev.c adapters/libev.h $(STLIBNAME)
$(CC) -o $@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -lev example-libev.c $(STLIBNAME)
ifndef AE_DIR
hiredis-example-ae:
@echo "Please specify AE_DIR (e.g. <redis repository>/src)"
@false
else
hiredis-example-ae: examples/example-ae.c adapters/ae.h $(STLIBNAME)
$(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. -I$(AE_DIR) $< $(AE_DIR)/ae.o $(AE_DIR)/zmalloc.o $(AE_DIR)/../deps/jemalloc/lib/libjemalloc.a -pthread $(STLIBNAME)
hiredis-example-ae: example-ae.c adapters/ae.h $(STLIBNAME)
$(CC) -o $@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I$(AE_DIR) $(AE_DIR)/ae.o $(AE_DIR)/zmalloc.o example-ae.c $(STLIBNAME)
endif
ifndef LIBUV_DIR
hiredis-example-libuv:
@echo "Please specify LIBUV_DIR (e.g. ../libuv/)"
@false
else
hiredis-example-libuv: examples/example-libuv.c adapters/libuv.h $(STLIBNAME)
$(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. -I$(LIBUV_DIR)/include $< $(LIBUV_DIR)/.libs/libuv.a -lpthread $(STLIBNAME)
endif
hiredis-example: examples/example.c $(STLIBNAME)
$(CC) -o examples/$@ $(REAL_CFLAGS) $(REAL_LDFLAGS) -I. $< $(STLIBNAME)
examples: $(EXAMPLES)
hiredis-test: test.o $(STLIBNAME)
hiredis-%: %.o $(STLIBNAME)
$(CC) -o $@ $(REAL_LDFLAGS) $< $(STLIBNAME)
test: hiredis-test
./hiredis-test
check: hiredis-test
@echo "$$REDIS_TEST_CONFIG" | $(REDIS_SERVER) -
./hiredis-test -h 127.0.0.1 -p $(REDIS_PORT) -s /tmp/hiredis-test-redis.sock || \
echo \
"daemonize yes\n" \
"pidfile /tmp/hiredis-test-redis.pid\n" \
"port 56379\n" \
"bind 127.0.0.1\n" \
"unixsocket /tmp/hiredis-test-redis.sock" \
| redis-server -
./hiredis-test -h 127.0.0.1 -p 56379 -s /tmp/hiredis-test-redis.sock || \
( kill `cat /tmp/hiredis-test-redis.pid` && false )
kill `cat /tmp/hiredis-test-redis.pid`
@@ -118,15 +98,17 @@ check: hiredis-test
$(CC) -std=c99 -pedantic -c $(REAL_CFLAGS) $<
clean:
rm -rf $(DYLIBNAME) $(STLIBNAME) $(TESTS) examples/hiredis-example* *.o *.gcda *.gcno *.gcov
rm -rf $(DYLIBNAME) $(STLIBNAME) $(BINS) hiredis-example* *.o *.gcda *.gcno *.gcov
dep:
$(CC) -MM *.c
# Installation related variables and target
PREFIX?=/usr/local
INSTALL_INCLUDE_PATH= $(PREFIX)/include/hiredis
INSTALL_LIBRARY_PATH= $(PREFIX)/lib
INCLUDE_PATH?=include/hiredis
LIBRARY_PATH?=lib
INSTALL_INCLUDE_PATH= $(PREFIX)/$(INCLUDE_PATH)
INSTALL_LIBRARY_PATH= $(PREFIX)/$(LIBRARY_PATH)
ifeq ($(uname_S),SunOS)
INSTALL?= cp -r
+3 -35
View File
@@ -1,5 +1,3 @@
[![Build Status](https://travis-ci.org/redis/hiredis.png)](https://travis-ci.org/redis/hiredis)
# HIREDIS
Hiredis is a minimalistic C client library for the [Redis](http://redis.io/) database.
@@ -46,7 +44,7 @@ After trying to connect to Redis using `redisConnect` you should
check the `err` field to see if establishing the connection was successful:
redisContext *c = redisConnect("127.0.0.1", 6379);
if (c != NULL && c->err) {
if (c->err) {
printf("Error: %s\n", c->errstr);
// handle error
}
@@ -68,14 +66,14 @@ When you need to pass binary safe strings in a command, the `%b` specifier can b
used. Together with a pointer to the string, it requires a `size_t` length argument
of the string:
reply = redisCommand(context, "SET foo %b", value, (size_t) valuelen);
reply = redisCommand(context, "SET foo %b", value, valuelen);
Internally, Hiredis splits the command in different arguments and will
convert it to the protocol used to communicate with Redis.
One or more spaces separates arguments, so you can use the specifiers
anywhere in an argument:
reply = redisCommand(context, "SET key:%s %s", myid, value);
reply = redisCommand("SET key:%s %s", myid, value);
### Using replies
@@ -322,10 +320,6 @@ The reply parsing API consists of the following functions:
int redisReaderFeed(redisReader *reader, const char *buf, size_t len);
int redisReaderGetReply(redisReader *reader, void **reply);
The same set of functions are used internally by hiredis when creating a
normal Redis context, the above API just exposes it to the user for a direct
usage.
### Usage
The function `redisReaderCreate` creates a `redisReader` structure that holds a
@@ -339,9 +333,6 @@ and a reply object (as described above) via `void **reply`. The returned status
can be either `REDIS_OK` or `REDIS_ERR`, where the latter means something went
wrong (either a protocol error, or an out of memory error).
The parser limits the level of nesting for multi bulk payloads to 7. If the
multi bulk nesting level is higher than this, the parser returns an error.
### Customizing replies
The function `redisReaderGetReply` creates `redisReply` and makes the function
@@ -355,29 +346,6 @@ immediately after creating the `redisReader`.
For example, [hiredis-rb](https://github.com/pietern/hiredis-rb/blob/master/ext/hiredis_ext/reader.c)
uses customized reply object functions to create Ruby objects.
### Reader max buffer
Both when using the Reader API directly or when using it indirectly via a
normal Redis context, the redisReader structure uses a buffer in order to
accumulate data from the server.
Usually this buffer is destroyed when it is empty and is larger than 16
kb in order to avoid wasting memory in unused buffers
However when working with very big payloads destroying the buffer may slow
down performances considerably, so it is possible to modify the max size of
an idle buffer changing the value of the `maxbuf` field of the reader structure
to the desired value. The special value of 0 means that there is no maximum
value for an idle buffer, so the buffer will never get freed.
For instance if you have a normal Redis context you can set the maximum idle
buffer to zero (unlimited) just with:
context->reader->maxbuf = 0;
This should be done only in order to maximize performances when working with
large payloads. The context should be set back to `REDIS_READER_MAX_BUF` again
as soon as possible in order to prevent allocation of useless memory.
## AUTHORS
Hiredis was written by Salvatore Sanfilippo (antirez at gmail) and
-30
View File
@@ -1,33 +1,3 @@
/*
* Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of Redis nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* 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.
*/
#ifndef __HIREDIS_AE_H__
#define __HIREDIS_AE_H__
#include <sys/types.h>
-30
View File
@@ -1,33 +1,3 @@
/*
* Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of Redis nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* 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.
*/
#ifndef __HIREDIS_LIBEV_H__
#define __HIREDIS_LIBEV_H__
#include <stdlib.h>
-30
View File
@@ -1,33 +1,3 @@
/*
* Copyright (c) 2010-2011, Pieter Noordhuis <pcnoordhuis at gmail dot com>
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of Redis nor the names of its contributors may be used
* to endorse or promote products derived from this software without
* specific prior written permission.
*
* 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.
*/
#ifndef __HIREDIS_LIBEVENT_H__
#define __HIREDIS_LIBEVENT_H__
#include <event.h>
-121
View File
@@ -1,121 +0,0 @@
#ifndef __HIREDIS_LIBUV_H__
#define __HIREDIS_LIBUV_H__
#include <uv.h>
#include "../hiredis.h"
#include "../async.h"
#include <string.h>
typedef struct redisLibuvEvents {
redisAsyncContext* context;
uv_poll_t handle;
int events;
} redisLibuvEvents;
int redisLibuvAttach(redisAsyncContext*, uv_loop_t*);
static void redisLibuvPoll(uv_poll_t* handle, int status, int events) {
redisLibuvEvents* p = (redisLibuvEvents*)handle->data;
if (status != 0) {
return;
}
if (events & UV_READABLE) {
redisAsyncHandleRead(p->context);
}
if (events & UV_WRITABLE) {
redisAsyncHandleWrite(p->context);
}
}
static void redisLibuvAddRead(void *privdata) {
redisLibuvEvents* p = (redisLibuvEvents*)privdata;
p->events |= UV_READABLE;
uv_poll_start(&p->handle, p->events, redisLibuvPoll);
}
static void redisLibuvDelRead(void *privdata) {
redisLibuvEvents* p = (redisLibuvEvents*)privdata;
p->events &= ~UV_READABLE;
if (p->events) {
uv_poll_start(&p->handle, p->events, redisLibuvPoll);
} else {
uv_poll_stop(&p->handle);
}
}
static void redisLibuvAddWrite(void *privdata) {
redisLibuvEvents* p = (redisLibuvEvents*)privdata;
p->events |= UV_WRITABLE;
uv_poll_start(&p->handle, p->events, redisLibuvPoll);
}
static void redisLibuvDelWrite(void *privdata) {
redisLibuvEvents* p = (redisLibuvEvents*)privdata;
p->events &= ~UV_WRITABLE;
if (p->events) {
uv_poll_start(&p->handle, p->events, redisLibuvPoll);
} else {
uv_poll_stop(&p->handle);
}
}
static void on_close(uv_handle_t* handle) {
redisLibuvEvents* p = (redisLibuvEvents*)handle->data;
free(p);
}
static void redisLibuvCleanup(void *privdata) {
redisLibuvEvents* p = (redisLibuvEvents*)privdata;
uv_close((uv_handle_t*)&p->handle, on_close);
}
static int redisLibuvAttach(redisAsyncContext* ac, uv_loop_t* loop) {
redisContext *c = &(ac->c);
if (ac->ev.data != NULL) {
return REDIS_ERR;
}
ac->ev.addRead = redisLibuvAddRead;
ac->ev.delRead = redisLibuvDelRead;
ac->ev.addWrite = redisLibuvAddWrite;
ac->ev.delWrite = redisLibuvDelWrite;
ac->ev.cleanup = redisLibuvCleanup;
redisLibuvEvents* p = (redisLibuvEvents*)malloc(sizeof(*p));
if (!p) {
return REDIS_ERR;
}
memset(p, 0, sizeof(*p));
if (uv_poll_init(loop, &p->handle, c->fd) != 0) {
return REDIS_ERR;
}
ac->ev.data = p;
p->handle.data = p;
p->context = ac;
return REDIS_OK;
}
#endif
+20 -77
View File
@@ -62,8 +62,7 @@ void __redisAppendCommand(redisContext *c, char *cmd, size_t len);
/* Functions managing dictionary of callbacks for pub/sub. */
static unsigned int callbackHash(const void *key) {
return dictGenHashFunction((const unsigned char *)key,
sdslen((const sds)key));
return dictGenHashFunction((unsigned char*)key,sdslen((char*)key));
}
static void *callbackValDup(void *privdata, const void *src) {
@@ -77,8 +76,8 @@ static int callbackKeyCompare(void *privdata, const void *key1, const void *key2
int l1, l2;
((void) privdata);
l1 = sdslen((const sds)key1);
l2 = sdslen((const sds)key2);
l1 = sdslen((sds)key1);
l2 = sdslen((sds)key2);
if (l1 != l2) return 0;
return memcmp(key1,key2,l1) == 0;
}
@@ -103,12 +102,7 @@ static dictType callbackDict = {
};
static redisAsyncContext *redisAsyncInitialize(redisContext *c) {
redisAsyncContext *ac;
ac = realloc(c,sizeof(redisAsyncContext));
if (ac == NULL)
return NULL;
redisAsyncContext *ac = realloc(c,sizeof(redisAsyncContext));
c = &(ac->c);
/* The regular connect functions will always set the flag REDIS_CONNECTED.
@@ -148,45 +142,15 @@ static void __redisAsyncCopyError(redisAsyncContext *ac) {
}
redisAsyncContext *redisAsyncConnect(const char *ip, int port) {
redisContext *c;
redisAsyncContext *ac;
c = redisConnectNonBlock(ip,port);
if (c == NULL)
return NULL;
ac = redisAsyncInitialize(c);
if (ac == NULL) {
redisFree(c);
return NULL;
}
__redisAsyncCopyError(ac);
return ac;
}
redisAsyncContext *redisAsyncConnectBind(const char *ip, int port,
const char *source_addr) {
redisContext *c = redisConnectBindNonBlock(ip,port,source_addr);
redisContext *c = redisConnectNonBlock(ip,port);
redisAsyncContext *ac = redisAsyncInitialize(c);
__redisAsyncCopyError(ac);
return ac;
}
redisAsyncContext *redisAsyncConnectUnix(const char *path) {
redisContext *c;
redisAsyncContext *ac;
c = redisConnectUnixNonBlock(path);
if (c == NULL)
return NULL;
ac = redisAsyncInitialize(c);
if (ac == NULL) {
redisFree(c);
return NULL;
}
redisContext *c = redisConnectUnixNonBlock(path);
redisAsyncContext *ac = redisAsyncInitialize(c);
__redisAsyncCopyError(ac);
return ac;
}
@@ -218,9 +182,6 @@ static int __redisPushCallback(redisCallbackList *list, redisCallback *source) {
/* Copy callback from stack to heap */
cb = malloc(sizeof(*cb));
if (cb == NULL)
return REDIS_ERR_OOM;
if (source != NULL) {
memcpy(cb,source,sizeof(*cb));
cb->next = NULL;
@@ -399,7 +360,7 @@ static int __redisGetSubscribeCallback(redisAsyncContext *ac, redisReply *reply,
void redisProcessCallbacks(redisAsyncContext *ac) {
redisContext *c = &(ac->c);
redisCallback cb = {NULL, NULL, NULL};
redisCallback cb;
void *reply = NULL;
int status;
@@ -412,11 +373,6 @@ void redisProcessCallbacks(redisAsyncContext *ac) {
return;
}
/* If monitor mode, repush callback */
if(c->flags & REDIS_MONITORING) {
__redisPushCallback(&ac->replies,&cb);
}
/* When the connection is not being disconnected, simply stop
* trying to get replies and wait for the next loop tick. */
break;
@@ -425,31 +381,22 @@ void redisProcessCallbacks(redisAsyncContext *ac) {
/* Even if the context is subscribed, pending regular callbacks will
* get a reply before pub/sub messages arrive. */
if (__redisShiftCallback(&ac->replies,&cb) != REDIS_OK) {
/*
* A spontaneous reply in a not-subscribed context can be the error
* reply that is sent when a new connection exceeds the maximum
* number of allowed connections on the server side.
*
* This is seen as an error instead of a regular reply because the
* server closes the connection after sending it.
*
* To prevent the error from being overwritten by an EOF error the
* connection is closed here. See issue #43.
*
* Another possibility is that the server is loading its dataset.
* In this case we also want to close the connection, and have the
* user wait until the server is ready to take our request.
*/
if (((redisReply*)reply)->type == REDIS_REPLY_ERROR) {
/* A spontaneous reply in a not-subscribed context can only be the
* error reply that is sent when a new connection exceeds the
* maximum number of allowed connections on the server side. This
* is seen as an error instead of a regular reply because the
* server closes the connection after sending it. To prevent the
* error from being overwritten by an EOF error the connection is
* closed here. See issue #43. */
if ( !(c->flags & REDIS_SUBSCRIBED) && ((redisReply*)reply)->type == REDIS_REPLY_ERROR ) {
c->err = REDIS_ERR_OTHER;
snprintf(c->errstr,sizeof(c->errstr),"%s",((redisReply*)reply)->str);
__redisAsyncDisconnect(ac);
return;
}
/* No more regular callbacks and no errors, the context *must* be subscribed or monitoring. */
assert((c->flags & REDIS_SUBSCRIBED || c->flags & REDIS_MONITORING));
if(c->flags & REDIS_SUBSCRIBED)
__redisGetSubscribeCallback(ac,reply,&cb);
/* No more regular callbacks and no errors, the context *must* be subscribed. */
assert(c->flags & REDIS_SUBSCRIBED);
__redisGetSubscribeCallback(ac,reply,&cb);
}
if (cb.fn != NULL) {
@@ -481,7 +428,7 @@ void redisProcessCallbacks(redisAsyncContext *ac) {
static int __redisAsyncHandleConnect(redisAsyncContext *ac) {
redisContext *c = &(ac->c);
if (redisCheckSocketError(c) == REDIS_ERR) {
if (redisCheckSocketError(c,c->fd) == REDIS_ERR) {
/* Try again later when connect(2) is still in progress. */
if (errno == EINPROGRESS)
return REDIS_OK;
@@ -610,10 +557,6 @@ static int __redisAsyncCommand(redisAsyncContext *ac, redisCallbackFn *fn, void
/* (P)UNSUBSCRIBE does not have its own response: every channel or
* pattern that is unsubscribed will receive a message. This means we
* should not append a callback function for this command. */
} else if(strncasecmp(cstr,"monitor\r\n",9) == 0) {
/* Set monitor flag and push callback */
c->flags |= REDIS_MONITORING;
__redisPushCallback(&ac->replies,&cb);
} else {
if (c->flags & REDIS_SUBSCRIBED)
/* This will likely result in an error reply, but it needs to be
-1
View File
@@ -102,7 +102,6 @@ typedef struct redisAsyncContext {
/* Functions that proxy to hiredis */
redisAsyncContext *redisAsyncConnect(const char *ip, int port);
redisAsyncContext *redisAsyncConnectBind(const char *ip, int port, const char *source_addr);
redisAsyncContext *redisAsyncConnectUnix(const char *path);
int redisAsyncSetConnectCallback(redisAsyncContext *ac, redisConnectCallback *fn);
int redisAsyncSetDisconnectCallback(redisAsyncContext *ac, redisDisconnectCallback *fn);
@@ -2,10 +2,9 @@
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <hiredis.h>
#include <async.h>
#include <adapters/ae.h>
#include "hiredis.h"
#include "async.h"
#include "adapters/ae.h"
/* Put event loop in the global scope, so it can be explicitly stopped */
static aeEventLoop *loop;
@@ -22,22 +21,17 @@ void getCallback(redisAsyncContext *c, void *r, void *privdata) {
void connectCallback(const redisAsyncContext *c, int status) {
if (status != REDIS_OK) {
printf("Error: %s\n", c->errstr);
aeStop(loop);
return;
}
printf("Connected...\n");
}
void disconnectCallback(const redisAsyncContext *c, int status) {
if (status != REDIS_OK) {
printf("Error: %s\n", c->errstr);
aeStop(loop);
return;
}
printf("Disconnected...\n");
aeStop(loop);
}
int main (int argc, char **argv) {
@@ -50,7 +44,7 @@ int main (int argc, char **argv) {
return 1;
}
loop = aeCreateEventLoop(64);
loop = aeCreateEventLoop();
redisAeAttach(loop, c);
redisAsyncSetConnectCallback(c,connectCallback);
redisAsyncSetDisconnectCallback(c,disconnectCallback);
@@ -2,10 +2,9 @@
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <hiredis.h>
#include <async.h>
#include <adapters/libev.h>
#include "hiredis.h"
#include "async.h"
#include "adapters/libev.h"
void getCallback(redisAsyncContext *c, void *r, void *privdata) {
redisReply *reply = r;
@@ -2,10 +2,9 @@
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <hiredis.h>
#include <async.h>
#include <adapters/libevent.h>
#include "hiredis.h"
#include "async.h"
#include "adapters/libevent.h"
void getCallback(redisAsyncContext *c, void *r, void *privdata) {
redisReply *reply = r;
+6 -16
View File
@@ -2,24 +2,17 @@
#include <stdlib.h>
#include <string.h>
#include <hiredis.h>
#include "hiredis.h"
int main(int argc, char **argv) {
int main(void) {
unsigned int j;
redisContext *c;
redisReply *reply;
const char *hostname = (argc > 1) ? argv[1] : "127.0.0.1";
int port = (argc > 2) ? atoi(argv[2]) : 6379;
struct timeval timeout = { 1, 500000 }; // 1.5 seconds
c = redisConnectWithTimeout(hostname, port, timeout);
if (c == NULL || c->err) {
if (c) {
printf("Connection error: %s\n", c->errstr);
redisFree(c);
} else {
printf("Connection error: can't allocate redis context\n");
}
c = redisConnectWithTimeout((char*)"127.0.0.2", 6379, timeout);
if (c->err) {
printf("Connection error: %s\n", c->errstr);
exit(1);
}
@@ -34,7 +27,7 @@ int main(int argc, char **argv) {
freeReplyObject(reply);
/* Set a key using binary safe API */
reply = redisCommand(c,"SET %b %b", "bar", (size_t) 3, "hello", (size_t) 5);
reply = redisCommand(c,"SET %b %b", "bar", 3, "hello", 5);
printf("SET (binary API): %s\n", reply->str);
freeReplyObject(reply);
@@ -71,8 +64,5 @@ int main(int argc, char **argv) {
}
freeReplyObject(reply);
/* Disconnects and frees the context */
redisFree(c);
return 0;
}
-53
View File
@@ -1,53 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <hiredis.h>
#include <async.h>
#include <adapters/libuv.h>
void getCallback(redisAsyncContext *c, void *r, void *privdata) {
redisReply *reply = r;
if (reply == NULL) return;
printf("argv[%s]: %s\n", (char*)privdata, reply->str);
/* Disconnect after receiving the reply to GET */
redisAsyncDisconnect(c);
}
void connectCallback(const redisAsyncContext *c, int status) {
if (status != REDIS_OK) {
printf("Error: %s\n", c->errstr);
return;
}
printf("Connected...\n");
}
void disconnectCallback(const redisAsyncContext *c, int status) {
if (status != REDIS_OK) {
printf("Error: %s\n", c->errstr);
return;
}
printf("Disconnected...\n");
}
int main (int argc, char **argv) {
signal(SIGPIPE, SIG_IGN);
uv_loop_t* loop = uv_default_loop();
redisAsyncContext *c = redisAsyncConnect("127.0.0.1", 6379);
if (c->err) {
/* Let *c leak for now... */
printf("Error: %s\n", c->errstr);
return 1;
}
redisLibuvAttach(c,loop);
redisAsyncSetConnectCallback(c,connectCallback);
redisAsyncSetDisconnectCallback(c,disconnectCallback);
redisAsyncCommand(c, NULL, NULL, "SET key %b", argv[argc-1], strlen(argv[argc-1]));
redisAsyncCommand(c, getCallback, (char*)"end-1", "GET key");
uv_run(loop, UV_RUN_DEFAULT);
return 0;
}
+1 -9
View File
@@ -5,20 +5,12 @@
#define _BSD_SOURCE
#endif
#if defined(_AIX)
#define _ALL_SOURCE
#endif
#if defined(__sun__)
#define _POSIX_C_SOURCE 200112L
#elif defined(__linux__) || defined(__OpenBSD__) || defined(__NetBSD__)
#elif defined(__linux__)
#define _XOPEN_SOURCE 600
#else
#define _XOPEN_SOURCE
#endif
#if __APPLE__ && __MACH__
#define _OSX
#endif
#endif
+19 -91
View File
@@ -446,7 +446,7 @@ static int processMultiBulkItem(redisReader *r) {
long elements;
int root = 0;
/* Set error for nested multi bulks with depth > 7 */
/* Set error for nested multi bulks with depth > 2 */
if (r->ridx == 8) {
__redisReaderSetError(r,REDIS_ERR_PROTOCOL,
"No support for nested multi bulk replies with depth > 7");
@@ -564,7 +564,6 @@ redisReader *redisReaderCreate(void) {
r->errstr[0] = '\0';
r->fn = &defaultFunctions;
r->buf = sdsempty();
r->maxbuf = REDIS_READER_MAX_BUF;
if (r->buf == NULL) {
free(r);
return NULL;
@@ -591,8 +590,9 @@ int redisReaderFeed(redisReader *r, const char *buf, size_t len) {
/* Copy the provided buffer. */
if (buf != NULL && len >= 1) {
#if 0
/* Destroy internal buffer when it is empty and is quite large. */
if (r->len == 0 && r->maxbuf != 0 && sdsavail(r->buf) > r->maxbuf) {
if (r->len == 0 && sdsavail(r->buf) > 16*1024) {
sdsfree(r->buf);
r->buf = sdsempty();
r->pos = 0;
@@ -600,6 +600,7 @@ int redisReaderFeed(redisReader *r, const char *buf, size_t len) {
/* r->buf should not be NULL since we just free'd a larger one. */
assert(r->buf != NULL);
}
#endif
newbuf = sdscatlen(r->buf,buf,len);
if (newbuf == NULL) {
@@ -650,7 +651,7 @@ int redisReaderGetReply(redisReader *r, void **reply) {
/* Discard part of the buffer when we've consumed at least 1k, to avoid
* doing unnecessary calls to memmove() in sds.c. */
if (r->pos >= 1024) {
sdsrange(r->buf,r->pos,-1);
r->buf = sdsrange(r->buf,r->pos,-1);
r->pos = 0;
r->len = sdslen(r->buf);
}
@@ -917,7 +918,7 @@ err:
* %b represents a binary safe string
*
* When using %b you need to provide both the pointer to the string
* and the length in bytes as a size_t. Examples:
* and the length in bytes. Examples:
*
* len = redisFormatCommand(target, "GET %s", mykey);
* len = redisFormatCommand(target, "SET %s %b", mykey, myval, myvallen);
@@ -1010,122 +1011,58 @@ void redisFree(redisContext *c) {
free(c);
}
int redisFreeKeepFd(redisContext *c) {
int fd = c->fd;
c->fd = -1;
redisFree(c);
return fd;
}
/* Connect to a Redis instance. On error the field error in the returned
* context will be set to the return value of the error function.
* When no set of reply functions is given, the default set will be used. */
redisContext *redisConnect(const char *ip, int port) {
redisContext *c;
c = redisContextInit();
if (c == NULL)
return NULL;
redisContext *c = redisContextInit();
c->flags |= REDIS_BLOCK;
redisContextConnectTcp(c,ip,port,NULL);
return c;
}
redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv) {
redisContext *c;
c = redisContextInit();
if (c == NULL)
return NULL;
redisContext *redisConnectWithTimeout(const char *ip, int port, struct timeval tv) {
redisContext *c = redisContextInit();
c->flags |= REDIS_BLOCK;
redisContextConnectTcp(c,ip,port,&tv);
return c;
}
redisContext *redisConnectNonBlock(const char *ip, int port) {
redisContext *c;
c = redisContextInit();
if (c == NULL)
return NULL;
redisContext *c = redisContextInit();
c->flags &= ~REDIS_BLOCK;
redisContextConnectTcp(c,ip,port,NULL);
return c;
}
redisContext *redisConnectBindNonBlock(const char *ip, int port,
const char *source_addr) {
redisContext *c = redisContextInit();
c->flags &= ~REDIS_BLOCK;
redisContextConnectBindTcp(c,ip,port,NULL,source_addr);
return c;
}
redisContext *redisConnectUnix(const char *path) {
redisContext *c;
c = redisContextInit();
if (c == NULL)
return NULL;
redisContext *c = redisContextInit();
c->flags |= REDIS_BLOCK;
redisContextConnectUnix(c,path,NULL);
return c;
}
redisContext *redisConnectUnixWithTimeout(const char *path, const struct timeval tv) {
redisContext *c;
c = redisContextInit();
if (c == NULL)
return NULL;
redisContext *redisConnectUnixWithTimeout(const char *path, struct timeval tv) {
redisContext *c = redisContextInit();
c->flags |= REDIS_BLOCK;
redisContextConnectUnix(c,path,&tv);
return c;
}
redisContext *redisConnectUnixNonBlock(const char *path) {
redisContext *c;
c = redisContextInit();
if (c == NULL)
return NULL;
redisContext *c = redisContextInit();
c->flags &= ~REDIS_BLOCK;
redisContextConnectUnix(c,path,NULL);
return c;
}
redisContext *redisConnectFd(int fd) {
redisContext *c;
c = redisContextInit();
if (c == NULL)
return NULL;
c->fd = fd;
c->flags |= REDIS_BLOCK | REDIS_CONNECTED;
return c;
}
/* Set read/write timeout on a blocking socket. */
int redisSetTimeout(redisContext *c, const struct timeval tv) {
int redisSetTimeout(redisContext *c, struct timeval tv) {
if (c->flags & REDIS_BLOCK)
return redisContextSetTimeout(c,tv);
return REDIS_ERR;
}
/* Enable connection KeepAlive. */
int redisEnableKeepAlive(redisContext *c) {
if (redisKeepAlive(c, REDIS_KEEPALIVE_INTERVAL) != REDIS_OK)
return REDIS_ERR;
return REDIS_OK;
}
/* Use this function to handle a read event on the descriptor. It will try
* and read some bytes from the socket and feed them to the reply parser.
*
@@ -1141,7 +1078,7 @@ int redisBufferRead(redisContext *c) {
nread = read(c->fd,buf,sizeof(buf));
if (nread == -1) {
if ((errno == EAGAIN && !(c->flags & REDIS_BLOCK)) || (errno == EINTR)) {
if (errno == EAGAIN && !(c->flags & REDIS_BLOCK)) {
/* Try again later */
} else {
__redisSetError(c,REDIS_ERR_IO,NULL);
@@ -1178,7 +1115,7 @@ int redisBufferWrite(redisContext *c, int *done) {
if (sdslen(c->obuf) > 0) {
nwritten = write(c->fd,c->obuf,sdslen(c->obuf));
if (nwritten == -1) {
if ((errno == EAGAIN && !(c->flags & REDIS_BLOCK)) || (errno == EINTR)) {
if (errno == EAGAIN && !(c->flags & REDIS_BLOCK)) {
/* Try again later */
} else {
__redisSetError(c,REDIS_ERR_IO,NULL);
@@ -1189,7 +1126,7 @@ int redisBufferWrite(redisContext *c, int *done) {
sdsfree(c->obuf);
c->obuf = sdsempty();
} else {
sdsrange(c->obuf,nwritten,-1);
c->obuf = sdsrange(c->obuf,nwritten,-1);
}
}
}
@@ -1244,7 +1181,7 @@ int redisGetReply(redisContext *c, void **reply) {
* is used, you need to call redisGetReply yourself to retrieve
* the reply (or replies in pub/sub).
*/
int __redisAppendCommand(redisContext *c, const char *cmd, size_t len) {
int __redisAppendCommand(redisContext *c, char *cmd, size_t len) {
sds newbuf;
newbuf = sdscatlen(c->obuf,cmd,len);
@@ -1257,15 +1194,6 @@ int __redisAppendCommand(redisContext *c, const char *cmd, size_t len) {
return REDIS_OK;
}
int redisAppendFormattedCommand(redisContext *c, const char *cmd, size_t len) {
if (__redisAppendCommand(c, cmd, len) != REDIS_OK) {
return REDIS_ERR;
}
return REDIS_OK;
}
int redisvAppendCommand(redisContext *c, const char *format, va_list ap) {
char *cmd;
int len;
+5 -21
View File
@@ -36,8 +36,8 @@
#include <sys/time.h> /* for struct timeval */
#define HIREDIS_MAJOR 0
#define HIREDIS_MINOR 11
#define HIREDIS_PATCH 0
#define HIREDIS_MINOR 10
#define HIREDIS_PATCH 1
#define REDIS_ERR -1
#define REDIS_OK 0
@@ -76,9 +76,6 @@
/* Flag that is set when the async context has one or more subscriptions. */
#define REDIS_SUBSCRIBED 0x20
/* Flag that is set when monitor mode is active */
#define REDIS_MONITORING 0x40
#define REDIS_REPLY_STRING 1
#define REDIS_REPLY_ARRAY 2
#define REDIS_REPLY_INTEGER 3
@@ -86,10 +83,6 @@
#define REDIS_REPLY_STATUS 5
#define REDIS_REPLY_ERROR 6
#define REDIS_READER_MAX_BUF (1024*16) /* Default max unused reader buffer. */
#define REDIS_KEEPALIVE_INTERVAL 15 /* seconds */
#ifdef __cplusplus
extern "C" {
#endif
@@ -129,7 +122,6 @@ typedef struct redisReader {
char *buf; /* Read buffer */
size_t pos; /* Buffer cursor */
size_t len; /* Buffer length */
size_t maxbuf; /* Max length of unused buffer */
redisReadTask rstack[9];
int ridx; /* Index of current read task */
@@ -173,17 +165,13 @@ typedef struct redisContext {
} redisContext;
redisContext *redisConnect(const char *ip, int port);
redisContext *redisConnectWithTimeout(const char *ip, int port, const struct timeval tv);
redisContext *redisConnectWithTimeout(const char *ip, int port, struct timeval tv);
redisContext *redisConnectNonBlock(const char *ip, int port);
redisContext *redisConnectBindNonBlock(const char *ip, int port, const char *source_addr);
redisContext *redisConnectUnix(const char *path);
redisContext *redisConnectUnixWithTimeout(const char *path, const struct timeval tv);
redisContext *redisConnectUnixWithTimeout(const char *path, struct timeval tv);
redisContext *redisConnectUnixNonBlock(const char *path);
redisContext *redisConnectFd(int fd);
int redisSetTimeout(redisContext *c, const struct timeval tv);
int redisEnableKeepAlive(redisContext *c);
int redisSetTimeout(redisContext *c, struct timeval tv);
void redisFree(redisContext *c);
int redisFreeKeepFd(redisContext *c);
int redisBufferRead(redisContext *c);
int redisBufferWrite(redisContext *c, int *done);
@@ -194,10 +182,6 @@ int redisBufferWrite(redisContext *c, int *done);
int redisGetReply(redisContext *c, void **reply);
int redisGetReplyFromReader(redisContext *c, void **reply);
/* Write a formatted command to the output buffer. Use these functions in blocking mode
* to get a pipeline of commands. */
int redisAppendFormattedCommand(redisContext *c, const char *cmd, size_t len);
/* Write a command to the output buffer. Use these functions in blocking mode
* to get a pipeline of commands. */
int redisvAppendCommand(redisContext *c, const char *format, va_list ap);
+57 -160
View File
@@ -45,8 +45,6 @@
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <poll.h>
#include <limits.h>
#include "net.h"
#include "sds.h"
@@ -54,15 +52,8 @@
/* Defined in hiredis.c */
void __redisSetError(redisContext *c, int type, const char *str);
static void redisContextCloseFd(redisContext *c) {
if (c && c->fd >= 0) {
close(c->fd);
c->fd = -1;
}
}
static void __redisSetErrorFromErrno(redisContext *c, int type, const char *prefix) {
char buf[128] = { 0 };
char buf[128];
size_t len = 0;
if (prefix != NULL)
@@ -71,11 +62,11 @@ static void __redisSetErrorFromErrno(redisContext *c, int type, const char *pref
__redisSetError(c,type,buf);
}
static int redisSetReuseAddr(redisContext *c) {
static int redisSetReuseAddr(redisContext *c, int fd) {
int on = 1;
if (setsockopt(c->fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
__redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
redisContextCloseFd(c);
close(fd);
return REDIS_ERR;
}
return REDIS_OK;
@@ -87,24 +78,23 @@ static int redisCreateSocket(redisContext *c, int type) {
__redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
return REDIS_ERR;
}
c->fd = s;
if (type == AF_INET) {
if (redisSetReuseAddr(c) == REDIS_ERR) {
if (redisSetReuseAddr(c,s) == REDIS_ERR) {
return REDIS_ERR;
}
}
return REDIS_OK;
return s;
}
static int redisSetBlocking(redisContext *c, int blocking) {
static int redisSetBlocking(redisContext *c, int fd, int blocking) {
int flags;
/* Set the socket nonblocking.
* Note that fcntl(2) for F_GETFL and F_SETFL can't be
* interrupted by a signal. */
if ((flags = fcntl(c->fd, F_GETFL)) == -1) {
if ((flags = fcntl(fd, F_GETFL)) == -1) {
__redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_GETFL)");
redisContextCloseFd(c);
close(fd);
return REDIS_ERR;
}
@@ -113,135 +103,84 @@ static int redisSetBlocking(redisContext *c, int blocking) {
else
flags |= O_NONBLOCK;
if (fcntl(c->fd, F_SETFL, flags) == -1) {
if (fcntl(fd, F_SETFL, flags) == -1) {
__redisSetErrorFromErrno(c,REDIS_ERR_IO,"fcntl(F_SETFL)");
redisContextCloseFd(c);
close(fd);
return REDIS_ERR;
}
return REDIS_OK;
}
int redisKeepAlive(redisContext *c, int interval) {
int val = 1;
int fd = c->fd;
if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)) == -1){
__redisSetError(c,REDIS_ERR_OTHER,strerror(errno));
return REDIS_ERR;
}
val = interval;
#ifdef _OSX
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &val, sizeof(val)) < 0) {
__redisSetError(c,REDIS_ERR_OTHER,strerror(errno));
return REDIS_ERR;
}
#else
#ifndef __sun
val = interval;
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &val, sizeof(val)) < 0) {
__redisSetError(c,REDIS_ERR_OTHER,strerror(errno));
return REDIS_ERR;
}
val = interval/3;
if (val == 0) val = 1;
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &val, sizeof(val)) < 0) {
__redisSetError(c,REDIS_ERR_OTHER,strerror(errno));
return REDIS_ERR;
}
val = 3;
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &val, sizeof(val)) < 0) {
__redisSetError(c,REDIS_ERR_OTHER,strerror(errno));
return REDIS_ERR;
}
#endif
#endif
return REDIS_OK;
}
static int redisSetTcpNoDelay(redisContext *c) {
static int redisSetTcpNoDelay(redisContext *c, int fd) {
int yes = 1;
if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes)) == -1) {
if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &yes, sizeof(yes)) == -1) {
__redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(TCP_NODELAY)");
redisContextCloseFd(c);
close(fd);
return REDIS_ERR;
}
return REDIS_OK;
}
#define __MAX_MSEC (((LONG_MAX) - 999) / 1000)
static int redisContextWaitReady(redisContext *c, const struct timeval *timeout) {
struct pollfd wfd[1];
long msec;
msec = -1;
wfd[0].fd = c->fd;
wfd[0].events = POLLOUT;
static int redisContextWaitReady(redisContext *c, int fd, const struct timeval *timeout) {
struct timeval to;
struct timeval *toptr = NULL;
fd_set wfd;
/* Only use timeout when not NULL. */
if (timeout != NULL) {
if (timeout->tv_usec > 1000000 || timeout->tv_sec > __MAX_MSEC) {
__redisSetErrorFromErrno(c, REDIS_ERR_IO, NULL);
redisContextCloseFd(c);
return REDIS_ERR;
}
msec = (timeout->tv_sec * 1000) + ((timeout->tv_usec + 999) / 1000);
if (msec < 0 || msec > INT_MAX) {
msec = INT_MAX;
}
to = *timeout;
toptr = &to;
}
if (errno == EINPROGRESS) {
int res;
FD_ZERO(&wfd);
FD_SET(fd, &wfd);
if ((res = poll(wfd, 1, msec)) == -1) {
__redisSetErrorFromErrno(c, REDIS_ERR_IO, "poll(2)");
redisContextCloseFd(c);
return REDIS_ERR;
} else if (res == 0) {
errno = ETIMEDOUT;
__redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
redisContextCloseFd(c);
if (select(FD_SETSIZE, NULL, &wfd, NULL, toptr) == -1) {
__redisSetErrorFromErrno(c,REDIS_ERR_IO,"select(2)");
close(fd);
return REDIS_ERR;
}
if (redisCheckSocketError(c) != REDIS_OK)
if (!FD_ISSET(fd, &wfd)) {
errno = ETIMEDOUT;
__redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
close(fd);
return REDIS_ERR;
}
if (redisCheckSocketError(c, fd) != REDIS_OK)
return REDIS_ERR;
return REDIS_OK;
}
__redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
redisContextCloseFd(c);
close(fd);
return REDIS_ERR;
}
int redisCheckSocketError(redisContext *c) {
int redisCheckSocketError(redisContext *c, int fd) {
int err = 0;
socklen_t errlen = sizeof(err);
if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1) {
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1) {
__redisSetErrorFromErrno(c,REDIS_ERR_IO,"getsockopt(SO_ERROR)");
close(fd);
return REDIS_ERR;
}
if (err) {
errno = err;
__redisSetErrorFromErrno(c,REDIS_ERR_IO,NULL);
close(fd);
return REDIS_ERR;
}
return REDIS_OK;
}
int redisContextSetTimeout(redisContext *c, const struct timeval tv) {
int redisContextSetTimeout(redisContext *c, struct timeval tv) {
if (setsockopt(c->fd,SOL_SOCKET,SO_RCVTIMEO,&tv,sizeof(tv)) == -1) {
__redisSetErrorFromErrno(c,REDIS_ERR_IO,"setsockopt(SO_RCVTIMEO)");
return REDIS_ERR;
@@ -253,12 +192,10 @@ int redisContextSetTimeout(redisContext *c, const struct timeval tv) {
return REDIS_OK;
}
static int _redisContextConnectTcp(redisContext *c, const char *addr, int port,
const struct timeval *timeout,
const char *source_addr) {
int redisContextConnectTcp(redisContext *c, const char *addr, int port, struct timeval *timeout) {
int s, rv;
char _port[6]; /* strlen("65535"); */
struct addrinfo hints, *servinfo, *bservinfo, *p, *b;
struct addrinfo hints, *servinfo, *p;
int blocking = (c->flags & REDIS_BLOCK);
snprintf(_port, 6, "%d", port);
@@ -266,64 +203,33 @@ static int _redisContextConnectTcp(redisContext *c, const char *addr, int port,
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
/* Try with IPv6 if no IPv4 address was found. We do it in this order since
* in a Redis client you can't afford to test if you have IPv6 connectivity
* as this would add latency to every connect. Otherwise a more sensible
* route could be: Use IPv6 if both addresses are available and there is IPv6
* connectivity. */
if ((rv = getaddrinfo(addr,_port,&hints,&servinfo)) != 0) {
hints.ai_family = AF_INET6;
if ((rv = getaddrinfo(addr,_port,&hints,&servinfo)) != 0) {
__redisSetError(c,REDIS_ERR_OTHER,gai_strerror(rv));
return REDIS_ERR;
}
__redisSetError(c,REDIS_ERR_OTHER,gai_strerror(rv));
return REDIS_ERR;
}
for (p = servinfo; p != NULL; p = p->ai_next) {
if ((s = socket(p->ai_family,p->ai_socktype,p->ai_protocol)) == -1)
continue;
c->fd = s;
if (redisSetBlocking(c,0) != REDIS_OK)
if (redisSetBlocking(c,s,0) != REDIS_OK)
goto error;
if (source_addr) {
int bound = 0;
/* Using getaddrinfo saves us from self-determining IPv4 vs IPv6 */
if ((rv = getaddrinfo(source_addr, NULL, &hints, &bservinfo)) != 0) {
char buf[128];
snprintf(buf,sizeof(buf),"Can't get addr: %s",gai_strerror(rv));
__redisSetError(c,REDIS_ERR_OTHER,buf);
goto error;
}
for (b = bservinfo; b != NULL; b = b->ai_next) {
if (bind(s,b->ai_addr,b->ai_addrlen) != -1) {
bound = 1;
break;
}
}
freeaddrinfo(bservinfo);
if (!bound) {
char buf[128];
snprintf(buf,sizeof(buf),"Can't bind socket: %s",strerror(errno));
__redisSetError(c,REDIS_ERR_OTHER,buf);
goto error;
}
}
if (connect(s,p->ai_addr,p->ai_addrlen) == -1) {
if (errno == EHOSTUNREACH) {
redisContextCloseFd(c);
close(s);
continue;
} else if (errno == EINPROGRESS && !blocking) {
/* This is ok. */
} else {
if (redisContextWaitReady(c,timeout) != REDIS_OK)
if (redisContextWaitReady(c,s,timeout) != REDIS_OK)
goto error;
}
}
if (blocking && redisSetBlocking(c,1) != REDIS_OK)
if (blocking && redisSetBlocking(c,s,1) != REDIS_OK)
goto error;
if (redisSetTcpNoDelay(c) != REDIS_OK)
if (redisSetTcpNoDelay(c,s) != REDIS_OK)
goto error;
c->fd = s;
c->flags |= REDIS_CONNECTED;
rv = REDIS_OK;
goto end;
@@ -342,41 +248,32 @@ end:
return rv; // Need to return REDIS_OK if alright
}
int redisContextConnectTcp(redisContext *c, const char *addr, int port,
const struct timeval *timeout) {
return _redisContextConnectTcp(c, addr, port, timeout, NULL);
}
int redisContextConnectBindTcp(redisContext *c, const char *addr, int port,
const struct timeval *timeout,
const char *source_addr) {
return _redisContextConnectTcp(c, addr, port, timeout, source_addr);
}
int redisContextConnectUnix(redisContext *c, const char *path, const struct timeval *timeout) {
int redisContextConnectUnix(redisContext *c, const char *path, struct timeval *timeout) {
int s;
int blocking = (c->flags & REDIS_BLOCK);
struct sockaddr_un sa;
if (redisCreateSocket(c,AF_LOCAL) < 0)
if ((s = redisCreateSocket(c,AF_LOCAL)) < 0)
return REDIS_ERR;
if (redisSetBlocking(c,0) != REDIS_OK)
if (redisSetBlocking(c,s,0) != REDIS_OK)
return REDIS_ERR;
sa.sun_family = AF_LOCAL;
strncpy(sa.sun_path,path,sizeof(sa.sun_path)-1);
if (connect(c->fd, (struct sockaddr*)&sa, sizeof(sa)) == -1) {
if (connect(s, (struct sockaddr*)&sa, sizeof(sa)) == -1) {
if (errno == EINPROGRESS && !blocking) {
/* This is ok. */
} else {
if (redisContextWaitReady(c,timeout) != REDIS_OK)
if (redisContextWaitReady(c,s,timeout) != REDIS_OK)
return REDIS_ERR;
}
}
/* Reset socket to be blocking after connect(2). */
if (blocking && redisSetBlocking(c,1) != REDIS_OK)
if (blocking && redisSetBlocking(c,s,1) != REDIS_OK)
return REDIS_ERR;
c->fd = s;
c->flags |= REDIS_CONNECTED;
return REDIS_OK;
}
+5 -9
View File
@@ -35,17 +35,13 @@
#include "hiredis.h"
#if defined(__sun) || defined(_AIX)
#if defined(__sun)
#define AF_LOCAL AF_UNIX
#endif
int redisCheckSocketError(redisContext *c);
int redisContextSetTimeout(redisContext *c, const struct timeval tv);
int redisContextConnectTcp(redisContext *c, const char *addr, int port, const struct timeval *timeout);
int redisContextConnectBindTcp(redisContext *c, const char *addr, int port,
const struct timeval *timeout,
const char *source_addr);
int redisContextConnectUnix(redisContext *c, const char *path, const struct timeval *timeout);
int redisKeepAlive(redisContext *c, int interval);
int redisCheckSocketError(redisContext *c, int fd);
int redisContextSetTimeout(redisContext *c, struct timeval tv);
int redisContextConnectTcp(redisContext *c, const char *addr, int port, struct timeval *timeout);
int redisContextConnectUnix(redisContext *c, const char *path, struct timeval *timeout);
#endif
+135 -633
View File
File diff suppressed because it is too large Load Diff
+10 -23
View File
@@ -31,16 +31,14 @@
#ifndef __SDS_H
#define __SDS_H
#define SDS_MAX_PREALLOC (1024*1024)
#include <sys/types.h>
#include <stdarg.h>
typedef char *sds;
struct sdshdr {
unsigned int len;
unsigned int free;
int len;
int free;
char buf[];
};
@@ -60,13 +58,12 @@ sds sdsempty(void);
size_t sdslen(const sds s);
sds sdsdup(const sds s);
void sdsfree(sds s);
size_t sdsavail(const sds s);
size_t sdsavail(sds s);
sds sdsgrowzero(sds s, size_t len);
sds sdscatlen(sds s, const void *t, size_t len);
sds sdscat(sds s, const char *t);
sds sdscatsds(sds s, const sds t);
sds sdscpylen(sds s, const char *t, size_t len);
sds sdscpy(sds s, const char *t);
sds sdscpylen(sds s, char *t, size_t len);
sds sdscpy(sds s, char *t);
sds sdscatvprintf(sds s, const char *fmt, va_list ap);
#ifdef __GNUC__
@@ -76,26 +73,16 @@ sds sdscatprintf(sds s, const char *fmt, ...)
sds sdscatprintf(sds s, const char *fmt, ...);
#endif
sds sdscatfmt(sds s, char const *fmt, ...);
sds sdstrim(sds s, const char *cset);
void sdsrange(sds s, int start, int end);
sds sdsrange(sds s, int start, int end);
void sdsupdatelen(sds s);
void sdsclear(sds s);
int sdscmp(const sds s1, const sds s2);
sds *sdssplitlen(const char *s, int len, const char *sep, int seplen, int *count);
int sdscmp(sds s1, sds s2);
sds *sdssplitlen(char *s, int len, char *sep, int seplen, int *count);
void sdsfreesplitres(sds *tokens, int count);
void sdstolower(sds s);
void sdstoupper(sds s);
sds sdsfromlonglong(long long value);
sds sdscatrepr(sds s, const char *p, size_t len);
sds *sdssplitargs(const char *line, int *argc);
sds sdsmapchars(sds s, const char *from, const char *to, size_t setlen);
sds sdsjoin(char **argv, int argc, char *sep);
/* Low level functions exposed to the user API */
sds sdsMakeRoomFor(sds s, size_t addlen);
void sdsIncrLen(sds s, int incr);
sds sdsRemoveFreeSpace(sds s);
size_t sdsAllocSize(sds s);
sds sdscatrepr(sds s, char *p, size_t len);
sds *sdssplitargs(char *line, int *argc);
#endif
+17 -96
View File
@@ -8,14 +8,12 @@
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <limits.h>
#include "hiredis.h"
enum connection_type {
CONN_TCP,
CONN_UNIX,
CONN_FD
CONN_UNIX
};
struct config {
@@ -24,7 +22,6 @@ struct config {
struct {
const char *host;
int port;
struct timeval timeout;
} tcp;
struct {
@@ -51,7 +48,7 @@ static redisContext *select_database(redisContext *c) {
assert(reply != NULL);
freeReplyObject(reply);
/* Make sure the DB is empty */
/* Make sure the DB is emtpy */
reply = redisCommand(c,"DBSIZE");
assert(reply != NULL);
if (reply->type == REDIS_REPLY_INTEGER && reply->integer == 0) {
@@ -65,7 +62,7 @@ static redisContext *select_database(redisContext *c) {
return c;
}
static int disconnect(redisContext *c, int keep_fd) {
static void disconnect(redisContext *c) {
redisReply *reply;
/* Make sure we're on DB 9. */
@@ -76,11 +73,8 @@ static int disconnect(redisContext *c, int keep_fd) {
assert(reply != NULL);
freeReplyObject(reply);
/* Free the context as well, but keep the fd if requested. */
if (keep_fd)
return redisFreeKeepFd(c);
/* Free the context as well. */
redisFree(c);
return -1;
}
static redisContext *connect(struct config config) {
@@ -90,22 +84,11 @@ static redisContext *connect(struct config config) {
c = redisConnect(config.tcp.host, config.tcp.port);
} else if (config.type == CONN_UNIX) {
c = redisConnectUnix(config.unix.path);
} else if (config.type == CONN_FD) {
/* Create a dummy connection just to get an fd to inherit */
redisContext *dummy_ctx = redisConnectUnix(config.unix.path);
if (dummy_ctx) {
int fd = disconnect(dummy_ctx, 1);
printf("Connecting to inherited fd %d\n", fd);
c = redisConnectFd(fd);
}
} else {
assert(NULL);
}
if (c == NULL) {
printf("Connection error: can't allocate redis context\n");
exit(1);
} else if (c->err) {
if (c->err) {
printf("Connection error: %s\n", c->errstr);
exit(1);
}
@@ -142,13 +125,13 @@ static void test_format_commands(void) {
free(cmd);
test("Format command with %%b string interpolation: ");
len = redisFormatCommand(&cmd,"SET %b %b","foo",(size_t)3,"b\0r",(size_t)3);
len = redisFormatCommand(&cmd,"SET %b %b","foo",3,"b\0r",3);
test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$3\r\nb\0r\r\n",len) == 0 &&
len == 4+4+(3+2)+4+(3+2)+4+(3+2));
free(cmd);
test("Format command with %%b and an empty string: ");
len = redisFormatCommand(&cmd,"SET %b %b","foo",(size_t)3,"",(size_t)0);
len = redisFormatCommand(&cmd,"SET %b %b","foo",3,"",0);
test_cond(strncmp(cmd,"*3\r\n$3\r\nSET\r\n$3\r\nfoo\r\n$0\r\n\r\n",len) == 0 &&
len == 4+4+(3+2)+4+(3+2)+4+(0+2));
free(cmd);
@@ -194,7 +177,7 @@ static void test_format_commands(void) {
FLOAT_WIDTH_TEST(double);
test("Format command with invalid printf format: ");
len = redisFormatCommand(&cmd,"key:%08p %b",(void*)1234,"foo",(size_t)3);
len = redisFormatCommand(&cmd,"key:%08p %b",(void*)1234,"foo",3);
test_cond(len == -1);
const char *argv[3];
@@ -217,33 +200,10 @@ static void test_format_commands(void) {
free(cmd);
}
static void test_append_formatted_commands(struct config config) {
redisContext *c;
redisReply *reply;
char *cmd;
int len;
c = connect(config);
test("Append format command: ");
len = redisFormatCommand(&cmd, "SET foo bar");
test_cond(redisAppendFormattedCommand(c, cmd, len) == REDIS_OK);
assert(redisGetReply(c, (void*)&reply) == REDIS_OK);
free(cmd);
freeReplyObject(reply);
disconnect(c, 0);
}
static void test_reply_reader(void) {
redisReader *reader;
void *reply;
int ret;
int i;
test("Error handling in reply parser: ");
reader = redisReaderCreate();
@@ -265,13 +225,12 @@ static void test_reply_reader(void) {
strcasecmp(reader->errstr,"Protocol error, got \"@\" as reply type byte") == 0);
redisReaderFree(reader);
test("Set error on nested multi bulks with depth > 7: ");
test("Set error on nested multi bulks with depth > 2: ");
reader = redisReaderCreate();
for (i = 0; i < 9; i++) {
redisReaderFeed(reader,(char*)"*1\r\n",4);
}
redisReaderFeed(reader,(char*)"*1\r\n",4);
redisReaderFeed(reader,(char*)"*1\r\n",4);
redisReaderFeed(reader,(char*)"*1\r\n",4);
redisReaderFeed(reader,(char*)"*1\r\n",4);
ret = redisReaderGetReply(reader,NULL);
test_cond(ret == REDIS_ERR &&
strncasecmp(reader->errstr,"No support for",14) == 0);
@@ -325,10 +284,7 @@ static void test_blocking_connection_errors(void) {
c = redisConnect((char*)"idontexist.local", 6379);
test_cond(c->err == REDIS_ERR_OTHER &&
(strcmp(c->errstr,"Name or service not known") == 0 ||
strcmp(c->errstr,"Can't resolve: idontexist.local") == 0 ||
strcmp(c->errstr,"nodename nor servname provided, or not known") == 0 ||
strcmp(c->errstr,"No address associated with hostname") == 0 ||
strcmp(c->errstr,"no address associated with name") == 0));
strcmp(c->errstr,"Can't resolve: idontexist.local") == 0));
redisFree(c);
test("Returns error when the port is not open: ");
@@ -370,7 +326,7 @@ static void test_blocking_connection(struct config config) {
freeReplyObject(reply);
test("%%b String interpolation works: ");
reply = redisCommand(c,"SET %b %b","foo",(size_t)3,"hello\x00world",(size_t)11);
reply = redisCommand(c,"SET %b %b","foo",3,"hello\x00world",11);
freeReplyObject(reply);
reply = redisCommand(c,"GET foo");
test_cond(reply->type == REDIS_REPLY_STRING &&
@@ -418,7 +374,7 @@ static void test_blocking_connection(struct config config) {
strcasecmp(reply->element[1]->str,"pong") == 0);
freeReplyObject(reply);
disconnect(c, 0);
disconnect(c);
}
static void test_blocking_io_errors(struct config config) {
@@ -472,30 +428,6 @@ static void test_blocking_io_errors(struct config config) {
redisFree(c);
}
static void test_invalid_timeout_errors(struct config config) {
redisContext *c;
test("Set error when an invalid timeout usec value is given to redisConnectWithTimeout: ");
config.tcp.timeout.tv_sec = 0;
config.tcp.timeout.tv_usec = 10000001;
c = redisConnectWithTimeout(config.tcp.host, config.tcp.port, config.tcp.timeout);
test_cond(c->err == REDIS_ERR_IO);
test("Set error when an invalid timeout sec value is given to redisConnectWithTimeout: ");
config.tcp.timeout.tv_sec = (((LONG_MAX) - 999) / 1000) + 1;
config.tcp.timeout.tv_usec = 0;
c = redisConnectWithTimeout(config.tcp.host, config.tcp.port, config.tcp.timeout);
test_cond(c->err == REDIS_ERR_IO);
redisFree(c);
}
static void test_throughput(struct config config) {
redisContext *c = connect(config);
redisReply **replies;
@@ -558,7 +490,7 @@ static void test_throughput(struct config config) {
free(replies);
printf("\t(%dx LRANGE with 500 elements (pipelined): %.3fs)\n", num, (t2-t1)/1000000.0);
disconnect(c, 0);
disconnect(c);
}
// static long __test_callback_flags = 0;
@@ -671,7 +603,6 @@ int main(int argc, char **argv) {
}
};
int throughput = 1;
int test_inherit_fd = 1;
/* Ignore broken pipe signal (for I/O error tests). */
signal(SIGPIPE, SIG_IGN);
@@ -690,8 +621,6 @@ int main(int argc, char **argv) {
cfg.unix.path = argv[0];
} else if (argc >= 1 && !strcmp(argv[0],"--skip-throughput")) {
throughput = 0;
} else if (argc >= 1 && !strcmp(argv[0],"--skip-inherit-fd")) {
test_inherit_fd = 0;
} else {
fprintf(stderr, "Invalid argument: %s\n", argv[0]);
exit(1);
@@ -707,8 +636,6 @@ int main(int argc, char **argv) {
cfg.type = CONN_TCP;
test_blocking_connection(cfg);
test_blocking_io_errors(cfg);
test_invalid_timeout_errors(cfg);
test_append_formatted_commands(cfg);
if (throughput) test_throughput(cfg);
printf("\nTesting against Unix socket connection (%s):\n", cfg.unix.path);
@@ -717,12 +644,6 @@ int main(int argc, char **argv) {
test_blocking_io_errors(cfg);
if (throughput) test_throughput(cfg);
if (test_inherit_fd) {
printf("\nTesting against inherited fd (%s):\n", cfg.unix.path);
cfg.type = CONN_FD;
test_blocking_connection(cfg);
}
if (fails) {
printf("*** %d TESTS FAILED ***\n", fails);
return 1;
-13
View File
@@ -1,13 +0,0 @@
/* Drop in replacement for zmalloc.h in order to just use libc malloc without
* any wrappering. */
#ifndef ZMALLOC_H
#define ZMALLOC_H
#define zmalloc malloc
#define zrealloc realloc
#define zcalloc(x) calloc(x,1)
#define zfree free
#define zstrdup strdup
#endif
+9 -58
View File
@@ -1,72 +1,23 @@
/*.gcov.*
/autom4te.cache/
/bin/jemalloc.sh
/config.stamp
/config.log
/config.status
/configure
/doc/html.xsl
/doc/manpages.xsl
/doc/jemalloc.xml
/doc/jemalloc.html
/doc/jemalloc.3
/lib/
/Makefile
/include/jemalloc/internal/jemalloc_internal.h
/include/jemalloc/internal/jemalloc_internal_defs.h
/include/jemalloc/internal/private_namespace.h
/include/jemalloc/internal/private_unnamespace.h
/include/jemalloc/internal/public_namespace.h
/include/jemalloc/internal/public_symbols.txt
/include/jemalloc/internal/public_unnamespace.h
/include/jemalloc/internal/size_classes.h
/include/jemalloc/jemalloc.h
/include/jemalloc/jemalloc_defs.h
/include/jemalloc/jemalloc_macros.h
/include/jemalloc/jemalloc_mangle.h
/include/jemalloc/jemalloc_mangle_jet.h
/include/jemalloc/jemalloc_protos.h
/include/jemalloc/jemalloc_protos_jet.h
/include/jemalloc/jemalloc_rename.h
/include/jemalloc/internal/jemalloc_internal\.h
/include/jemalloc/jemalloc\.h
/include/jemalloc/jemalloc_defs\.h
/test/jemalloc_test\.h
/src/*.[od]
/src/*.gcda
/src/*.gcno
/test/test.sh
test/include/test/jemalloc_test.h
test/include/test/jemalloc_test_defs.h
/test/integration/[A-Za-z]*
!/test/integration/[A-Za-z]*.*
/test/integration/*.[od]
/test/integration/*.gcda
/test/integration/*.gcno
/test/integration/*.out
/test/src/*.[od]
/test/src/*.gcda
/test/src/*.gcno
/test/stress/[A-Za-z]*
!/test/stress/[A-Za-z]*.*
/test/stress/*.[od]
/test/stress/*.gcda
/test/stress/*.gcno
/test/stress/*.out
/test/unit/[A-Za-z]*
!/test/unit/[A-Za-z]*.*
/test/unit/*.[od]
/test/unit/*.gcda
/test/unit/*.gcno
/test/unit/*.out
/test/*.[od]
/test/*.out
/test/[a-z]*
!test/*.c
!test/*.exp
/VERSION
+28 -4
View File
@@ -1,10 +1,9 @@
Unless otherwise specified, files in the jemalloc source distribution are
subject to the following license:
subject to the following licenses:
--------------------------------------------------------------------------------
Copyright (C) 2002-2014 Jason Evans <jasone@canonware.com>.
Copyright (C) 2002-2010 Jason Evans <jasone@canonware.com>.
All rights reserved.
Copyright (C) 2007-2012 Mozilla Foundation. All rights reserved.
Copyright (C) 2009-2014 Facebook, Inc. All rights reserved.
Copyright (C) 2007-2010 Mozilla Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
@@ -25,3 +24,28 @@ 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.
--------------------------------------------------------------------------------
Copyright (C) 2009-2010 Facebook, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* 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.
* Neither the name of Facebook, Inc. nor the names of its contributors may be
used to endorse or promote products derived from this software without
specific prior written permission.
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.
--------------------------------------------------------------------------------
+2 -300
View File
@@ -3,306 +3,8 @@ bug fixes are all mentioned, but internal enhancements are omitted here for
brevity (even though they are more fun to write about). Much more detail can be
found in the git revision history:
https://github.com/jemalloc/jemalloc
* 3.6.0 (March 31, 2014)
This version contains a critical bug fix for a regression present in 3.5.0 and
3.5.1.
Bug fixes:
- Fix a regression in arena_chunk_alloc() that caused crashes during
small/large allocation if chunk allocation failed. In the absence of this
bug, chunk allocation failure would result in allocation failure, e.g. NULL
return from malloc(). This regression was introduced in 3.5.0.
- Fix backtracing for gcc intrinsics-based backtracing by specifying
-fno-omit-frame-pointer to gcc. Note that the application (and all the
libraries it links to) must also be compiled with this option for
backtracing to be reliable.
- Use dss allocation precedence for huge allocations as well as small/large
allocations.
- Fix test assertion failure message formatting. This bug did not manifect on
x86_64 systems because of implementation subtleties in va_list.
- Fix inconsequential test failures for hash and SFMT code.
New features:
- Support heap profiling on FreeBSD. This feature depends on the proc
filesystem being mounted during heap profile dumping.
* 3.5.1 (February 25, 2014)
This version primarily addresses minor bugs in test code.
Bug fixes:
- Configure Solaris/Illumos to use MADV_FREE.
- Fix junk filling for mremap(2)-based huge reallocation. This is only
relevant if configuring with the --enable-mremap option specified.
- Avoid compilation failure if 'restrict' C99 keyword is not supported by the
compiler.
- Add a configure test for SSE2 rather than assuming it is usable on i686
systems. This fixes test compilation errors, especially on 32-bit Linux
systems.
- Fix mallctl argument size mismatches (size_t vs. uint64_t) in the stats unit
test.
- Fix/remove flawed alignment-related overflow tests.
- Prevent compiler optimizations that could change backtraces in the
prof_accum unit test.
* 3.5.0 (January 22, 2014)
This version focuses on refactoring and automated testing, though it also
includes some non-trivial heap profiling optimizations not mentioned below.
New features:
- Add the *allocx() API, which is a successor to the experimental *allocm()
API. The *allocx() functions are slightly simpler to use because they have
fewer parameters, they directly return the results of primary interest, and
mallocx()/rallocx() avoid the strict aliasing pitfall that
allocm()/rallocm() share with posix_memalign(). Note that *allocm() is
slated for removal in the next non-bugfix release.
- Add support for LinuxThreads.
Bug fixes:
- Unless heap profiling is enabled, disable floating point code and don't link
with libm. This, in combination with e.g. EXTRA_CFLAGS=-mno-sse on x64
systems, makes it possible to completely disable floating point register
use. Some versions of glibc neglect to save/restore caller-saved floating
point registers during dynamic lazy symbol loading, and the symbol loading
code uses whatever malloc the application happens to have linked/loaded
with, the result being potential floating point register corruption.
- Report ENOMEM rather than EINVAL if an OOM occurs during heap profiling
backtrace creation in imemalign(). This bug impacted posix_memalign() and
aligned_alloc().
- Fix a file descriptor leak in a prof_dump_maps() error path.
- Fix prof_dump() to close the dump file descriptor for all relevant error
paths.
- Fix rallocm() to use the arena specified by the ALLOCM_ARENA(s) flag for
allocation, not just deallocation.
- Fix a data race for large allocation stats counters.
- Fix a potential infinite loop during thread exit. This bug occurred on
Solaris, and could affect other platforms with similar pthreads TSD
implementations.
- Don't junk-fill reallocations unless usable size changes. This fixes a
violation of the *allocx()/*allocm() semantics.
- Fix growing large reallocation to junk fill new space.
- Fix huge deallocation to junk fill when munmap is disabled.
- Change the default private namespace prefix from empty to je_, and change
--with-private-namespace-prefix so that it prepends an additional prefix
rather than replacing je_. This reduces the likelihood of applications
which statically link jemalloc experiencing symbol name collisions.
- Add missing private namespace mangling (relevant when
--with-private-namespace is specified).
- Add and use JEMALLOC_INLINE_C so that static inline functions are marked as
static even for debug builds.
- Add a missing mutex unlock in a malloc_init_hard() error path. In practice
this error path is never executed.
- Fix numerous bugs in malloc_strotumax() error handling/reporting. These
bugs had no impact except for malformed inputs.
- Fix numerous bugs in malloc_snprintf(). These bugs were not exercised by
existing calls, so they had no impact.
* 3.4.1 (October 20, 2013)
Bug fixes:
- Fix a race in the "arenas.extend" mallctl that could cause memory corruption
of internal data structures and subsequent crashes.
- Fix Valgrind integration flaws that caused Valgrind warnings about reads of
uninitialized memory in:
+ arena chunk headers
+ internal zero-initialized data structures (relevant to tcache and prof
code)
- Preserve errno during the first allocation. A readlink(2) call during
initialization fails unless /etc/malloc.conf exists, so errno was typically
set during the first allocation prior to this fix.
- Fix compilation warnings reported by gcc 4.8.1.
* 3.4.0 (June 2, 2013)
This version is essentially a small bugfix release, but the addition of
aarch64 support requires that the minor version be incremented.
Bug fixes:
- Fix race-triggered deadlocks in chunk_record(). These deadlocks were
typically triggered by multiple threads concurrently deallocating huge
objects.
New features:
- Add support for the aarch64 architecture.
* 3.3.1 (March 6, 2013)
This version fixes bugs that are typically encountered only when utilizing
custom run-time options.
Bug fixes:
- Fix a locking order bug that could cause deadlock during fork if heap
profiling were enabled.
- Fix a chunk recycling bug that could cause the allocator to lose track of
whether a chunk was zeroed. On FreeBSD, NetBSD, and OS X, it could cause
corruption if allocating via sbrk(2) (unlikely unless running with the
"dss:primary" option specified). This was completely harmless on Linux
unless using mlockall(2) (and unlikely even then, unless the
--disable-munmap configure option or the "dss:primary" option was
specified). This regression was introduced in 3.1.0 by the
mlockall(2)/madvise(2) interaction fix.
- Fix TLS-related memory corruption that could occur during thread exit if the
thread never allocated memory. Only the quarantine and prof facilities were
susceptible.
- Fix two quarantine bugs:
+ Internal reallocation of the quarantined object array leaked the old
array.
+ Reallocation failure for internal reallocation of the quarantined object
array (very unlikely) resulted in memory corruption.
- Fix Valgrind integration to annotate all internally allocated memory in a
way that keeps Valgrind happy about internal data structure access.
- Fix building for s390 systems.
* 3.3.0 (January 23, 2013)
This version includes a few minor performance improvements in addition to the
listed new features and bug fixes.
New features:
- Add clipping support to lg_chunk option processing.
- Add the --enable-ivsalloc option.
- Add the --without-export option.
- Add the --disable-zone-allocator option.
Bug fixes:
- Fix "arenas.extend" mallctl to output the number of arenas.
- Fix chunk_recycle() to unconditionally inform Valgrind that returned memory
is undefined.
- Fix build break on FreeBSD related to alloca.h.
* 3.2.0 (November 9, 2012)
In addition to a couple of bug fixes, this version modifies page run
allocation and dirty page purging algorithms in order to better control
page-level virtual memory fragmentation.
Incompatible changes:
- Change the "opt.lg_dirty_mult" default from 5 to 3 (32:1 to 8:1).
Bug fixes:
- Fix dss/mmap allocation precedence code to use recyclable mmap memory only
after primary dss allocation fails.
- Fix deadlock in the "arenas.purge" mallctl. This regression was introduced
in 3.1.0 by the addition of the "arena.<i>.purge" mallctl.
* 3.1.0 (October 16, 2012)
New features:
- Auto-detect whether running inside Valgrind, thus removing the need to
manually specify MALLOC_CONF=valgrind:true.
- Add the "arenas.extend" mallctl, which allows applications to create
manually managed arenas.
- Add the ALLOCM_ARENA() flag for {,r,d}allocm().
- Add the "opt.dss", "arena.<i>.dss", and "stats.arenas.<i>.dss" mallctls,
which provide control over dss/mmap precedence.
- Add the "arena.<i>.purge" mallctl, which obsoletes "arenas.purge".
- Define LG_QUANTUM for hppa.
Incompatible changes:
- Disable tcache by default if running inside Valgrind, in order to avoid
making unallocated objects appear reachable to Valgrind.
- Drop const from malloc_usable_size() argument on Linux.
Bug fixes:
- Fix heap profiling crash if sampled object is freed via realloc(p, 0).
- Remove const from __*_hook variable declarations, so that glibc can modify
them during process forking.
- Fix mlockall(2)/madvise(2) interaction.
- Fix fork(2)-related deadlocks.
- Fix error return value for "thread.tcache.enabled" mallctl.
* 3.0.0 (May 11, 2012)
Although this version adds some major new features, the primary focus is on
internal code cleanup that facilitates maintainability and portability, most
of which is not reflected in the ChangeLog. This is the first release to
incorporate substantial contributions from numerous other developers, and the
result is a more broadly useful allocator (see the git revision history for
contribution details). Note that the license has been unified, thanks to
Facebook granting a license under the same terms as the other copyright
holders (see COPYING).
New features:
- Implement Valgrind support, redzones, and quarantine.
- Add support for additional platforms:
+ FreeBSD
+ Mac OS X Lion
+ MinGW
+ Windows (no support yet for replacing the system malloc)
- Add support for additional architectures:
+ MIPS
+ SH4
+ Tilera
- Add support for cross compiling.
- Add nallocm(), which rounds a request size up to the nearest size class
without actually allocating.
- Implement aligned_alloc() (blame C11).
- Add the "thread.tcache.enabled" mallctl.
- Add the "opt.prof_final" mallctl.
- Update pprof (from gperftools 2.0).
- Add the --with-mangling option.
- Add the --disable-experimental option.
- Add the --disable-munmap option, and make it the default on Linux.
- Add the --enable-mremap option, which disables use of mremap(2) by default.
Incompatible changes:
- Enable stats by default.
- Enable fill by default.
- Disable lazy locking by default.
- Rename the "tcache.flush" mallctl to "thread.tcache.flush".
- Rename the "arenas.pagesize" mallctl to "arenas.page".
- Change the "opt.lg_prof_sample" default from 0 to 19 (1 B to 512 KiB).
- Change the "opt.prof_accum" default from true to false.
Removed features:
- Remove the swap feature, including the "config.swap", "swap.avail",
"swap.prezeroed", "swap.nfds", and "swap.fds" mallctls.
- Remove highruns statistics, including the
"stats.arenas.<i>.bins.<j>.highruns" and
"stats.arenas.<i>.lruns.<j>.highruns" mallctls.
- As part of small size class refactoring, remove the "opt.lg_[qc]space_max",
"arenas.cacheline", "arenas.subpage", "arenas.[tqcs]space_{min,max}", and
"arenas.[tqcs]bins" mallctls.
- Remove the "arenas.chunksize" mallctl.
- Remove the "opt.lg_prof_tcmax" option.
- Remove the "opt.lg_prof_bt_max" option.
- Remove the "opt.lg_tcache_gc_sweep" option.
- Remove the --disable-tiny option, including the "config.tiny" mallctl.
- Remove the --enable-dynamic-page-shift configure option.
- Remove the --enable-sysv configure option.
Bug fixes:
- Fix a statistics-related bug in the "thread.arena" mallctl that could cause
invalid statistics and crashes.
- Work around TLS deallocation via free() on Linux. This bug could cause
write-after-free memory corruption.
- Fix a potential deadlock that could occur during interval- and
growth-triggered heap profile dumps.
- Fix large calloc() zeroing bugs due to dropping chunk map unzeroed flags.
- Fix chunk_alloc_dss() to stop claiming memory is zeroed. This bug could
cause memory corruption and crashes with --enable-dss specified.
- Fix fork-related bugs that could cause deadlock in children between fork
and exec.
- Fix malloc_stats_print() to honor 'b' and 'l' in the opts parameter.
- Fix realloc(p, 0) to act like free(p).
- Do not enforce minimum alignment in memalign().
- Check for NULL pointer in malloc_usable_size().
- Fix an off-by-one heap profile statistics bug that could be observed in
interval- and growth-triggered heap profiles.
- Fix the "epoch" mallctl to update cached stats even if the passed in epoch
is 0.
- Fix bin->runcur management to fix a layout policy bug. This bug did not
affect correctness.
- Fix a bug in choose_arena_hard() that potentially caused more arenas to be
initialized than necessary.
- Add missing "opt.lg_tcache_max" mallctl implementation.
- Use glibc allocator hooks to make mixed allocator usage less likely.
- Fix build issues for --disable-tcache.
- Don't mangle pthread_create() when --with-private-namespace is specified.
http://www.canonware.com/cgi-bin/gitweb.cgi?p=jemalloc.git
git://canonware.com/jemalloc.git
* 2.2.5 (November 14, 2011)
+38 -87
View File
@@ -26,19 +26,6 @@ any of the following arguments (not a definitive list) to 'configure':
Embed one or more library paths, so that libjemalloc can find the libraries
it is linked to. This works only on ELF-based systems.
--with-mangling=<map>
Mangle public symbols specified in <map> which is a comma-separated list of
name:mangled pairs.
For example, to use ld's --wrap option as an alternative method for
overriding libc's malloc implementation, specify something like:
--with-mangling=malloc:__wrap_malloc,free:__wrap_free[...]
Note that mangling happens prior to application of the prefix specified by
--with-jemalloc-prefix, and mangled symbols are then ignored when applying
the prefix.
--with-jemalloc-prefix=<prefix>
Prefix all public APIs with <prefix>. For example, if <prefix> is
"prefix_", API changes like the following occur:
@@ -55,16 +42,11 @@ any of the following arguments (not a definitive list) to 'configure':
jemalloc overlays the default malloc zone, but makes no attempt to actually
replace the "malloc", "calloc", etc. symbols.
--without-export
Don't export public APIs. This can be useful when building jemalloc as a
static library, or to avoid exporting public APIs when using the zone
allocator on OSX.
--with-private-namespace=<prefix>
Prefix all library-private APIs with <prefix>je_. For shared libraries,
Prefix all library-private APIs with <prefix>. For shared libraries,
symbol visibility mechanisms prevent these symbols from being exported, but
for static libraries, naming collisions are a real possibility. By
default, <prefix> is empty, which results in a symbol prefix of je_ .
default, the prefix is "" (empty string).
--with-install-suffix=<suffix>
Append <suffix> to the base name of all installed files, such that multiple
@@ -79,28 +61,9 @@ any of the following arguments (not a definitive list) to 'configure':
--enable-debug
Enable assertions and validation code. This incurs a substantial
performance hit, but is very useful during application development.
Implies --enable-ivsalloc.
--enable-code-coverage
Enable code coverage support, for use during jemalloc test development.
Additional testing targets are available if this option is enabled:
coverage
coverage_unit
coverage_integration
coverage_stress
These targets do not clear code coverage results from previous runs, and
there are interactions between the various coverage targets, so it is
usually advisable to run 'make clean' between repeated code coverage runs.
--enable-ivsalloc
Enable validation code, which verifies that pointers reside within
jemalloc-owned chunks before dereferencing them. This incurs a substantial
performance hit.
--disable-stats
Disable statistics gathering functionality. See the "opt.stats_print"
--enable-stats
Enable statistics gathering functionality. See the "opt.stats_print"
option documentation for usage details.
--enable-prof
@@ -127,54 +90,51 @@ any of the following arguments (not a definitive list) to 'configure':
Statically link against the specified libunwind.a rather than dynamically
linking with -lunwind.
--disable-tiny
Disable tiny (sub-quantum-sized) object support. Technically it is not
legal for a malloc implementation to allocate objects with less than
quantum alignment (8 or 16 bytes, depending on architecture), but in
practice it never causes any problems if, for example, 4-byte allocations
are 4-byte-aligned.
--disable-tcache
Disable thread-specific caches for small objects. Objects are cached and
released in bulk, thus reducing the total number of mutex operations. See
the "opt.tcache" option for usage details.
--enable-mremap
Enable huge realloc() via mremap(2). mremap() is disabled by default
because the flavor used is specific to Linux, which has a quirk in its
virtual memory allocation algorithm that causes semi-permanent VM map holes
under normal jemalloc operation.
--disable-munmap
Disable virtual memory deallocation via munmap(2); instead keep track of
the virtual memory for later use. munmap() is disabled by default (i.e.
--disable-munmap is implied) on Linux, which has a quirk in its virtual
memory allocation algorithm that causes semi-permanent VM map holes under
normal jemalloc operation.
--enable-swap
Enable mmap()ed swap file support. When this feature is built in, it is
possible to specify one or more files that act as backing store. This
effectively allows for per application swap files.
--enable-dss
Enable support for page allocation/deallocation via sbrk(2), in addition to
mmap(2).
--disable-fill
Disable support for junk/zero filling of memory, quarantine, and redzones.
See the "opt.junk", "opt.zero", "opt.quarantine", and "opt.redzone" option
documentation for usage details.
--disable-valgrind
Disable support for Valgrind.
--disable-experimental
Disable support for the experimental API (*allocm()).
--disable-zone-allocator
Disable zone allocator for Darwin. This means jemalloc won't be hooked as
the default allocator on OSX/iOS.
--enable-utrace
Enable utrace(2)-based allocation tracing. This feature is not broadly
portable (FreeBSD has it, but Linux and OS X do not).
--enable-fill
Enable support for junk/zero filling of memory. See the "opt.junk"/
"opt.zero" option documentation for usage details.
--enable-xmalloc
Enable support for optional immediate termination due to out-of-memory
errors, as is commonly implemented by "xmalloc" wrapper function for malloc.
See the "opt.xmalloc" option documentation for usage details.
--enable-lazy-lock
Enable code that wraps pthread_create() to detect when an application
--enable-sysv
Enable support for System V semantics, wherein malloc(0) returns NULL
rather than a minimal allocation. See the "opt.sysv" option documentation
for usage details.
--enable-dynamic-page-shift
Under most conditions, the system page size never changes (usually 4KiB or
8KiB, depending on architecture and configuration), and unless this option
is enabled, jemalloc assumes that page size can safely be determined during
configuration and hard-coded. Enabling dynamic page size determination has
a measurable impact on performance, since the compiler is forced to load
the page size from memory rather than embedding immediate values.
--disable-lazy-lock
Disable code that wraps pthread_create() to detect when an application
switches from single-threaded to multi-threaded mode, so that it can avoid
mutex locking/unlocking operations while in single-threaded mode. In
practice, this feature usually has little impact on performance unless
@@ -221,24 +181,11 @@ PATH="?"
=== Advanced compilation =======================================================
To build only parts of jemalloc, use the following targets:
build_lib_shared
build_lib_static
build_lib
build_doc_html
build_doc_man
build_doc
To install only parts of jemalloc, use the following targets:
install_bin
install_include
install_lib_shared
install_lib_static
install_lib
install_doc_html
install_doc_man
install_doc
To clean up build results to varying degrees, use the following make targets:
@@ -301,6 +248,10 @@ directory, issue configuration and build commands:
The manual page is generated in both html and roff formats. Any web browser
can be used to view the html manual. The roff manual page can be formatted
prior to installation via the following command:
prior to installation via any of the following commands:
nroff -man -t doc/jemalloc.3
groff -man -t -Tps doc/jemalloc.3 | ps2pdf - doc/jemalloc.3.pdf
(cd doc; groff -man -man-ext -t -Thtml jemalloc.3 > jemalloc.3.html)
+155 -334
View File
@@ -17,262 +17,130 @@ INCLUDEDIR := $(DESTDIR)@INCLUDEDIR@
LIBDIR := $(DESTDIR)@LIBDIR@
DATADIR := $(DESTDIR)@DATADIR@
MANDIR := $(DESTDIR)@MANDIR@
srcroot := @srcroot@
objroot := @objroot@
abs_srcroot := @abs_srcroot@
abs_objroot := @abs_objroot@
# Build parameters.
CPPFLAGS := @CPPFLAGS@ -I$(srcroot)include -I$(objroot)include
CPPFLAGS := @CPPFLAGS@ -I@srcroot@include -I@objroot@include
CFLAGS := @CFLAGS@
ifeq (macho, @abi@)
CFLAGS += -dynamic
endif
LDFLAGS := @LDFLAGS@
EXTRA_LDFLAGS := @EXTRA_LDFLAGS@
LIBS := @LIBS@
RPATH_EXTRA := @RPATH_EXTRA@
SO := @so@
IMPORTLIB := @importlib@
O := @o@
A := @a@
EXE := @exe@
LIBPREFIX := @libprefix@
REV := @rev@
install_suffix := @install_suffix@
ABI := @abi@
XSLTPROC := @XSLTPROC@
AUTOCONF := @AUTOCONF@
_RPATH = @RPATH@
RPATH = $(if $(1),$(call _RPATH,$(1)))
cfghdrs_in := @cfghdrs_in@
cfghdrs_out := @cfghdrs_out@
cfgoutputs_in := @cfgoutputs_in@
cfgoutputs_out := @cfgoutputs_out@
enable_autogen := @enable_autogen@
enable_code_coverage := @enable_code_coverage@
enable_experimental := @enable_experimental@
enable_zone_allocator := @enable_zone_allocator@
DSO_LDFLAGS = @DSO_LDFLAGS@
SOREV = @SOREV@
PIC_CFLAGS = @PIC_CFLAGS@
CTARGET = @CTARGET@
LDTARGET = @LDTARGET@
MKLIB = @MKLIB@
AR = @AR@
ARFLAGS = @ARFLAGS@
CC_MM = @CC_MM@
ifeq (macho, $(ABI))
TEST_LIBRARY_PATH := DYLD_FALLBACK_LIBRARY_PATH="$(objroot)lib"
ifeq (macho, @abi@)
SO := dylib
WL_SONAME := dylib_install_name
else
ifeq (pecoff, $(ABI))
TEST_LIBRARY_PATH := PATH="$(PATH):$(objroot)lib"
SO := so
WL_SONAME := soname
endif
REV := 1
ifeq (macho, @abi@)
TEST_LIBRARY_PATH := DYLD_FALLBACK_LIBRARY_PATH=@objroot@lib
else
TEST_LIBRARY_PATH :=
endif
endif
LIBJEMALLOC := $(LIBPREFIX)jemalloc$(install_suffix)
# Lists of files.
BINS := $(srcroot)bin/pprof $(objroot)bin/jemalloc.sh
C_HDRS := $(objroot)include/jemalloc/jemalloc$(install_suffix).h
C_SRCS := $(srcroot)src/jemalloc.c $(srcroot)src/arena.c \
$(srcroot)src/atomic.c $(srcroot)src/base.c $(srcroot)src/bitmap.c \
$(srcroot)src/chunk.c $(srcroot)src/chunk_dss.c \
$(srcroot)src/chunk_mmap.c $(srcroot)src/ckh.c $(srcroot)src/ctl.c \
$(srcroot)src/extent.c $(srcroot)src/hash.c $(srcroot)src/huge.c \
$(srcroot)src/mb.c $(srcroot)src/mutex.c $(srcroot)src/prof.c \
$(srcroot)src/quarantine.c $(srcroot)src/rtree.c $(srcroot)src/stats.c \
$(srcroot)src/tcache.c $(srcroot)src/util.c $(srcroot)src/tsd.c
ifeq ($(enable_zone_allocator), 1)
C_SRCS += $(srcroot)src/zone.c
BINS := @srcroot@bin/pprof
CHDRS := @objroot@include/jemalloc/jemalloc@install_suffix@.h \
@objroot@include/jemalloc/jemalloc_defs@install_suffix@.h
CSRCS := @srcroot@src/jemalloc.c @srcroot@src/arena.c @srcroot@src/atomic.c \
@srcroot@src/base.c @srcroot@src/bitmap.c @srcroot@src/chunk.c \
@srcroot@src/chunk_dss.c @srcroot@src/chunk_mmap.c \
@srcroot@src/chunk_swap.c @srcroot@src/ckh.c @srcroot@src/ctl.c \
@srcroot@src/extent.c @srcroot@src/hash.c @srcroot@src/huge.c \
@srcroot@src/mb.c @srcroot@src/mutex.c @srcroot@src/prof.c \
@srcroot@src/rtree.c @srcroot@src/stats.c @srcroot@src/tcache.c
ifeq (macho, @abi@)
CSRCS += @srcroot@src/zone.c
endif
ifeq ($(IMPORTLIB),$(SO))
STATIC_LIBS := $(objroot)lib/$(LIBJEMALLOC).$(A)
endif
ifdef PIC_CFLAGS
STATIC_LIBS += $(objroot)lib/$(LIBJEMALLOC)_pic.$(A)
else
STATIC_LIBS += $(objroot)lib/$(LIBJEMALLOC)_s.$(A)
endif
DSOS := $(objroot)lib/$(LIBJEMALLOC).$(SOREV)
ifneq ($(SOREV),$(SO))
DSOS += $(objroot)lib/$(LIBJEMALLOC).$(SO)
endif
MAN3 := $(objroot)doc/jemalloc$(install_suffix).3
DOCS_XML := $(objroot)doc/jemalloc$(install_suffix).xml
DOCS_HTML := $(DOCS_XML:$(objroot)%.xml=$(srcroot)%.html)
DOCS_MAN3 := $(DOCS_XML:$(objroot)%.xml=$(srcroot)%.3)
STATIC_LIBS := @objroot@lib/libjemalloc@install_suffix@.a
DSOS := @objroot@lib/libjemalloc@install_suffix@.$(SO).$(REV) \
@objroot@lib/libjemalloc@install_suffix@.$(SO) \
@objroot@lib/libjemalloc@install_suffix@_pic.a
MAN3 := @objroot@doc/jemalloc@install_suffix@.3
DOCS_XML := @objroot@doc/jemalloc@install_suffix@.xml
DOCS_HTML := $(DOCS_XML:@objroot@%.xml=@srcroot@%.html)
DOCS_MAN3 := $(DOCS_XML:@objroot@%.xml=@srcroot@%.3)
DOCS := $(DOCS_HTML) $(DOCS_MAN3)
C_TESTLIB_SRCS := $(srcroot)test/src/math.c $(srcroot)test/src/mtx.c \
$(srcroot)test/src/SFMT.c $(srcroot)test/src/test.c \
$(srcroot)test/src/thd.c
C_UTIL_INTEGRATION_SRCS := $(srcroot)src/util.c
TESTS_UNIT := $(srcroot)test/unit/bitmap.c \
$(srcroot)test/unit/ckh.c \
$(srcroot)test/unit/hash.c \
$(srcroot)test/unit/junk.c \
$(srcroot)test/unit/mallctl.c \
$(srcroot)test/unit/math.c \
$(srcroot)test/unit/mq.c \
$(srcroot)test/unit/mtx.c \
$(srcroot)test/unit/prof_accum.c \
$(srcroot)test/unit/prof_gdump.c \
$(srcroot)test/unit/prof_idump.c \
$(srcroot)test/unit/ql.c \
$(srcroot)test/unit/qr.c \
$(srcroot)test/unit/quarantine.c \
$(srcroot)test/unit/rb.c \
$(srcroot)test/unit/rtree.c \
$(srcroot)test/unit/SFMT.c \
$(srcroot)test/unit/stats.c \
$(srcroot)test/unit/tsd.c \
$(srcroot)test/unit/util.c \
$(srcroot)test/unit/zero.c
TESTS_UNIT_AUX := $(srcroot)test/unit/prof_accum_a.c \
$(srcroot)test/unit/prof_accum_b.c
TESTS_INTEGRATION := $(srcroot)test/integration/aligned_alloc.c \
$(srcroot)test/integration/allocated.c \
$(srcroot)test/integration/mallocx.c \
$(srcroot)test/integration/mremap.c \
$(srcroot)test/integration/posix_memalign.c \
$(srcroot)test/integration/rallocx.c \
$(srcroot)test/integration/thread_arena.c \
$(srcroot)test/integration/thread_tcache_enabled.c \
$(srcroot)test/integration/xallocx.c
ifeq ($(enable_experimental), 1)
TESTS_INTEGRATION += $(srcroot)test/integration/allocm.c \
$(srcroot)test/integration/MALLOCX_ARENA.c \
$(srcroot)test/integration/rallocm.c
endif
TESTS_STRESS :=
TESTS := $(TESTS_UNIT) $(TESTS_INTEGRATION) $(TESTS_STRESS)
CTESTS := @srcroot@test/allocated.c @srcroot@test/allocm.c \
@srcroot@test/bitmap.c @srcroot@test/mremap.c \
@srcroot@test/posix_memalign.c @srcroot@test/rallocm.c \
@srcroot@test/thread_arena.c
C_OBJS := $(C_SRCS:$(srcroot)%.c=$(objroot)%.$(O))
C_PIC_OBJS := $(C_SRCS:$(srcroot)%.c=$(objroot)%.pic.$(O))
C_JET_OBJS := $(C_SRCS:$(srcroot)%.c=$(objroot)%.jet.$(O))
C_TESTLIB_UNIT_OBJS := $(C_TESTLIB_SRCS:$(srcroot)%.c=$(objroot)%.unit.$(O))
C_TESTLIB_INTEGRATION_OBJS := $(C_TESTLIB_SRCS:$(srcroot)%.c=$(objroot)%.integration.$(O))
C_UTIL_INTEGRATION_OBJS := $(C_UTIL_INTEGRATION_SRCS:$(srcroot)%.c=$(objroot)%.integration.$(O))
C_TESTLIB_STRESS_OBJS := $(C_TESTLIB_SRCS:$(srcroot)%.c=$(objroot)%.stress.$(O))
C_TESTLIB_OBJS := $(C_TESTLIB_UNIT_OBJS) $(C_TESTLIB_INTEGRATION_OBJS) $(C_UTIL_INTEGRATION_OBJS) $(C_TESTLIB_STRESS_OBJS)
TESTS_UNIT_OBJS := $(TESTS_UNIT:$(srcroot)%.c=$(objroot)%.$(O))
TESTS_UNIT_AUX_OBJS := $(TESTS_UNIT_AUX:$(srcroot)%.c=$(objroot)%.$(O))
TESTS_INTEGRATION_OBJS := $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%.$(O))
TESTS_STRESS_OBJS := $(TESTS_STRESS:$(srcroot)%.c=$(objroot)%.$(O))
TESTS_OBJS := $(TESTS_UNIT_OBJS) $(TESTS_UNIT_AUX_OBJS) $(TESTS_INTEGRATION_OBJS) $(TESTS_STRESS_OBJS)
.PHONY: all dist build_doc_html build_doc_man build_doc
.PHONY: all dist doc_html doc_man doc
.PHONY: install_bin install_include install_lib
.PHONY: install_doc_html install_doc_man install_doc install
.PHONY: install_html install_man install_doc install
.PHONY: tests check clean distclean relclean
.SECONDARY : $(TESTS_OBJS)
.SECONDARY : $(CTESTS:@srcroot@%.c=@objroot@%.o)
# Default target.
all: build_lib
all: $(DSOS) $(STATIC_LIBS)
dist: build_doc
dist: doc
$(srcroot)doc/%.html : $(objroot)doc/%.xml $(srcroot)doc/stylesheet.xsl $(objroot)doc/html.xsl
$(XSLTPROC) -o $@ $(objroot)doc/html.xsl $<
@srcroot@doc/%.html : @objroot@doc/%.xml @srcroot@doc/stylesheet.xsl @objroot@doc/html.xsl
@XSLTPROC@ -o $@ @objroot@doc/html.xsl $<
$(srcroot)doc/%.3 : $(objroot)doc/%.xml $(srcroot)doc/stylesheet.xsl $(objroot)doc/manpages.xsl
$(XSLTPROC) -o $@ $(objroot)doc/manpages.xsl $<
@srcroot@doc/%.3 : @objroot@doc/%.xml @srcroot@doc/stylesheet.xsl @objroot@doc/manpages.xsl
@XSLTPROC@ -o $@ @objroot@doc/manpages.xsl $<
build_doc_html: $(DOCS_HTML)
build_doc_man: $(DOCS_MAN3)
build_doc: $(DOCS)
doc_html: $(DOCS_HTML)
doc_man: $(DOCS_MAN3)
doc: $(DOCS)
#
# Include generated dependency files.
#
ifdef CC_MM
-include $(C_OBJS:%.$(O)=%.d)
-include $(C_PIC_OBJS:%.$(O)=%.d)
-include $(C_JET_OBJS:%.$(O)=%.d)
-include $(C_TESTLIB_OBJS:%.$(O)=%.d)
-include $(TESTS_OBJS:%.$(O)=%.d)
endif
-include $(CSRCS:@srcroot@%.c=@objroot@%.d)
-include $(CSRCS:@srcroot@%.c=@objroot@%.pic.d)
-include $(CTESTS:@srcroot@%.c=@objroot@%.d)
$(C_OBJS): $(objroot)src/%.$(O): $(srcroot)src/%.c
$(C_PIC_OBJS): $(objroot)src/%.pic.$(O): $(srcroot)src/%.c
$(C_PIC_OBJS): CFLAGS += $(PIC_CFLAGS)
$(C_JET_OBJS): $(objroot)src/%.jet.$(O): $(srcroot)src/%.c
$(C_JET_OBJS): CFLAGS += -DJEMALLOC_JET
$(C_TESTLIB_UNIT_OBJS): $(objroot)test/src/%.unit.$(O): $(srcroot)test/src/%.c
$(C_TESTLIB_UNIT_OBJS): CPPFLAGS += -DJEMALLOC_UNIT_TEST
$(C_TESTLIB_INTEGRATION_OBJS): $(objroot)test/src/%.integration.$(O): $(srcroot)test/src/%.c
$(C_TESTLIB_INTEGRATION_OBJS): CPPFLAGS += -DJEMALLOC_INTEGRATION_TEST
$(C_UTIL_INTEGRATION_OBJS): $(objroot)src/%.integration.$(O): $(srcroot)src/%.c
$(C_TESTLIB_STRESS_OBJS): $(objroot)test/src/%.stress.$(O): $(srcroot)test/src/%.c
$(C_TESTLIB_STRESS_OBJS): CPPFLAGS += -DJEMALLOC_STRESS_TEST -DJEMALLOC_STRESS_TESTLIB
$(C_TESTLIB_OBJS): CPPFLAGS += -I$(srcroot)test/include -I$(objroot)test/include
$(TESTS_UNIT_OBJS): CPPFLAGS += -DJEMALLOC_UNIT_TEST
$(TESTS_UNIT_AUX_OBJS): CPPFLAGS += -DJEMALLOC_UNIT_TEST
define make-unit-link-dep
$(1): TESTS_UNIT_LINK_OBJS += $(2)
$(1): $(2)
endef
$(foreach test, $(TESTS_UNIT:$(srcroot)test/unit/%.c=$(objroot)test/unit/%$(EXE)), $(eval $(call make-unit-link-dep,$(test),$(filter $(test:%=%_a.$(O)) $(test:%=%_b.$(O)),$(TESTS_UNIT_AUX_OBJS)))))
$(TESTS_INTEGRATION_OBJS): CPPFLAGS += -DJEMALLOC_INTEGRATION_TEST
$(TESTS_STRESS_OBJS): CPPFLAGS += -DJEMALLOC_STRESS_TEST
$(TESTS_OBJS): $(objroot)test/%.$(O): $(srcroot)test/%.c
$(TESTS_OBJS): CPPFLAGS += -I$(srcroot)test/include -I$(objroot)test/include
ifneq ($(IMPORTLIB),$(SO))
$(C_OBJS): CPPFLAGS += -DDLLEXPORT
endif
ifndef CC_MM
# Dependencies.
HEADER_DIRS = $(srcroot)include/jemalloc/internal \
$(objroot)include/jemalloc $(objroot)include/jemalloc/internal
HEADERS = $(wildcard $(foreach dir,$(HEADER_DIRS),$(dir)/*.h))
$(C_OBJS) $(C_PIC_OBJS) $(C_JET_OBJS) $(C_TESTLIB_OBJS) $(TESTS_OBJS): $(HEADERS)
$(TESTS_OBJS): $(objroot)test/unit/jemalloc_test.h
endif
$(C_OBJS) $(C_PIC_OBJS) $(C_JET_OBJS) $(C_TESTLIB_OBJS) $(TESTS_OBJS): %.$(O):
@objroot@src/%.o: @srcroot@src/%.c
@mkdir -p $(@D)
$(CC) $(CFLAGS) -c $(CPPFLAGS) $(CTARGET) $<
ifdef CC_MM
@$(CC) -MM $(CPPFLAGS) -MT $@ -o $(@:%.$(O)=%.d) $<
endif
$(CC) $(CFLAGS) -c $(CPPFLAGS) -o $@ $<
@$(SHELL) -ec "$(CC) -MM $(CPPFLAGS) $< | sed \"s/\($(subst /,\/,$(notdir $(basename $@)))\)\.o\([ :]*\)/$(subst /,\/,$(strip $(dir $@)))\1.o \2/g\" > $(@:%.o=%.d)"
ifneq ($(SOREV),$(SO))
%.$(SO) : %.$(SOREV)
@objroot@src/%.pic.o: @srcroot@src/%.c
@mkdir -p $(@D)
$(CC) $(CFLAGS) -fPIC -DPIC -c $(CPPFLAGS) -o $@ $<
@$(SHELL) -ec "$(CC) -MM $(CPPFLAGS) $< | sed \"s/\($(subst /,\/,$(notdir $(basename $(basename $@))))\)\.o\([ :]*\)/$(subst /,\/,$(strip $(dir $@)))\1.pic.o \2/g\" > $(@:%.o=%.d)"
%.$(SO) : %.$(SO).$(REV)
@mkdir -p $(@D)
ln -sf $(<F) $@
@objroot@lib/libjemalloc@install_suffix@.$(SO).$(REV) : $(CSRCS:@srcroot@%.c=@objroot@%.pic.o)
@mkdir -p $(@D)
$(CC) -shared -Wl,-$(WL_SONAME),$(@F) $(RPATH_EXTRA:%=@RPATH@%) -o $@ $+ $(LDFLAGS) $(LIBS)
@objroot@lib/libjemalloc@install_suffix@_pic.a : $(CSRCS:@srcroot@%.c=@objroot@%.pic.o)
@mkdir -p $(@D)
ar crus $@ $+
@objroot@lib/libjemalloc@install_suffix@.a : $(CSRCS:@srcroot@%.c=@objroot@%.o)
@mkdir -p $(@D)
ar crus $@ $+
@objroot@test/%.o: @srcroot@test/%.c
@mkdir -p $(@D)
$(CC) $(CFLAGS) -c $(CPPFLAGS) -I@objroot@test -o $@ $<
@$(SHELL) -ec "$(CC) -MM $(CPPFLAGS) -I@objroot@test $< | sed \"s/\($(subst /,\/,$(notdir $(basename $@)))\)\.o\([ :]*\)/$(subst /,\/,$(strip $(dir $@)))\1.o \2/g\" > $(@:%.o=%.d)"
# Automatic dependency generation misses #include "*.c".
@objroot@test/bitmap.o : @objroot@src/bitmap.o
@objroot@test/%: @objroot@test/%.o \
@objroot@lib/libjemalloc@install_suffix@.$(SO)
@mkdir -p $(@D)
ifneq (@RPATH@, )
$(CC) -o $@ $< @RPATH@@objroot@lib -L@objroot@lib -ljemalloc@install_suffix@ -lpthread
else
$(CC) -o $@ $< -L@objroot@lib -ljemalloc@install_suffix@ -lpthread
endif
$(objroot)lib/$(LIBJEMALLOC).$(SOREV) : $(if $(PIC_CFLAGS),$(C_PIC_OBJS),$(C_OBJS))
@mkdir -p $(@D)
$(CC) $(DSO_LDFLAGS) $(call RPATH,$(RPATH_EXTRA)) $(LDTARGET) $+ $(LDFLAGS) $(LIBS) $(EXTRA_LDFLAGS)
$(objroot)lib/$(LIBJEMALLOC)_pic.$(A) : $(C_PIC_OBJS)
$(objroot)lib/$(LIBJEMALLOC).$(A) : $(C_OBJS)
$(objroot)lib/$(LIBJEMALLOC)_s.$(A) : $(C_OBJS)
$(STATIC_LIBS):
@mkdir -p $(@D)
$(AR) $(ARFLAGS)@AROUT@ $+
$(objroot)test/unit/%$(EXE): $(objroot)test/unit/%.$(O) $(TESTS_UNIT_LINK_OBJS) $(C_JET_OBJS) $(C_TESTLIB_UNIT_OBJS)
@mkdir -p $(@D)
$(CC) $(LDTARGET) $(filter %.$(O),$^) $(call RPATH,$(objroot)lib) $(LDFLAGS) $(filter-out -lm,$(LIBS)) -lm $(EXTRA_LDFLAGS)
$(objroot)test/integration/%$(EXE): $(objroot)test/integration/%.$(O) $(C_TESTLIB_INTEGRATION_OBJS) $(C_UTIL_INTEGRATION_OBJS) $(objroot)lib/$(LIBJEMALLOC).$(IMPORTLIB)
@mkdir -p $(@D)
$(CC) $(LDTARGET) $(filter %.$(O),$^) $(call RPATH,$(objroot)lib) $(objroot)lib/$(LIBJEMALLOC).$(IMPORTLIB) $(LDFLAGS) $(filter-out -lm,$(filter -lpthread,$(LIBS))) -lm $(EXTRA_LDFLAGS)
$(objroot)test/stress/%$(EXE): $(objroot)test/stress/%.$(O) $(C_JET_OBJS) $(C_TESTLIB_STRESS_OBJS) $(objroot)lib/$(LIBJEMALLOC).$(IMPORTLIB)
@mkdir -p $(@D)
$(CC) $(LDTARGET) $(filter %.$(O),$^) $(call RPATH,$(objroot)lib) $(objroot)lib/$(LIBJEMALLOC).$(IMPORTLIB) $(LDFLAGS) $(filter-out -lm,$(LIBS)) -lm $(EXTRA_LDFLAGS)
build_lib_shared: $(DSOS)
build_lib_static: $(STATIC_LIBS)
build_lib: build_lib_shared build_lib_static
install_bin:
install -d $(BINDIR)
@for b in $(BINS); do \
@@ -282,157 +150,110 @@ done
install_include:
install -d $(INCLUDEDIR)/jemalloc
@for h in $(C_HDRS); do \
@for h in $(CHDRS); do \
echo "install -m 644 $$h $(INCLUDEDIR)/jemalloc"; \
install -m 644 $$h $(INCLUDEDIR)/jemalloc; \
done
install_lib_shared: $(DSOS)
install_lib: $(DSOS) $(STATIC_LIBS)
install -d $(LIBDIR)
install -m 755 $(objroot)lib/$(LIBJEMALLOC).$(SOREV) $(LIBDIR)
ifneq ($(SOREV),$(SO))
ln -sf $(LIBJEMALLOC).$(SOREV) $(LIBDIR)/$(LIBJEMALLOC).$(SO)
endif
install -m 755 @objroot@lib/libjemalloc@install_suffix@.$(SO).$(REV) $(LIBDIR)
ln -sf libjemalloc@install_suffix@.$(SO).$(REV) $(LIBDIR)/libjemalloc@install_suffix@.$(SO)
install -m 755 @objroot@lib/libjemalloc@install_suffix@_pic.a $(LIBDIR)
install -m 755 @objroot@lib/libjemalloc@install_suffix@.a $(LIBDIR)
install_lib_static: $(STATIC_LIBS)
install -d $(LIBDIR)
@for l in $(STATIC_LIBS); do \
echo "install -m 755 $$l $(LIBDIR)"; \
install -m 755 $$l $(LIBDIR); \
done
install_lib: install_lib_shared install_lib_static
install_doc_html:
install -d $(DATADIR)/doc/jemalloc$(install_suffix)
install_html:
install -d $(DATADIR)/doc/jemalloc@install_suffix@
@for d in $(DOCS_HTML); do \
echo "install -m 644 $$d $(DATADIR)/doc/jemalloc$(install_suffix)"; \
install -m 644 $$d $(DATADIR)/doc/jemalloc$(install_suffix); \
echo "install -m 644 $$d $(DATADIR)/doc/jemalloc@install_suffix@"; \
install -m 644 $$d $(DATADIR)/doc/jemalloc@install_suffix@; \
done
install_doc_man:
install_man:
install -d $(MANDIR)/man3
@for d in $(DOCS_MAN3); do \
echo "install -m 644 $$d $(MANDIR)/man3"; \
install -m 644 $$d $(MANDIR)/man3; \
done
install_doc: install_doc_html install_doc_man
install_doc: install_html install_man
install: install_bin install_include install_lib install_doc
tests_unit: $(TESTS_UNIT:$(srcroot)%.c=$(objroot)%$(EXE))
tests_integration: $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%$(EXE))
tests_stress: $(TESTS_STRESS:$(srcroot)%.c=$(objroot)%$(EXE))
tests: tests_unit tests_integration tests_stress
tests: $(CTESTS:@srcroot@%.c=@objroot@%)
check_unit_dir:
@mkdir -p $(objroot)test/unit
check_integration_dir:
@mkdir -p $(objroot)test/integration
check_stress_dir:
@mkdir -p $(objroot)test/stress
check_dir: check_unit_dir check_integration_dir check_stress_dir
check_unit: tests_unit check_unit_dir
$(SHELL) $(objroot)test/test.sh $(TESTS_UNIT:$(srcroot)%.c=$(objroot)%)
check_integration: tests_integration check_integration_dir
$(SHELL) $(objroot)test/test.sh $(TESTS_INTEGRATION:$(srcroot)%.c=$(objroot)%)
check_stress: tests_stress check_stress_dir
$(SHELL) $(objroot)test/test.sh $(TESTS_STRESS:$(srcroot)%.c=$(objroot)%)
check: tests check_dir
$(SHELL) $(objroot)test/test.sh $(TESTS:$(srcroot)%.c=$(objroot)%)
ifeq ($(enable_code_coverage), 1)
coverage_unit: check_unit
$(SHELL) $(srcroot)coverage.sh $(srcroot)src jet $(C_JET_OBJS)
$(SHELL) $(srcroot)coverage.sh $(srcroot)test/src unit $(C_TESTLIB_UNIT_OBJS)
$(SHELL) $(srcroot)coverage.sh $(srcroot)test/unit unit $(TESTS_UNIT_OBJS)
coverage_integration: check_integration
$(SHELL) $(srcroot)coverage.sh $(srcroot)src pic $(C_PIC_OBJS)
$(SHELL) $(srcroot)coverage.sh $(srcroot)src integration $(C_UTIL_INTEGRATION_OBJS)
$(SHELL) $(srcroot)coverage.sh $(srcroot)test/src integration $(C_TESTLIB_INTEGRATION_OBJS)
$(SHELL) $(srcroot)coverage.sh $(srcroot)test/integration integration $(TESTS_INTEGRATION_OBJS)
coverage_stress: check_stress
$(SHELL) $(srcroot)coverage.sh $(srcroot)src pic $(C_PIC_OBJS)
$(SHELL) $(srcroot)coverage.sh $(srcroot)src jet $(C_JET_OBJS)
$(SHELL) $(srcroot)coverage.sh $(srcroot)test/src stress $(C_TESTLIB_STRESS_OBJS)
$(SHELL) $(srcroot)coverage.sh $(srcroot)test/stress stress $(TESTS_STRESS_OBJS)
coverage: check
$(SHELL) $(srcroot)coverage.sh $(srcroot)src pic $(C_PIC_OBJS)
$(SHELL) $(srcroot)coverage.sh $(srcroot)src jet $(C_JET_OBJS)
$(SHELL) $(srcroot)coverage.sh $(srcroot)src integration $(C_UTIL_INTEGRATION_OBJS)
$(SHELL) $(srcroot)coverage.sh $(srcroot)test/src unit $(C_TESTLIB_UNIT_OBJS)
$(SHELL) $(srcroot)coverage.sh $(srcroot)test/src integration $(C_TESTLIB_INTEGRATION_OBJS)
$(SHELL) $(srcroot)coverage.sh $(srcroot)test/src stress $(C_TESTLIB_STRESS_OBJS)
$(SHELL) $(srcroot)coverage.sh $(srcroot)test/unit unit $(TESTS_UNIT_OBJS) $(TESTS_UNIT_AUX_OBJS)
$(SHELL) $(srcroot)coverage.sh $(srcroot)test/integration integration $(TESTS_INTEGRATION_OBJS)
$(SHELL) $(srcroot)coverage.sh $(srcroot)test/stress integration $(TESTS_STRESS_OBJS)
endif
check: tests
@mkdir -p @objroot@test
@$(SHELL) -c 'total=0; \
failures=0; \
echo "========================================="; \
for t in $(CTESTS:@srcroot@%.c=@objroot@%); do \
total=`expr $$total + 1`; \
/bin/echo -n "$${t} ... "; \
$(TEST_LIBRARY_PATH) $${t} @abs_srcroot@ @abs_objroot@ \
> @objroot@$${t}.out 2>&1; \
if test -e "@srcroot@$${t}.exp"; then \
diff -u @srcroot@$${t}.exp \
@objroot@$${t}.out >/dev/null 2>&1; \
fail=$$?; \
if test "$${fail}" -eq "1" ; then \
failures=`expr $${failures} + 1`; \
echo "*** FAIL ***"; \
else \
echo "pass"; \
fi; \
else \
echo "*** FAIL *** (.exp file is missing)"; \
failures=`expr $${failures} + 1`; \
fi; \
done; \
echo "========================================="; \
echo "Failures: $${failures}/$${total}"'
clean:
rm -f $(C_OBJS)
rm -f $(C_PIC_OBJS)
rm -f $(C_JET_OBJS)
rm -f $(C_TESTLIB_OBJS)
rm -f $(C_OBJS:%.$(O)=%.d)
rm -f $(C_OBJS:%.$(O)=%.gcda)
rm -f $(C_OBJS:%.$(O)=%.gcno)
rm -f $(C_PIC_OBJS:%.$(O)=%.d)
rm -f $(C_PIC_OBJS:%.$(O)=%.gcda)
rm -f $(C_PIC_OBJS:%.$(O)=%.gcno)
rm -f $(C_JET_OBJS:%.$(O)=%.d)
rm -f $(C_JET_OBJS:%.$(O)=%.gcda)
rm -f $(C_JET_OBJS:%.$(O)=%.gcno)
rm -f $(C_TESTLIB_OBJS:%.$(O)=%.d)
rm -f $(C_TESTLIB_OBJS:%.$(O)=%.gcda)
rm -f $(C_TESTLIB_OBJS:%.$(O)=%.gcno)
rm -f $(TESTS_OBJS:%.$(O)=%$(EXE))
rm -f $(TESTS_OBJS)
rm -f $(TESTS_OBJS:%.$(O)=%.d)
rm -f $(TESTS_OBJS:%.$(O)=%.gcda)
rm -f $(TESTS_OBJS:%.$(O)=%.gcno)
rm -f $(TESTS_OBJS:%.$(O)=%.out)
rm -f $(CSRCS:@srcroot@%.c=@objroot@%.o)
rm -f $(CSRCS:@srcroot@%.c=@objroot@%.pic.o)
rm -f $(CSRCS:@srcroot@%.c=@objroot@%.d)
rm -f $(CSRCS:@srcroot@%.c=@objroot@%.pic.d)
rm -f $(CTESTS:@srcroot@%.c=@objroot@%)
rm -f $(CTESTS:@srcroot@%.c=@objroot@%.o)
rm -f $(CTESTS:@srcroot@%.c=@objroot@%.d)
rm -f $(CTESTS:@srcroot@%.c=@objroot@%.out)
rm -f $(DSOS) $(STATIC_LIBS)
rm -f $(objroot)*.gcov.*
distclean: clean
rm -rf $(objroot)autom4te.cache
rm -f $(objroot)bin/jemalloc.sh
rm -f $(objroot)config.log
rm -f $(objroot)config.status
rm -f $(objroot)config.stamp
rm -f $(cfghdrs_out)
rm -f $(cfgoutputs_out)
rm -rf @objroot@autom4te.cache
rm -f @objroot@config.log
rm -f @objroot@config.status
rm -f @objroot@config.stamp
rm -f @cfghdrs_out@
rm -f @cfgoutputs_out@
relclean: distclean
rm -f $(objroot)configure
rm -f $(srcroot)VERSION
rm -f @objroot@configure
rm -f @srcroot@VERSION
rm -f $(DOCS_HTML)
rm -f $(DOCS_MAN3)
#===============================================================================
# Re-configuration rules.
ifeq ($(enable_autogen), 1)
$(srcroot)configure : $(srcroot)configure.ac
cd ./$(srcroot) && $(AUTOCONF)
ifeq (@enable_autogen@, 1)
@srcroot@configure : @srcroot@configure.ac
cd ./@srcroot@ && @AUTOCONF@
$(objroot)config.status : $(srcroot)configure
./$(objroot)config.status --recheck
@objroot@config.status : @srcroot@configure
./@objroot@config.status --recheck
$(srcroot)config.stamp.in : $(srcroot)configure.ac
echo stamp > $(srcroot)config.stamp.in
@srcroot@config.stamp.in : @srcroot@configure.ac
echo stamp > @srcroot@config.stamp.in
$(objroot)config.stamp : $(cfgoutputs_in) $(cfghdrs_in) $(srcroot)configure
./$(objroot)config.status
@objroot@config.stamp : @cfgoutputs_in@ @cfghdrs_in@ @srcroot@configure
./@objroot@config.status
@touch $@
# There must be some action in order for make to re-read Makefile when it is
# out of date.
$(cfgoutputs_out) $(cfghdrs_out) : $(objroot)config.stamp
@cfgoutputs_out@ @cfghdrs_out@ : @objroot@config.stamp
@true
endif
+7 -11
View File
@@ -1,14 +1,10 @@
jemalloc is a general purpose malloc(3) implementation that emphasizes
fragmentation avoidance and scalable concurrency support. jemalloc first came
into use as the FreeBSD libc allocator in 2005, and since then it has found its
way into numerous applications that rely on its predictable behavior. In 2010
jemalloc development efforts broadened to include developer support features
such as heap profiling, Valgrind integration, and extensive monitoring/tuning
hooks. Modern jemalloc releases continue to be integrated back into FreeBSD,
and therefore versatility remains critical. Ongoing development efforts trend
toward making jemalloc among the best allocators for a broad range of demanding
applications, and eliminating/mitigating weaknesses that have practical
repercussions for real world applications.
jemalloc is a general-purpose scalable concurrent malloc(3) implementation.
This distribution is a stand-alone "portable" implementation that currently
targets Linux and Apple OS X. jemalloc is included as the default allocator in
the FreeBSD and NetBSD operating systems, and it is used by the Mozilla Firefox
web browser on Microsoft Windows-related platforms. Depending on your needs,
one of the other divergent versions may suit your needs better than this
distribution.
The COPYING file contains copyright and licensing information.
+1 -1
View File
@@ -1 +1 @@
3.6.0-0-g46c0af68bd248b04df75e4f92d5fb804c3d75340
2.2.5-0-gfc1bb70e5f0d9a58b39efa39cc549b5af5104760
-9
View File
@@ -1,9 +0,0 @@
#!/bin/sh
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
@LD_PRELOAD_VAR@=${libdir}/libjemalloc.@SOREV@
export @LD_PRELOAD_VAR@
exec "$@"
+195 -674
View File
File diff suppressed because it is too large Load Diff
+505 -607
View File
File diff suppressed because it is too large Load Diff
+124 -368
View File
@@ -1,40 +1,42 @@
#! /bin/sh
# Configuration validation subroutine script.
# Copyright 1992-2013 Free Software Foundation, Inc.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
timestamp='2013-10-01'
timestamp='2004-02-23'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
# can handle that machine. It does not imply ALL GNU software can.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that
# program. This Exception is an additional permission under section 7
# of the GNU General Public License, version 3 ("GPLv3").
# the same distribution terms that you use for the rest of that program.
# Please send patches with a ChangeLog entry to config-patches@gnu.org.
# Please send patches to <config-patches@gnu.org>. Submit a context
# diff and a properly formatted ChangeLog entry.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
# If it is invalid, we print an error message on stderr and exit with code 1.
# Otherwise, we print the canonical config type on stdout and succeed.
# You can get the latest version of this script from:
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
# This file is supposed to be the same for all GNU packages
# and recognize all the CPU types, system types and aliases
# that are meaningful with *any* GNU software.
@@ -68,7 +70,8 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
Copyright 1992-2013 Free Software Foundation, Inc.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -80,11 +83,11 @@ Try \`$me --help' for more information."
while test $# -gt 0 ; do
case $1 in
--time-stamp | --time* | -t )
echo "$timestamp" ; exit ;;
echo "$timestamp" ; exit 0 ;;
--version | -v )
echo "$version" ; exit ;;
echo "$version" ; exit 0 ;;
--help | --h* | -h )
echo "$usage"; exit ;;
echo "$usage"; exit 0 ;;
-- ) # Stop option processing
shift; break ;;
- ) # Use stdin as input.
@@ -96,7 +99,7 @@ while test $# -gt 0 ; do
*local*)
# First pass through any local machine types.
echo $1
exit ;;
exit 0;;
* )
break ;;
@@ -115,18 +118,11 @@ esac
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
knetbsd*-gnu* | netbsd*-gnu* | \
kopensolaris*-gnu* | \
storm-chaos* | os2-emx* | rtmk-nova*)
nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \
kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
android-linux)
os=-linux-android
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
;;
*)
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
if [ $basic_machine != $1 ]
@@ -149,13 +145,10 @@ case $os in
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-apple | -axis | -knuth | -cray | -microblaze*)
-apple | -axis)
os=
basic_machine=$1
;;
-bluegene*)
os=-cnk
;;
-sim | -cisco | -oki | -wec | -winbond)
os=
basic_machine=$1
@@ -170,17 +163,13 @@ case $os in
os=-chorusos
basic_machine=$1
;;
-chorusrdb)
os=-chorusrdb
-chorusrdb)
os=-chorusrdb
basic_machine=$1
;;
;;
-hiux*)
os=-hiuxwe2
;;
-sco6)
os=-sco5v6
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco5)
os=-sco3.2v5
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
@@ -197,10 +186,6 @@ case $os in
# Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco5v6*)
# Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco*)
os=-sco3.2v2
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
@@ -218,12 +203,6 @@ case $os in
-isc*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-lynx*178)
os=-lynxos178
;;
-lynx*5)
os=-lynxos5
;;
-lynx*)
os=-lynxos
;;
@@ -248,107 +227,57 @@ case $basic_machine in
# Some are omitted here because they have special meanings below.
1750a | 580 \
| a29k \
| aarch64 | aarch64_be \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
| arc | arceb \
| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
| avr | avr32 \
| be32 | be64 \
| bfin \
| c4x | c8051 | clipper \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
| c4x | clipper \
| d10v | d30v | dlx | dsp16xx \
| epiphany \
| fido | fr30 | frv \
| fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| hexagon \
| i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \
| k1om \
| le32 | le64 \
| lm32 \
| m32c | m32r | m32rle | m68000 | m68k | m88k \
| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
| m32r | m68000 | m68k | m88k | mcore \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64el \
| mips64octeon | mips64octeonel \
| mips64orion | mips64orionel \
| mips64r5900 | mips64r5900el \
| mips64vr | mips64vrel \
| mips64orion | mips64orionel \
| mips64vr4100 | mips64vr4100el \
| mips64vr4300 | mips64vr4300el \
| mips64vr5000 | mips64vr5000el \
| mips64vr5900 | mips64vr5900el \
| mipsisa32 | mipsisa32el \
| mipsisa32r2 | mipsisa32r2el \
| mipsisa64 | mipsisa64el \
| mipsisa64r2 | mipsisa64r2el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
| mipsr5900 | mipsr5900el \
| mipstx39 | mipstx39el \
| mn10200 | mn10300 \
| moxie \
| mt \
| msp430 \
| nds32 | nds32le | nds32be \
| nios | nios2 | nios2eb | nios2el \
| ns16k | ns32k \
| open8 \
| or1k | or32 \
| openrisc | or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle \
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
| pyramid \
| rl78 | rx \
| score \
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
| spu \
| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
| ubicom32 \
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
| strongarm \
| tahoe | thumb | tic4x | tic80 | tron \
| v850 | v850e \
| we32k \
| x86 | xc16x | xstormy16 | xtensa \
| z8k | z80)
| x86 | xscale | xstormy16 | xtensa \
| z8k)
basic_machine=$basic_machine-unknown
;;
c54x)
basic_machine=tic54x-unknown
;;
c55x)
basic_machine=tic55x-unknown
;;
c6x)
basic_machine=tic6x-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
m6811 | m68hc11 | m6812 | m68hc12)
# Motorola 68HC11/12.
basic_machine=$basic_machine-unknown
os=-none
;;
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
;;
ms1)
basic_machine=mt-unknown
;;
strongarm | thumb | xscale)
basic_machine=arm-unknown
;;
xgate)
basic_machine=$basic_machine-unknown
os=-none
;;
xscaleeb)
basic_machine=armeb-unknown
;;
xscaleel)
basic_machine=armel-unknown
;;
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
@@ -364,83 +293,59 @@ case $basic_machine in
# Recognize the basic CPU types with company name.
580-* \
| a29k-* \
| aarch64-* | aarch64_be-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* | avr32-* \
| be32-* | be64-* \
| bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* \
| c8051-* | clipper-* | craynv-* | cydra-* \
| avr-* \
| bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
| clipper-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| hexagon-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* | iq2000-* \
| k1om-* \
| le32-* | le64-* \
| lm32-* \
| m32c-* | m32r-* | m32rle-* \
| m32r-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
| microblaze-* | microblazeel-* \
| m88110-* | m88k-* | mcore-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
| mips16-* \
| mips64-* | mips64el-* \
| mips64octeon-* | mips64octeonel-* \
| mips64orion-* | mips64orionel-* \
| mips64r5900-* | mips64r5900el-* \
| mips64vr-* | mips64vrel-* \
| mips64orion-* | mips64orionel-* \
| mips64vr4100-* | mips64vr4100el-* \
| mips64vr4300-* | mips64vr4300el-* \
| mips64vr5000-* | mips64vr5000el-* \
| mips64vr5900-* | mips64vr5900el-* \
| mipsisa32-* | mipsisa32el-* \
| mipsisa32r2-* | mipsisa32r2el-* \
| mipsisa64-* | mipsisa64el-* \
| mipsisa64r2-* | mipsisa64r2el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
| mipsr5900-* | mipsr5900el-* \
| mipstx39-* | mipstx39el-* \
| mmix-* \
| mt-* \
| msp430-* \
| nds32-* | nds32le-* | nds32be-* \
| nios-* | nios2-* | nios2eb-* | nios2el-* \
| none-* | np1-* | ns16k-* | ns32k-* \
| open8-* \
| none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
| pyramid-* \
| rl78-* | romp-* | rs6000-* | rx-* \
| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| romp-* | rs6000-* \
| sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
| sparclite-* \
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
| tahoe-* \
| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
| tahoe-* | thumb-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
| tile*-* \
| tron-* \
| ubicom32-* \
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
| vax-* \
| v850-* | v850e-* | vax-* \
| we32k-* \
| x86-* | x86_64-* | xc16x-* | xps100-* \
| xstormy16-* | xtensa*-* \
| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
| xtensa-* \
| ymp-* \
| z8k-* | z80-*)
;;
# Recognize the basic CPU types without company name, with glob match.
xtensa*)
basic_machine=$basic_machine-unknown
| z8k-*)
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
@@ -458,7 +363,7 @@ case $basic_machine in
basic_machine=a29k-amd
os=-udi
;;
abacus)
abacus)
basic_machine=abacus-unknown
;;
adobe68k)
@@ -504,10 +409,6 @@ case $basic_machine in
basic_machine=m68k-apollo
os=-bsd
;;
aros)
basic_machine=i386-pc
os=-aros
;;
aux)
basic_machine=m68k-apple
os=-aux
@@ -516,35 +417,10 @@ case $basic_machine in
basic_machine=ns32k-sequent
os=-dynix
;;
blackfin)
basic_machine=bfin-unknown
os=-linux
;;
blackfin-*)
basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
bluegene*)
basic_machine=powerpc-ibm
os=-cnk
;;
c54x-*)
basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
c55x-*)
basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
c6x-*)
basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
c90)
basic_machine=c90-cray
os=-unicos
;;
cegcc)
basic_machine=arm-unknown
os=-cegcc
;;
convex-c1)
basic_machine=c1-convex
os=-bsd
@@ -569,20 +445,13 @@ case $basic_machine in
basic_machine=j90-cray
os=-unicos
;;
craynv)
basic_machine=craynv-cray
os=-unicosmp
;;
cr16 | cr16-*)
basic_machine=cr16-unknown
cr16c)
basic_machine=cr16c-unknown
os=-elf
;;
crds | unos)
basic_machine=m68k-crds
;;
crisv32 | crisv32-* | etraxfs*)
basic_machine=crisv32-axis
;;
cris | cris-* | etrax*)
basic_machine=cris-axis
;;
@@ -612,14 +481,6 @@ case $basic_machine in
basic_machine=m88k-motorola
os=-sysv3
;;
dicos)
basic_machine=i686-pc
os=-dicos
;;
djgpp)
basic_machine=i586-pc
os=-msdosdjgpp
;;
dpx20 | dpx20-*)
basic_machine=rs6000-bull
os=-bosx
@@ -731,6 +592,7 @@ case $basic_machine in
i370-ibm* | ibm*)
basic_machine=i370-ibm
;;
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
i*86v32)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv32
@@ -769,14 +631,6 @@ case $basic_machine in
basic_machine=m68k-isi
os=-sysv
;;
m68knommu)
basic_machine=m68k-unknown
os=-linux
;;
m68knommu-*)
basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
m88k-omron*)
basic_machine=m88k-omron
;;
@@ -788,21 +642,10 @@ case $basic_machine in
basic_machine=ns32k-utek
os=-sysv
;;
microblaze*)
basic_machine=microblaze-xilinx
;;
mingw64)
basic_machine=x86_64-pc
os=-mingw64
;;
mingw32)
basic_machine=i686-pc
basic_machine=i386-pc
os=-mingw32
;;
mingw32ce)
basic_machine=arm-unknown
os=-mingw32ce
;;
miniframe)
basic_machine=m68000-convergent
;;
@@ -816,6 +659,10 @@ case $basic_machine in
mips3*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
;;
mmix*)
basic_machine=mmix-knuth
os=-mmixware
;;
monitor)
basic_machine=m68k-rom68k
os=-coff
@@ -828,21 +675,10 @@ case $basic_machine in
basic_machine=i386-pc
os=-msdos
;;
ms1-*)
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
;;
msys)
basic_machine=i686-pc
os=-msys
;;
mvs)
basic_machine=i370-ibm
os=-mvs
;;
nacl)
basic_machine=le32-unknown
os=-nacl
;;
ncr3000)
basic_machine=i486-ncr
os=-sysv4
@@ -907,11 +743,9 @@ case $basic_machine in
np1)
basic_machine=np1-gould
;;
neo-tandem)
basic_machine=neo-tandem
;;
nse-tandem)
basic_machine=nse-tandem
nv1)
basic_machine=nv1-cray
os=-unicosmp
;;
nsr-tandem)
basic_machine=nsr-tandem
@@ -920,8 +754,9 @@ case $basic_machine in
basic_machine=hppa1.1-oki
os=-proelf
;;
openrisc | openrisc-*)
or32 | or32-*)
basic_machine=or32-unknown
os=-coff
;;
os400)
basic_machine=powerpc-ibm
@@ -943,14 +778,6 @@ case $basic_machine in
basic_machine=i860-intel
os=-osf
;;
parisc)
basic_machine=hppa-unknown
os=-linux
;;
parisc-*)
basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
os=-linux
;;
pbd)
basic_machine=sparc-tti
;;
@@ -960,12 +787,6 @@ case $basic_machine in
pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
pc98)
basic_machine=i386-pc
;;
pc98-*)
basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentium | p5 | k5 | k6 | nexgen | viac3)
basic_machine=i586-pc
;;
@@ -995,10 +816,9 @@ case $basic_machine in
;;
power) basic_machine=power-ibm
;;
ppc | ppcbe) basic_machine=powerpc-unknown
ppc) basic_machine=powerpc-unknown
;;
ppc-* | ppcbe-*)
basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppcle | powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown
@@ -1023,14 +843,6 @@ case $basic_machine in
basic_machine=i586-unknown
os=-pw32
;;
rdos | rdos64)
basic_machine=x86_64-pc
os=-rdos
;;
rdos32)
basic_machine=i386-pc
os=-rdos
;;
rom68k)
basic_machine=m68k-rom68k
os=-coff
@@ -1057,10 +869,6 @@ case $basic_machine in
sb1el)
basic_machine=mipsisa64sb1el-unknown
;;
sde)
basic_machine=mipsisa32-sde
os=-elf
;;
sei)
basic_machine=mips-sei
os=-seiux
@@ -1072,9 +880,6 @@ case $basic_machine in
basic_machine=sh-hitachi
os=-hms
;;
sh5el)
basic_machine=sh5le-unknown
;;
sh64)
basic_machine=sh64-unknown
;;
@@ -1096,9 +901,6 @@ case $basic_machine in
basic_machine=i860-stratus
os=-sysv4
;;
strongarm-* | thumb-*)
basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
sun2)
basic_machine=m68000-sun
;;
@@ -1155,9 +957,17 @@ case $basic_machine in
basic_machine=t90-cray
os=-unicos
;;
tile*)
basic_machine=$basic_machine-unknown
os=-linux-gnu
tic54x | c54x*)
basic_machine=tic54x-unknown
os=-coff
;;
tic55x | c55x*)
basic_machine=tic55x-unknown
os=-coff
;;
tic6x | c6x*)
basic_machine=tic6x-unknown
os=-coff
;;
tx39)
basic_machine=mipstx39-unknown
@@ -1219,16 +1029,9 @@ case $basic_machine in
basic_machine=hppa1.1-winbond
os=-proelf
;;
xbox)
basic_machine=i686-pc
os=-mingw32
;;
xps | xps100)
basic_machine=xps100-honeywell
;;
xscale-* | xscalee[bl]-*)
basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
;;
ymp)
basic_machine=ymp-cray
os=-unicos
@@ -1237,10 +1040,6 @@ case $basic_machine in
basic_machine=z8k-unknown
os=-sim
;;
z80-*-coff)
basic_machine=z80-unknown
os=-sim
;;
none)
basic_machine=none-none
os=-none
@@ -1260,9 +1059,6 @@ case $basic_machine in
romp)
basic_machine=romp-ibm
;;
mmix)
basic_machine=mmix-knuth
;;
rs6000)
basic_machine=rs6000-ibm
;;
@@ -1279,10 +1075,13 @@ case $basic_machine in
we32k)
basic_machine=we32k-att
;;
sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
basic_machine=sh-unknown
;;
sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
sh64)
basic_machine=sh64-unknown
;;
sparc | sparcv9 | sparcv9b)
basic_machine=sparc-sun
;;
cydra)
@@ -1326,12 +1125,9 @@ esac
if [ x"$os" != x"" ]
then
case $os in
# First match some system type aliases
# that might get confused with valid system types.
# First match some system type aliases
# that might get confused with valid system types.
# -solaris* is a basic system type, with this one exception.
-auroraux)
os=-auroraux
;;
-solaris1 | -solaris1.*)
os=`echo $os | sed -e 's|solaris1|sunos4|'`
;;
@@ -1352,31 +1148,26 @@ case $os in
# Each alternative MUST END IN A *, to match a version number.
# -sysv* is not here because it comes later, after sysvr4.
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
| -sym* | -kopensolaris* | -plan9* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
| -aos* | -aros* \
| -aos* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
| -bitrig* | -openbsd* | -solidbsd* \
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* | -cegcc* \
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* \
| -chorusos* | -chorusrdb* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1394,7 +1185,7 @@ case $os in
os=`echo $os | sed -e 's|nto|nto-qnx|'`
;;
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
| -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
| -windows* | -osx | -abug | -netware* | -os9* | -beos* \
| -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
;;
-mac*)
@@ -1415,7 +1206,7 @@ case $os in
-opened*)
os=-openedition
;;
-os400*)
-os400*)
os=-os400
;;
-wince*)
@@ -1464,7 +1255,7 @@ case $os in
-sinix*)
os=-sysv4
;;
-tpf*)
-tpf*)
os=-tpf
;;
-triton*)
@@ -1500,13 +1291,8 @@ case $os in
-aros*)
os=-aros
;;
-zvmoe)
os=-zvmoe
;;
-dicos*)
os=-dicos
;;
-nacl*)
-kaos*)
os=-kaos
;;
-none)
;;
@@ -1530,12 +1316,6 @@ else
# system, and we'll never get to this point.
case $basic_machine in
score-*)
os=-elf
;;
spu-*)
os=-elf
;;
*-acorn)
os=-riscix1.2
;;
@@ -1545,24 +1325,9 @@ case $basic_machine in
arm*-semi)
os=-aout
;;
c4x-* | tic4x-*)
os=-coff
;;
c8051-*)
os=-elf
;;
hexagon-*)
os=-elf
;;
tic54x-*)
os=-coff
;;
tic55x-*)
os=-coff
;;
tic6x-*)
os=-coff
;;
c4x-* | tic4x-*)
os=-coff
;;
# This must come before the *-dec entry.
pdp10-*)
os=-tops20
@@ -1581,22 +1346,19 @@ case $basic_machine in
;;
m68000-sun)
os=-sunos3
# This also exists in the configure program, but was not the
# default.
# os=-sunos4
;;
m68*-cisco)
os=-aout
;;
mep-*)
os=-elf
;;
mips*-cisco)
os=-elf
;;
mips*-*)
os=-elf
;;
or1k-*)
os=-elf
;;
or32-*)
os=-coff
;;
@@ -1609,15 +1371,9 @@ case $basic_machine in
*-be)
os=-beos
;;
*-haiku)
os=-haiku
;;
*-ibm)
os=-aix
;;
*-knuth)
os=-mmixware
;;
*-wec)
os=-proelf
;;
@@ -1720,7 +1476,7 @@ case $basic_machine in
-sunos*)
vendor=sun
;;
-cnk*|-aix*)
-aix*)
vendor=ibm
;;
-beos*)
@@ -1783,7 +1539,7 @@ case $basic_machine in
esac
echo $basic_machine$os
exit
exit 0
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
+1101 -2649
View File
File diff suppressed because it is too large Load Diff
+237 -786
View File
File diff suppressed because it is too large Load Diff
-16
View File
@@ -1,16 +0,0 @@
#!/bin/sh
set -e
objdir=$1
suffix=$2
shift 2
objs=$@
gcov -b -p -f -o "${objdir}" ${objs}
# Move gcov outputs so that subsequent gcov invocations won't clobber results
# for the same sources with different compilation flags.
for f in `find . -maxdepth 1 -type f -name '*.gcov'` ; do
mv "${f}" "${f}.${suffix}"
done
+310 -465
View File
File diff suppressed because it is too large Load Diff
+507 -489
View File
File diff suppressed because one or more lines are too long
+592 -657
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+21 -156
View File
@@ -11,8 +11,22 @@
#define atomic_read_uint64(p) atomic_add_uint64(p, 0)
#define atomic_read_uint32(p) atomic_add_uint32(p, 0)
#define atomic_read_z(p) atomic_add_z(p, 0)
#define atomic_read_u(p) atomic_add_u(p, 0)
#if (LG_SIZEOF_PTR == 3)
# define atomic_read_z(p) \
(size_t)atomic_add_uint64((uint64_t *)p, (uint64_t)0)
# define atomic_add_z(p, x) \
(size_t)atomic_add_uint64((uint64_t *)p, (uint64_t)x)
# define atomic_sub_z(p, x) \
(size_t)atomic_sub_uint64((uint64_t *)p, (uint64_t)x)
#elif (LG_SIZEOF_PTR == 2)
# define atomic_read_z(p) \
(size_t)atomic_add_uint32((uint32_t *)p, (uint32_t)0)
# define atomic_add_z(p, x) \
(size_t)atomic_add_uint32((uint32_t *)p, (uint32_t)x)
# define atomic_sub_z(p, x) \
(size_t)atomic_sub_uint32((uint32_t *)p, (uint32_t)x)
#endif
#endif /* JEMALLOC_H_EXTERNS */
/******************************************************************************/
@@ -23,17 +37,12 @@ uint64_t atomic_add_uint64(uint64_t *p, uint64_t x);
uint64_t atomic_sub_uint64(uint64_t *p, uint64_t x);
uint32_t atomic_add_uint32(uint32_t *p, uint32_t x);
uint32_t atomic_sub_uint32(uint32_t *p, uint32_t x);
size_t atomic_add_z(size_t *p, size_t x);
size_t atomic_sub_z(size_t *p, size_t x);
unsigned atomic_add_u(unsigned *p, unsigned x);
unsigned atomic_sub_u(unsigned *p, unsigned x);
#endif
#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_ATOMIC_C_))
/******************************************************************************/
/* 64-bit operations. */
#if (LG_SIZEOF_PTR == 3 || LG_SIZEOF_INT == 3)
# ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
JEMALLOC_INLINE uint64_t
atomic_add_uint64(uint64_t *p, uint64_t x)
{
@@ -47,20 +56,6 @@ atomic_sub_uint64(uint64_t *p, uint64_t x)
return (__sync_sub_and_fetch(p, x));
}
#elif (defined(_MSC_VER))
JEMALLOC_INLINE uint64_t
atomic_add_uint64(uint64_t *p, uint64_t x)
{
return (InterlockedExchangeAdd64(p, x));
}
JEMALLOC_INLINE uint64_t
atomic_sub_uint64(uint64_t *p, uint64_t x)
{
return (InterlockedExchangeAdd64(p, -((int64_t)x)));
}
#elif (defined(JEMALLOC_OSATOMIC))
JEMALLOC_INLINE uint64_t
atomic_add_uint64(uint64_t *p, uint64_t x)
@@ -75,7 +70,7 @@ atomic_sub_uint64(uint64_t *p, uint64_t x)
return (OSAtomicAdd64(-((int64_t)x), (int64_t *)p));
}
# elif (defined(__amd64__) || defined(__x86_64__))
#elif (defined(__amd64_) || defined(__x86_64__))
JEMALLOC_INLINE uint64_t
atomic_add_uint64(uint64_t *p, uint64_t x)
{
@@ -102,43 +97,8 @@ atomic_sub_uint64(uint64_t *p, uint64_t x)
return (x);
}
# elif (defined(JEMALLOC_ATOMIC9))
JEMALLOC_INLINE uint64_t
atomic_add_uint64(uint64_t *p, uint64_t x)
{
/*
* atomic_fetchadd_64() doesn't exist, but we only ever use this
* function on LP64 systems, so atomic_fetchadd_long() will do.
*/
assert(sizeof(uint64_t) == sizeof(unsigned long));
return (atomic_fetchadd_long(p, (unsigned long)x) + x);
}
JEMALLOC_INLINE uint64_t
atomic_sub_uint64(uint64_t *p, uint64_t x)
{
assert(sizeof(uint64_t) == sizeof(unsigned long));
return (atomic_fetchadd_long(p, (unsigned long)(-(long)x)) - x);
}
# elif (defined(JE_FORCE_SYNC_COMPARE_AND_SWAP_8))
JEMALLOC_INLINE uint64_t
atomic_add_uint64(uint64_t *p, uint64_t x)
{
return (__sync_add_and_fetch(p, x));
}
JEMALLOC_INLINE uint64_t
atomic_sub_uint64(uint64_t *p, uint64_t x)
{
return (__sync_sub_and_fetch(p, x));
}
# else
#else
# if (LG_SIZEOF_PTR == 3)
# error "Missing implementation for 64-bit atomic operations"
# endif
#endif
@@ -159,20 +119,6 @@ atomic_sub_uint32(uint32_t *p, uint32_t x)
return (__sync_sub_and_fetch(p, x));
}
#elif (defined(_MSC_VER))
JEMALLOC_INLINE uint32_t
atomic_add_uint32(uint32_t *p, uint32_t x)
{
return (InterlockedExchangeAdd(p, x));
}
JEMALLOC_INLINE uint32_t
atomic_sub_uint32(uint32_t *p, uint32_t x)
{
return (InterlockedExchangeAdd(p, -((int32_t)x)));
}
#elif (defined(JEMALLOC_OSATOMIC))
JEMALLOC_INLINE uint32_t
atomic_add_uint32(uint32_t *p, uint32_t x)
@@ -187,7 +133,7 @@ atomic_sub_uint32(uint32_t *p, uint32_t x)
return (OSAtomicAdd32(-((int32_t)x), (int32_t *)p));
}
#elif (defined(__i386__) || defined(__amd64__) || defined(__x86_64__))
#elif (defined(__i386__) || defined(__amd64_) || defined(__x86_64__))
JEMALLOC_INLINE uint32_t
atomic_add_uint32(uint32_t *p, uint32_t x)
{
@@ -214,90 +160,9 @@ atomic_sub_uint32(uint32_t *p, uint32_t x)
return (x);
}
#elif (defined(JEMALLOC_ATOMIC9))
JEMALLOC_INLINE uint32_t
atomic_add_uint32(uint32_t *p, uint32_t x)
{
return (atomic_fetchadd_32(p, x) + x);
}
JEMALLOC_INLINE uint32_t
atomic_sub_uint32(uint32_t *p, uint32_t x)
{
return (atomic_fetchadd_32(p, (uint32_t)(-(int32_t)x)) - x);
}
#elif (defined(JE_FORCE_SYNC_COMPARE_AND_SWAP_4))
JEMALLOC_INLINE uint32_t
atomic_add_uint32(uint32_t *p, uint32_t x)
{
return (__sync_add_and_fetch(p, x));
}
JEMALLOC_INLINE uint32_t
atomic_sub_uint32(uint32_t *p, uint32_t x)
{
return (__sync_sub_and_fetch(p, x));
}
#else
# error "Missing implementation for 32-bit atomic operations"
#endif
/******************************************************************************/
/* size_t operations. */
JEMALLOC_INLINE size_t
atomic_add_z(size_t *p, size_t x)
{
#if (LG_SIZEOF_PTR == 3)
return ((size_t)atomic_add_uint64((uint64_t *)p, (uint64_t)x));
#elif (LG_SIZEOF_PTR == 2)
return ((size_t)atomic_add_uint32((uint32_t *)p, (uint32_t)x));
#endif
}
JEMALLOC_INLINE size_t
atomic_sub_z(size_t *p, size_t x)
{
#if (LG_SIZEOF_PTR == 3)
return ((size_t)atomic_add_uint64((uint64_t *)p,
(uint64_t)-((int64_t)x)));
#elif (LG_SIZEOF_PTR == 2)
return ((size_t)atomic_add_uint32((uint32_t *)p,
(uint32_t)-((int32_t)x)));
#endif
}
/******************************************************************************/
/* unsigned operations. */
JEMALLOC_INLINE unsigned
atomic_add_u(unsigned *p, unsigned x)
{
#if (LG_SIZEOF_INT == 3)
return ((unsigned)atomic_add_uint64((uint64_t *)p, (uint64_t)x));
#elif (LG_SIZEOF_INT == 2)
return ((unsigned)atomic_add_uint32((uint32_t *)p, (uint32_t)x));
#endif
}
JEMALLOC_INLINE unsigned
atomic_sub_u(unsigned *p, unsigned x)
{
#if (LG_SIZEOF_INT == 3)
return ((unsigned)atomic_add_uint64((uint64_t *)p,
(uint64_t)-((int64_t)x)));
#elif (LG_SIZEOF_INT == 2)
return ((unsigned)atomic_add_uint32((uint32_t *)p,
(uint32_t)-((int32_t)x)));
#endif
}
/******************************************************************************/
#endif
#endif /* JEMALLOC_H_INLINES */
+2 -4
View File
@@ -9,14 +9,12 @@
/******************************************************************************/
#ifdef JEMALLOC_H_EXTERNS
extern malloc_mutex_t base_mtx;
void *base_alloc(size_t size);
void *base_calloc(size_t number, size_t size);
extent_node_t *base_node_alloc(void);
void base_node_dealloc(extent_node_t *node);
bool base_boot(void);
void base_prefork(void);
void base_postfork_parent(void);
void base_postfork_child(void);
#endif /* JEMALLOC_H_EXTERNS */
/******************************************************************************/
+9 -7
View File
@@ -28,14 +28,20 @@
#ifdef JEMALLOC_H_EXTERNS
extern size_t opt_lg_chunk;
extern const char *opt_dss;
#ifdef JEMALLOC_SWAP
extern bool opt_overcommit;
#endif
#if (defined(JEMALLOC_STATS) || defined(JEMALLOC_PROF))
/* Protects stats_chunks; currently not used for any other purpose. */
extern malloc_mutex_t chunks_mtx;
/* Chunk statistics. */
extern chunk_stats_t stats_chunks;
#endif
#ifdef JEMALLOC_IVSALLOC
extern rtree_t *chunks_rtree;
#endif
extern size_t chunksize;
extern size_t chunksize_mask; /* (chunksize - 1). */
@@ -43,14 +49,9 @@ extern size_t chunk_npages;
extern size_t map_bias; /* Number of arena chunk header pages. */
extern size_t arena_maxclass; /* Max size class for arenas. */
void *chunk_alloc(size_t size, size_t alignment, bool base, bool *zero,
dss_prec_t dss_prec);
void chunk_unmap(void *chunk, size_t size);
void *chunk_alloc(size_t size, bool base, bool *zero);
void chunk_dealloc(void *chunk, size_t size, bool unmap);
bool chunk_boot(void);
void chunk_prefork(void);
void chunk_postfork_parent(void);
void chunk_postfork_child(void);
#endif /* JEMALLOC_H_EXTERNS */
/******************************************************************************/
@@ -59,5 +60,6 @@ void chunk_postfork_child(void);
#endif /* JEMALLOC_H_INLINES */
/******************************************************************************/
#include "jemalloc/internal/chunk_swap.h"
#include "jemalloc/internal/chunk_dss.h"
#include "jemalloc/internal/chunk_mmap.h"
+10 -18
View File
@@ -1,34 +1,25 @@
#ifdef JEMALLOC_DSS
/******************************************************************************/
#ifdef JEMALLOC_H_TYPES
typedef enum {
dss_prec_disabled = 0,
dss_prec_primary = 1,
dss_prec_secondary = 2,
dss_prec_limit = 3
} dss_prec_t;
#define DSS_PREC_DEFAULT dss_prec_secondary
#define DSS_DEFAULT "secondary"
#endif /* JEMALLOC_H_TYPES */
/******************************************************************************/
#ifdef JEMALLOC_H_STRUCTS
extern const char *dss_prec_names[];
#endif /* JEMALLOC_H_STRUCTS */
/******************************************************************************/
#ifdef JEMALLOC_H_EXTERNS
dss_prec_t chunk_dss_prec_get(void);
bool chunk_dss_prec_set(dss_prec_t dss_prec);
void *chunk_alloc_dss(size_t size, size_t alignment, bool *zero);
/*
* Protects sbrk() calls. This avoids malloc races among threads, though it
* does not protect against races with threads that call sbrk() directly.
*/
extern malloc_mutex_t dss_mtx;
void *chunk_alloc_dss(size_t size, bool *zero);
bool chunk_in_dss(void *chunk);
bool chunk_dealloc_dss(void *chunk, size_t size);
bool chunk_dss_boot(void);
void chunk_dss_prefork(void);
void chunk_dss_postfork_parent(void);
void chunk_dss_postfork_child(void);
#endif /* JEMALLOC_H_EXTERNS */
/******************************************************************************/
@@ -36,3 +27,4 @@ void chunk_dss_postfork_child(void);
#endif /* JEMALLOC_H_INLINES */
/******************************************************************************/
#endif /* JEMALLOC_DSS */
+4 -3
View File
@@ -9,10 +9,11 @@
/******************************************************************************/
#ifdef JEMALLOC_H_EXTERNS
bool pages_purge(void *addr, size_t length);
void *chunk_alloc_mmap(size_t size);
void *chunk_alloc_mmap_noreserve(size_t size);
void chunk_dealloc_mmap(void *chunk, size_t size);
void *chunk_alloc_mmap(size_t size, size_t alignment, bool *zero);
bool chunk_dealloc_mmap(void *chunk, size_t size);
bool chunk_mmap_boot(void);
#endif /* JEMALLOC_H_EXTERNS */
/******************************************************************************/
+34
View File
@@ -0,0 +1,34 @@
#ifdef JEMALLOC_SWAP
/******************************************************************************/
#ifdef JEMALLOC_H_TYPES
#endif /* JEMALLOC_H_TYPES */
/******************************************************************************/
#ifdef JEMALLOC_H_STRUCTS
#endif /* JEMALLOC_H_STRUCTS */
/******************************************************************************/
#ifdef JEMALLOC_H_EXTERNS
extern malloc_mutex_t swap_mtx;
extern bool swap_enabled;
extern bool swap_prezeroed;
extern size_t swap_nfds;
extern int *swap_fds;
#ifdef JEMALLOC_STATS
extern size_t swap_avail;
#endif
void *chunk_alloc_swap(size_t size, bool *zero);
bool chunk_in_swap(void *chunk);
bool chunk_dealloc_swap(void *chunk, size_t size);
bool chunk_swap_enable(const int *fds, unsigned nfds, bool prezeroed);
bool chunk_swap_boot(void);
#endif /* JEMALLOC_H_EXTERNS */
/******************************************************************************/
#ifdef JEMALLOC_H_INLINES
#endif /* JEMALLOC_H_INLINES */
/******************************************************************************/
#endif /* JEMALLOC_SWAP */
+12 -5
View File
@@ -5,7 +5,7 @@ typedef struct ckh_s ckh_t;
typedef struct ckhc_s ckhc_t;
/* Typedefs to allow easy function pointer passing. */
typedef void ckh_hash_t (const void *, size_t[2]);
typedef void ckh_hash_t (const void *, unsigned, size_t *, size_t *);
typedef bool ckh_keycomp_t (const void *, const void *);
/* Maintain counters used to get an idea of performance. */
@@ -17,7 +17,7 @@ typedef bool ckh_keycomp_t (const void *, const void *);
* There are 2^LG_CKH_BUCKET_CELLS cells in each hash table bucket. Try to fit
* one bucket per L1 cache line.
*/
#define LG_CKH_BUCKET_CELLS (LG_CACHELINE - LG_SIZEOF_PTR - 1)
#define LG_CKH_BUCKET_CELLS (LG_CACHELINE - LG_SIZEOF_PTR - 1)
#endif /* JEMALLOC_H_TYPES */
/******************************************************************************/
@@ -30,6 +30,11 @@ struct ckhc_s {
};
struct ckh_s {
#ifdef JEMALLOC_DEBUG
#define CKH_MAGIC 0x3af2489d
uint32_t magic;
#endif
#ifdef CKH_COUNT
/* Counters used to get an idea of performance. */
uint64_t ngrows;
@@ -42,7 +47,7 @@ struct ckh_s {
/* Used for pseudo-random number generation. */
#define CKH_A 1103515241
#define CKH_C 12347
uint32_t prng_state;
uint32_t prn_state;
/* Total number of items. */
size_t count;
@@ -75,9 +80,11 @@ bool ckh_insert(ckh_t *ckh, const void *key, const void *data);
bool ckh_remove(ckh_t *ckh, const void *searchkey, void **key,
void **data);
bool ckh_search(ckh_t *ckh, const void *seachkey, void **key, void **data);
void ckh_string_hash(const void *key, size_t r_hash[2]);
void ckh_string_hash(const void *key, unsigned minbits, size_t *hash1,
size_t *hash2);
bool ckh_string_keycomp(const void *k1, const void *k2);
void ckh_pointer_hash(const void *key, size_t r_hash[2]);
void ckh_pointer_hash(const void *key, unsigned minbits, size_t *hash1,
size_t *hash2);
bool ckh_pointer_keycomp(const void *k1, const void *k2);
#endif /* JEMALLOC_H_EXTERNS */
+32 -31
View File
@@ -2,8 +2,6 @@
#ifdef JEMALLOC_H_TYPES
typedef struct ctl_node_s ctl_node_t;
typedef struct ctl_named_node_s ctl_named_node_t;
typedef struct ctl_indexed_node_s ctl_indexed_node_t;
typedef struct ctl_arena_stats_s ctl_arena_stats_t;
typedef struct ctl_stats_s ctl_stats_t;
@@ -13,29 +11,28 @@ typedef struct ctl_stats_s ctl_stats_t;
struct ctl_node_s {
bool named;
};
struct ctl_named_node_s {
struct ctl_node_s node;
const char *name;
/* If (nchildren == 0), this is a terminal node. */
unsigned nchildren;
const ctl_node_t *children;
int (*ctl)(const size_t *, size_t, void *, size_t *,
void *, size_t);
};
struct ctl_indexed_node_s {
struct ctl_node_s node;
const ctl_named_node_t *(*index)(const size_t *, size_t, size_t);
union {
struct {
const char *name;
/* If (nchildren == 0), this is a terminal node. */
unsigned nchildren;
const ctl_node_t *children;
} named;
struct {
const ctl_node_t *(*index)(const size_t *, size_t,
size_t);
} indexed;
} u;
int (*ctl)(const size_t *, size_t, void *, size_t *, void *,
size_t);
};
struct ctl_arena_stats_s {
bool initialized;
unsigned nthreads;
const char *dss;
size_t pactive;
size_t pdirty;
#ifdef JEMALLOC_STATS
arena_stats_t astats;
/* Aggregate stats for small size classes, based on bin stats. */
@@ -44,11 +41,13 @@ struct ctl_arena_stats_s {
uint64_t ndalloc_small;
uint64_t nrequests_small;
malloc_bin_stats_t bstats[NBINS];
malloc_bin_stats_t *bstats; /* nbins elements. */
malloc_large_stats_t *lstats; /* nlclasses elements. */
#endif
};
struct ctl_stats_s {
#ifdef JEMALLOC_STATS
size_t allocated;
size_t active;
size_t mapped;
@@ -62,8 +61,11 @@ struct ctl_stats_s {
uint64_t nmalloc; /* huge_nmalloc */
uint64_t ndalloc; /* huge_ndalloc */
} huge;
unsigned narenas;
#endif
ctl_arena_stats_t *arenas; /* (narenas + 1) elements. */
#ifdef JEMALLOC_SWAP
size_t swap_avail;
#endif
};
#endif /* JEMALLOC_H_STRUCTS */
@@ -77,30 +79,29 @@ int ctl_nametomib(const char *name, size_t *mibp, size_t *miblenp);
int ctl_bymib(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
void *newp, size_t newlen);
bool ctl_boot(void);
void ctl_prefork(void);
void ctl_postfork_parent(void);
void ctl_postfork_child(void);
#define xmallctl(name, oldp, oldlenp, newp, newlen) do { \
if (je_mallctl(name, oldp, oldlenp, newp, newlen) \
if (JEMALLOC_P(mallctl)(name, oldp, oldlenp, newp, newlen) \
!= 0) { \
malloc_printf( \
"<jemalloc>: Failure in xmallctl(\"%s\", ...)\n", \
name); \
malloc_write("<jemalloc>: Failure in xmallctl(\""); \
malloc_write(name); \
malloc_write("\", ...)\n"); \
abort(); \
} \
} while (0)
#define xmallctlnametomib(name, mibp, miblenp) do { \
if (je_mallctlnametomib(name, mibp, miblenp) != 0) { \
malloc_printf("<jemalloc>: Failure in " \
"xmallctlnametomib(\"%s\", ...)\n", name); \
if (JEMALLOC_P(mallctlnametomib)(name, mibp, miblenp) != 0) { \
malloc_write( \
"<jemalloc>: Failure in xmallctlnametomib(\""); \
malloc_write(name); \
malloc_write("\", ...)\n"); \
abort(); \
} \
} while (0)
#define xmallctlbymib(mib, miblen, oldp, oldlenp, newp, newlen) do { \
if (je_mallctlbymib(mib, miblen, oldp, oldlenp, newp, \
if (JEMALLOC_P(mallctlbymib)(mib, miblen, oldp, oldlenp, newp, \
newlen) != 0) { \
malloc_write( \
"<jemalloc>: Failure in xmallctlbymib()\n"); \
+6 -3
View File
@@ -9,23 +9,24 @@ typedef struct extent_node_s extent_node_t;
/* Tree of extents. */
struct extent_node_s {
#if (defined(JEMALLOC_SWAP) || defined(JEMALLOC_DSS))
/* Linkage for the size/address-ordered tree. */
rb_node(extent_node_t) link_szad;
#endif
/* Linkage for the address-ordered tree. */
rb_node(extent_node_t) link_ad;
#ifdef JEMALLOC_PROF
/* Profile counters, used for huge objects. */
prof_ctx_t *prof_ctx;
#endif
/* Pointer to the extent that this tree node is responsible for. */
void *addr;
/* Total region size. */
size_t size;
/* True if zero-filled; used by chunk recycling code. */
bool zeroed;
};
typedef rb_tree(extent_node_t) extent_tree_t;
@@ -33,7 +34,9 @@ typedef rb_tree(extent_node_t) extent_tree_t;
/******************************************************************************/
#ifdef JEMALLOC_H_EXTERNS
#if (defined(JEMALLOC_SWAP) || defined(JEMALLOC_DSS))
rb_proto(, extent_tree_szad_, extent_tree_t, extent_node_t)
#endif
rb_proto(, extent_tree_ad_, extent_tree_t, extent_node_t)
+36 -301
View File
@@ -1,8 +1,3 @@
/*
* The following hash function is based on MurmurHash3, placed into the public
* domain by Austin Appleby. See http://code.google.com/p/smhasher/ for
* details.
*/
/******************************************************************************/
#ifdef JEMALLOC_H_TYPES
@@ -19,316 +14,56 @@
#ifdef JEMALLOC_H_INLINES
#ifndef JEMALLOC_ENABLE_INLINE
uint32_t hash_x86_32(const void *key, int len, uint32_t seed);
void hash_x86_128(const void *key, const int len, uint32_t seed,
uint64_t r_out[2]);
void hash_x64_128(const void *key, const int len, const uint32_t seed,
uint64_t r_out[2]);
void hash(const void *key, size_t len, const uint32_t seed,
size_t r_hash[2]);
uint64_t hash(const void *key, size_t len, uint64_t seed);
#endif
#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_HASH_C_))
/******************************************************************************/
/* Internal implementation. */
JEMALLOC_INLINE uint32_t
hash_rotl_32(uint32_t x, int8_t r)
{
return (x << r) | (x >> (32 - r));
}
/*
* The following hash function is based on MurmurHash64A(), placed into the
* public domain by Austin Appleby. See http://murmurhash.googlepages.com/ for
* details.
*/
JEMALLOC_INLINE uint64_t
hash_rotl_64(uint64_t x, int8_t r)
hash(const void *key, size_t len, uint64_t seed)
{
return (x << r) | (x >> (64 - r));
}
const uint64_t m = 0xc6a4a7935bd1e995LLU;
const int r = 47;
uint64_t h = seed ^ (len * m);
const uint64_t *data = (const uint64_t *)key;
const uint64_t *end = data + (len/8);
const unsigned char *data2;
JEMALLOC_INLINE uint32_t
hash_get_block_32(const uint32_t *p, int i)
{
assert(((uintptr_t)key & 0x7) == 0);
return (p[i]);
}
while(data != end) {
uint64_t k = *data++;
JEMALLOC_INLINE uint64_t
hash_get_block_64(const uint64_t *p, int i)
{
k *= m;
k ^= k >> r;
k *= m;
return (p[i]);
}
h ^= k;
h *= m;
}
JEMALLOC_INLINE uint32_t
hash_fmix_32(uint32_t h)
{
data2 = (const unsigned char *)data;
switch(len & 7) {
case 7: h ^= ((uint64_t)(data2[6])) << 48;
case 6: h ^= ((uint64_t)(data2[5])) << 40;
case 5: h ^= ((uint64_t)(data2[4])) << 32;
case 4: h ^= ((uint64_t)(data2[3])) << 24;
case 3: h ^= ((uint64_t)(data2[2])) << 16;
case 2: h ^= ((uint64_t)(data2[1])) << 8;
case 1: h ^= ((uint64_t)(data2[0]));
h *= m;
}
h ^= h >> 16;
h *= 0x85ebca6b;
h ^= h >> 13;
h *= 0xc2b2ae35;
h ^= h >> 16;
h ^= h >> r;
h *= m;
h ^= h >> r;
return (h);
}
JEMALLOC_INLINE uint64_t
hash_fmix_64(uint64_t k)
{
k ^= k >> 33;
k *= QU(0xff51afd7ed558ccdLLU);
k ^= k >> 33;
k *= QU(0xc4ceb9fe1a85ec53LLU);
k ^= k >> 33;
return (k);
}
JEMALLOC_INLINE uint32_t
hash_x86_32(const void *key, int len, uint32_t seed)
{
const uint8_t *data = (const uint8_t *) key;
const int nblocks = len / 4;
uint32_t h1 = seed;
const uint32_t c1 = 0xcc9e2d51;
const uint32_t c2 = 0x1b873593;
/* body */
{
const uint32_t *blocks = (const uint32_t *) (data + nblocks*4);
int i;
for (i = -nblocks; i; i++) {
uint32_t k1 = hash_get_block_32(blocks, i);
k1 *= c1;
k1 = hash_rotl_32(k1, 15);
k1 *= c2;
h1 ^= k1;
h1 = hash_rotl_32(h1, 13);
h1 = h1*5 + 0xe6546b64;
}
}
/* tail */
{
const uint8_t *tail = (const uint8_t *) (data + nblocks*4);
uint32_t k1 = 0;
switch (len & 3) {
case 3: k1 ^= tail[2] << 16;
case 2: k1 ^= tail[1] << 8;
case 1: k1 ^= tail[0]; k1 *= c1; k1 = hash_rotl_32(k1, 15);
k1 *= c2; h1 ^= k1;
}
}
/* finalization */
h1 ^= len;
h1 = hash_fmix_32(h1);
return (h1);
}
UNUSED JEMALLOC_INLINE void
hash_x86_128(const void *key, const int len, uint32_t seed,
uint64_t r_out[2])
{
const uint8_t * data = (const uint8_t *) key;
const int nblocks = len / 16;
uint32_t h1 = seed;
uint32_t h2 = seed;
uint32_t h3 = seed;
uint32_t h4 = seed;
const uint32_t c1 = 0x239b961b;
const uint32_t c2 = 0xab0e9789;
const uint32_t c3 = 0x38b34ae5;
const uint32_t c4 = 0xa1e38b93;
/* body */
{
const uint32_t *blocks = (const uint32_t *) (data + nblocks*16);
int i;
for (i = -nblocks; i; i++) {
uint32_t k1 = hash_get_block_32(blocks, i*4 + 0);
uint32_t k2 = hash_get_block_32(blocks, i*4 + 1);
uint32_t k3 = hash_get_block_32(blocks, i*4 + 2);
uint32_t k4 = hash_get_block_32(blocks, i*4 + 3);
k1 *= c1; k1 = hash_rotl_32(k1, 15); k1 *= c2; h1 ^= k1;
h1 = hash_rotl_32(h1, 19); h1 += h2;
h1 = h1*5 + 0x561ccd1b;
k2 *= c2; k2 = hash_rotl_32(k2, 16); k2 *= c3; h2 ^= k2;
h2 = hash_rotl_32(h2, 17); h2 += h3;
h2 = h2*5 + 0x0bcaa747;
k3 *= c3; k3 = hash_rotl_32(k3, 17); k3 *= c4; h3 ^= k3;
h3 = hash_rotl_32(h3, 15); h3 += h4;
h3 = h3*5 + 0x96cd1c35;
k4 *= c4; k4 = hash_rotl_32(k4, 18); k4 *= c1; h4 ^= k4;
h4 = hash_rotl_32(h4, 13); h4 += h1;
h4 = h4*5 + 0x32ac3b17;
}
}
/* tail */
{
const uint8_t *tail = (const uint8_t *) (data + nblocks*16);
uint32_t k1 = 0;
uint32_t k2 = 0;
uint32_t k3 = 0;
uint32_t k4 = 0;
switch (len & 15) {
case 15: k4 ^= tail[14] << 16;
case 14: k4 ^= tail[13] << 8;
case 13: k4 ^= tail[12] << 0;
k4 *= c4; k4 = hash_rotl_32(k4, 18); k4 *= c1; h4 ^= k4;
case 12: k3 ^= tail[11] << 24;
case 11: k3 ^= tail[10] << 16;
case 10: k3 ^= tail[ 9] << 8;
case 9: k3 ^= tail[ 8] << 0;
k3 *= c3; k3 = hash_rotl_32(k3, 17); k3 *= c4; h3 ^= k3;
case 8: k2 ^= tail[ 7] << 24;
case 7: k2 ^= tail[ 6] << 16;
case 6: k2 ^= tail[ 5] << 8;
case 5: k2 ^= tail[ 4] << 0;
k2 *= c2; k2 = hash_rotl_32(k2, 16); k2 *= c3; h2 ^= k2;
case 4: k1 ^= tail[ 3] << 24;
case 3: k1 ^= tail[ 2] << 16;
case 2: k1 ^= tail[ 1] << 8;
case 1: k1 ^= tail[ 0] << 0;
k1 *= c1; k1 = hash_rotl_32(k1, 15); k1 *= c2; h1 ^= k1;
}
}
/* finalization */
h1 ^= len; h2 ^= len; h3 ^= len; h4 ^= len;
h1 += h2; h1 += h3; h1 += h4;
h2 += h1; h3 += h1; h4 += h1;
h1 = hash_fmix_32(h1);
h2 = hash_fmix_32(h2);
h3 = hash_fmix_32(h3);
h4 = hash_fmix_32(h4);
h1 += h2; h1 += h3; h1 += h4;
h2 += h1; h3 += h1; h4 += h1;
r_out[0] = (((uint64_t) h2) << 32) | h1;
r_out[1] = (((uint64_t) h4) << 32) | h3;
}
UNUSED JEMALLOC_INLINE void
hash_x64_128(const void *key, const int len, const uint32_t seed,
uint64_t r_out[2])
{
const uint8_t *data = (const uint8_t *) key;
const int nblocks = len / 16;
uint64_t h1 = seed;
uint64_t h2 = seed;
const uint64_t c1 = QU(0x87c37b91114253d5LLU);
const uint64_t c2 = QU(0x4cf5ad432745937fLLU);
/* body */
{
const uint64_t *blocks = (const uint64_t *) (data);
int i;
for (i = 0; i < nblocks; i++) {
uint64_t k1 = hash_get_block_64(blocks, i*2 + 0);
uint64_t k2 = hash_get_block_64(blocks, i*2 + 1);
k1 *= c1; k1 = hash_rotl_64(k1, 31); k1 *= c2; h1 ^= k1;
h1 = hash_rotl_64(h1, 27); h1 += h2;
h1 = h1*5 + 0x52dce729;
k2 *= c2; k2 = hash_rotl_64(k2, 33); k2 *= c1; h2 ^= k2;
h2 = hash_rotl_64(h2, 31); h2 += h1;
h2 = h2*5 + 0x38495ab5;
}
}
/* tail */
{
const uint8_t *tail = (const uint8_t*)(data + nblocks*16);
uint64_t k1 = 0;
uint64_t k2 = 0;
switch (len & 15) {
case 15: k2 ^= ((uint64_t)(tail[14])) << 48;
case 14: k2 ^= ((uint64_t)(tail[13])) << 40;
case 13: k2 ^= ((uint64_t)(tail[12])) << 32;
case 12: k2 ^= ((uint64_t)(tail[11])) << 24;
case 11: k2 ^= ((uint64_t)(tail[10])) << 16;
case 10: k2 ^= ((uint64_t)(tail[ 9])) << 8;
case 9: k2 ^= ((uint64_t)(tail[ 8])) << 0;
k2 *= c2; k2 = hash_rotl_64(k2, 33); k2 *= c1; h2 ^= k2;
case 8: k1 ^= ((uint64_t)(tail[ 7])) << 56;
case 7: k1 ^= ((uint64_t)(tail[ 6])) << 48;
case 6: k1 ^= ((uint64_t)(tail[ 5])) << 40;
case 5: k1 ^= ((uint64_t)(tail[ 4])) << 32;
case 4: k1 ^= ((uint64_t)(tail[ 3])) << 24;
case 3: k1 ^= ((uint64_t)(tail[ 2])) << 16;
case 2: k1 ^= ((uint64_t)(tail[ 1])) << 8;
case 1: k1 ^= ((uint64_t)(tail[ 0])) << 0;
k1 *= c1; k1 = hash_rotl_64(k1, 31); k1 *= c2; h1 ^= k1;
}
}
/* finalization */
h1 ^= len; h2 ^= len;
h1 += h2;
h2 += h1;
h1 = hash_fmix_64(h1);
h2 = hash_fmix_64(h2);
h1 += h2;
h2 += h1;
r_out[0] = h1;
r_out[1] = h2;
}
/******************************************************************************/
/* API. */
JEMALLOC_INLINE void
hash(const void *key, size_t len, const uint32_t seed, size_t r_hash[2])
{
#if (LG_SIZEOF_PTR == 3 && !defined(JEMALLOC_BIG_ENDIAN))
hash_x64_128(key, len, seed, (uint64_t *)r_hash);
#else
uint64_t hashes[2];
hash_x86_128(key, len, seed, hashes);
r_hash[0] = (size_t)hashes[0];
r_hash[1] = (size_t)hashes[1];
#endif
}
#endif
#endif /* JEMALLOC_H_INLINES */
+8 -13
View File
@@ -9,34 +9,29 @@
/******************************************************************************/
#ifdef JEMALLOC_H_EXTERNS
#ifdef JEMALLOC_STATS
/* Huge allocation statistics. */
extern uint64_t huge_nmalloc;
extern uint64_t huge_ndalloc;
extern size_t huge_allocated;
#endif
/* Protects chunk-related data structures. */
extern malloc_mutex_t huge_mtx;
void *huge_malloc(size_t size, bool zero, dss_prec_t dss_prec);
void *huge_palloc(size_t size, size_t alignment, bool zero,
dss_prec_t dss_prec);
bool huge_ralloc_no_move(void *ptr, size_t oldsize, size_t size,
void *huge_malloc(size_t size, bool zero);
void *huge_palloc(size_t size, size_t alignment, bool zero);
void *huge_ralloc_no_move(void *ptr, size_t oldsize, size_t size,
size_t extra);
void *huge_ralloc(void *ptr, size_t oldsize, size_t size, size_t extra,
size_t alignment, bool zero, bool try_tcache_dalloc, dss_prec_t dss_prec);
#ifdef JEMALLOC_JET
typedef void (huge_dalloc_junk_t)(void *, size_t);
extern huge_dalloc_junk_t *huge_dalloc_junk;
#endif
size_t alignment, bool zero);
void huge_dalloc(void *ptr, bool unmap);
size_t huge_salloc(const void *ptr);
dss_prec_t huge_dss_prec_get(arena_t *arena);
#ifdef JEMALLOC_PROF
prof_ctx_t *huge_prof_ctx_get(const void *ptr);
void huge_prof_ctx_set(const void *ptr, prof_ctx_t *ctx);
#endif
bool huge_boot(void);
void huge_prefork(void);
void huge_postfork_parent(void);
void huge_postfork_child(void);
#endif /* JEMALLOC_H_EXTERNS */
/******************************************************************************/
File diff suppressed because it is too large Load Diff
@@ -1,205 +0,0 @@
#ifndef JEMALLOC_INTERNAL_DEFS_H_
#define JEMALLOC_INTERNAL_DEFS_H_
/*
* If JEMALLOC_PREFIX is defined via --with-jemalloc-prefix, it will cause all
* public APIs to be prefixed. This makes it possible, with some care, to use
* multiple allocators simultaneously.
*/
#undef JEMALLOC_PREFIX
#undef JEMALLOC_CPREFIX
/*
* JEMALLOC_PRIVATE_NAMESPACE is used as a prefix for all library-private APIs.
* For shared libraries, symbol visibility mechanisms prevent these symbols
* from being exported, but for static libraries, naming collisions are a real
* possibility.
*/
#undef JEMALLOC_PRIVATE_NAMESPACE
/*
* Hyper-threaded CPUs may need a special instruction inside spin loops in
* order to yield to another virtual CPU.
*/
#undef CPU_SPINWAIT
/* Defined if the equivalent of FreeBSD's atomic(9) functions are available. */
#undef JEMALLOC_ATOMIC9
/*
* Defined if OSAtomic*() functions are available, as provided by Darwin, and
* documented in the atomic(3) manual page.
*/
#undef JEMALLOC_OSATOMIC
/*
* Defined if __sync_add_and_fetch(uint32_t *, uint32_t) and
* __sync_sub_and_fetch(uint32_t *, uint32_t) are available, despite
* __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 not being defined (which means the
* functions are defined in libgcc instead of being inlines)
*/
#undef JE_FORCE_SYNC_COMPARE_AND_SWAP_4
/*
* Defined if __sync_add_and_fetch(uint64_t *, uint64_t) and
* __sync_sub_and_fetch(uint64_t *, uint64_t) are available, despite
* __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 not being defined (which means the
* functions are defined in libgcc instead of being inlines)
*/
#undef JE_FORCE_SYNC_COMPARE_AND_SWAP_8
/*
* Defined if OSSpin*() functions are available, as provided by Darwin, and
* documented in the spinlock(3) manual page.
*/
#undef JEMALLOC_OSSPIN
/*
* Defined if _malloc_thread_cleanup() exists. At least in the case of
* FreeBSD, pthread_key_create() allocates, which if used during malloc
* bootstrapping will cause recursion into the pthreads library. Therefore, if
* _malloc_thread_cleanup() exists, use it as the basis for thread cleanup in
* malloc_tsd.
*/
#undef JEMALLOC_MALLOC_THREAD_CLEANUP
/*
* Defined if threaded initialization is known to be safe on this platform.
* Among other things, it must be possible to initialize a mutex without
* triggering allocation in order for threaded allocation to be safe.
*/
#undef JEMALLOC_THREADED_INIT
/*
* Defined if the pthreads implementation defines
* _pthread_mutex_init_calloc_cb(), in which case the function is used in order
* to avoid recursive allocation during mutex initialization.
*/
#undef JEMALLOC_MUTEX_INIT_CB
/* Defined if sbrk() is supported. */
#undef JEMALLOC_HAVE_SBRK
/* Non-empty if the tls_model attribute is supported. */
#undef JEMALLOC_TLS_MODEL
/* JEMALLOC_CC_SILENCE enables code that silences unuseful compiler warnings. */
#undef JEMALLOC_CC_SILENCE
/* JEMALLOC_CODE_COVERAGE enables test code coverage analysis. */
#undef JEMALLOC_CODE_COVERAGE
/*
* JEMALLOC_DEBUG enables assertions and other sanity checks, and disables
* inline functions.
*/
#undef JEMALLOC_DEBUG
/* JEMALLOC_STATS enables statistics calculation. */
#undef JEMALLOC_STATS
/* JEMALLOC_PROF enables allocation profiling. */
#undef JEMALLOC_PROF
/* Use libunwind for profile backtracing if defined. */
#undef JEMALLOC_PROF_LIBUNWIND
/* Use libgcc for profile backtracing if defined. */
#undef JEMALLOC_PROF_LIBGCC
/* Use gcc intrinsics for profile backtracing if defined. */
#undef JEMALLOC_PROF_GCC
/*
* JEMALLOC_TCACHE enables a thread-specific caching layer for small objects.
* This makes it possible to allocate/deallocate objects without any locking
* when the cache is in the steady state.
*/
#undef JEMALLOC_TCACHE
/*
* JEMALLOC_DSS enables use of sbrk(2) to allocate chunks from the data storage
* segment (DSS).
*/
#undef JEMALLOC_DSS
/* Support memory filling (junk/zero/quarantine/redzone). */
#undef JEMALLOC_FILL
/* Support utrace(2)-based tracing. */
#undef JEMALLOC_UTRACE
/* Support Valgrind. */
#undef JEMALLOC_VALGRIND
/* Support optional abort() on OOM. */
#undef JEMALLOC_XMALLOC
/* Support lazy locking (avoid locking unless a second thread is launched). */
#undef JEMALLOC_LAZY_LOCK
/* One page is 2^STATIC_PAGE_SHIFT bytes. */
#undef STATIC_PAGE_SHIFT
/*
* If defined, use munmap() to unmap freed chunks, rather than storing them for
* later reuse. This is disabled by default on Linux because common sequences
* of mmap()/munmap() calls will cause virtual memory map holes.
*/
#undef JEMALLOC_MUNMAP
/*
* If defined, use mremap(...MREMAP_FIXED...) for huge realloc(). This is
* disabled by default because it is Linux-specific and it will cause virtual
* memory map holes, much like munmap(2) does.
*/
#undef JEMALLOC_MREMAP
/* TLS is used to map arenas and magazine caches to threads. */
#undef JEMALLOC_TLS
/*
* JEMALLOC_IVSALLOC enables ivsalloc(), which verifies that pointers reside
* within jemalloc-owned chunks before dereferencing them.
*/
#undef JEMALLOC_IVSALLOC
/*
* Darwin (OS X) uses zones to work around Mach-O symbol override shortcomings.
*/
#undef JEMALLOC_ZONE
#undef JEMALLOC_ZONE_VERSION
/*
* Methods for purging unused pages differ between operating systems.
*
* madvise(..., MADV_DONTNEED) : On Linux, this immediately discards pages,
* such that new pages will be demand-zeroed if
* the address region is later touched.
* madvise(..., MADV_FREE) : On FreeBSD and Darwin, this marks pages as being
* unused, such that they will be discarded rather
* than swapped out.
*/
#undef JEMALLOC_PURGE_MADVISE_DONTNEED
#undef JEMALLOC_PURGE_MADVISE_FREE
/*
* Define if operating system has alloca.h header.
*/
#undef JEMALLOC_HAS_ALLOCA_H
/* C99 restrict keyword supported. */
#undef JEMALLOC_HAS_RESTRICT
/* For use by hash code. */
#undef JEMALLOC_BIG_ENDIAN
/* sizeof(int) == 2^LG_SIZEOF_INT. */
#undef LG_SIZEOF_INT
/* sizeof(long) == 2^LG_SIZEOF_LONG. */
#undef LG_SIZEOF_LONG
/* sizeof(intmax_t) == 2^LG_SIZEOF_INTMAX_T. */
#undef LG_SIZEOF_INTMAX_T
#endif /* JEMALLOC_INTERNAL_DEFS_H_ */
@@ -1,51 +0,0 @@
/*
* JEMALLOC_ALWAYS_INLINE and JEMALLOC_INLINE are used within header files for
* functions that are static inline functions if inlining is enabled, and
* single-definition library-private functions if inlining is disabled.
*
* JEMALLOC_ALWAYS_INLINE_C and JEMALLOC_INLINE_C are for use in .c files, in
* which case the denoted functions are always static, regardless of whether
* inlining is enabled.
*/
#if defined(JEMALLOC_DEBUG) || defined(JEMALLOC_CODE_COVERAGE)
/* Disable inlining to make debugging/profiling easier. */
# define JEMALLOC_ALWAYS_INLINE
# define JEMALLOC_ALWAYS_INLINE_C static
# define JEMALLOC_INLINE
# define JEMALLOC_INLINE_C static
# define inline
#else
# define JEMALLOC_ENABLE_INLINE
# ifdef JEMALLOC_HAVE_ATTR
# define JEMALLOC_ALWAYS_INLINE \
static inline JEMALLOC_ATTR(unused) JEMALLOC_ATTR(always_inline)
# define JEMALLOC_ALWAYS_INLINE_C \
static inline JEMALLOC_ATTR(always_inline)
# else
# define JEMALLOC_ALWAYS_INLINE static inline
# define JEMALLOC_ALWAYS_INLINE_C static inline
# endif
# define JEMALLOC_INLINE static inline
# define JEMALLOC_INLINE_C static inline
# ifdef _MSC_VER
# define inline _inline
# endif
#endif
#ifdef JEMALLOC_CC_SILENCE
# define UNUSED JEMALLOC_ATTR(unused)
#else
# define UNUSED
#endif
#define ZU(z) ((size_t)z)
#define QU(q) ((uint64_t)q)
#define QI(q) ((int64_t)q)
#ifndef __DECONST
# define __DECONST(type, var) ((type)(uintptr_t)(const void *)(var))
#endif
#ifndef JEMALLOC_HAS_RESTRICT
# define restrict
#endif
+1 -8
View File
@@ -54,7 +54,7 @@ mb_write(void)
);
#endif
}
#elif (defined(__amd64__) || defined(__x86_64__))
#elif (defined(__amd64_) || defined(__x86_64__))
JEMALLOC_INLINE void
mb_write(void)
{
@@ -87,13 +87,6 @@ mb_write(void)
: "memory" /* Clobbers. */
);
}
#elif defined(__tile__)
JEMALLOC_INLINE void
mb_write(void)
{
__sync_synchronize();
}
#else
/*
* This is much slower than a simple memory barrier, but the semantics of mutex
+31 -44
View File
@@ -1,42 +1,22 @@
/******************************************************************************/
#ifdef JEMALLOC_H_TYPES
typedef struct malloc_mutex_s malloc_mutex_t;
#ifdef _WIN32
# define MALLOC_MUTEX_INITIALIZER
#elif (defined(JEMALLOC_OSSPIN))
# define MALLOC_MUTEX_INITIALIZER {0}
#elif (defined(JEMALLOC_MUTEX_INIT_CB))
# define MALLOC_MUTEX_INITIALIZER {PTHREAD_MUTEX_INITIALIZER, NULL}
#ifdef JEMALLOC_OSSPIN
typedef OSSpinLock malloc_mutex_t;
#else
# if (defined(PTHREAD_MUTEX_ADAPTIVE_NP) && \
defined(PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP))
# define MALLOC_MUTEX_TYPE PTHREAD_MUTEX_ADAPTIVE_NP
# define MALLOC_MUTEX_INITIALIZER {PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP}
# else
# define MALLOC_MUTEX_TYPE PTHREAD_MUTEX_DEFAULT
# define MALLOC_MUTEX_INITIALIZER {PTHREAD_MUTEX_INITIALIZER}
# endif
typedef pthread_mutex_t malloc_mutex_t;
#endif
#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
# define MALLOC_MUTEX_INITIALIZER PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
#else
# define MALLOC_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
#endif
#endif /* JEMALLOC_H_TYPES */
/******************************************************************************/
#ifdef JEMALLOC_H_STRUCTS
struct malloc_mutex_s {
#ifdef _WIN32
CRITICAL_SECTION lock;
#elif (defined(JEMALLOC_OSSPIN))
OSSpinLock lock;
#elif (defined(JEMALLOC_MUTEX_INIT_CB))
pthread_mutex_t lock;
malloc_mutex_t *postponed_next;
#else
pthread_mutex_t lock;
#endif
};
#endif /* JEMALLOC_H_STRUCTS */
/******************************************************************************/
#ifdef JEMALLOC_H_EXTERNS
@@ -44,15 +24,11 @@ struct malloc_mutex_s {
#ifdef JEMALLOC_LAZY_LOCK
extern bool isthreaded;
#else
# undef isthreaded /* Undo private_namespace.h definition. */
# define isthreaded true
#endif
bool malloc_mutex_init(malloc_mutex_t *mutex);
void malloc_mutex_prefork(malloc_mutex_t *mutex);
void malloc_mutex_postfork_parent(malloc_mutex_t *mutex);
void malloc_mutex_postfork_child(malloc_mutex_t *mutex);
bool mutex_boot(void);
void malloc_mutex_destroy(malloc_mutex_t *mutex);
#endif /* JEMALLOC_H_EXTERNS */
/******************************************************************************/
@@ -60,6 +36,7 @@ bool mutex_boot(void);
#ifndef JEMALLOC_ENABLE_INLINE
void malloc_mutex_lock(malloc_mutex_t *mutex);
bool malloc_mutex_trylock(malloc_mutex_t *mutex);
void malloc_mutex_unlock(malloc_mutex_t *mutex);
#endif
@@ -69,27 +46,37 @@ malloc_mutex_lock(malloc_mutex_t *mutex)
{
if (isthreaded) {
#ifdef _WIN32
EnterCriticalSection(&mutex->lock);
#elif (defined(JEMALLOC_OSSPIN))
OSSpinLockLock(&mutex->lock);
#ifdef JEMALLOC_OSSPIN
OSSpinLockLock(mutex);
#else
pthread_mutex_lock(&mutex->lock);
pthread_mutex_lock(mutex);
#endif
}
}
JEMALLOC_INLINE bool
malloc_mutex_trylock(malloc_mutex_t *mutex)
{
if (isthreaded) {
#ifdef JEMALLOC_OSSPIN
return (OSSpinLockTry(mutex) == false);
#else
return (pthread_mutex_trylock(mutex) != 0);
#endif
} else
return (false);
}
JEMALLOC_INLINE void
malloc_mutex_unlock(malloc_mutex_t *mutex)
{
if (isthreaded) {
#ifdef _WIN32
LeaveCriticalSection(&mutex->lock);
#elif (defined(JEMALLOC_OSSPIN))
OSSpinLockUnlock(&mutex->lock);
#ifdef JEMALLOC_OSSPIN
OSSpinLockUnlock(mutex);
#else
pthread_mutex_unlock(&mutex->lock);
pthread_mutex_unlock(mutex);
#endif
}
}
@@ -0,0 +1,195 @@
#define arena_bin_index JEMALLOC_N(arena_bin_index)
#define arena_boot JEMALLOC_N(arena_boot)
#define arena_dalloc JEMALLOC_N(arena_dalloc)
#define arena_dalloc_bin JEMALLOC_N(arena_dalloc_bin)
#define arena_dalloc_large JEMALLOC_N(arena_dalloc_large)
#define arena_malloc JEMALLOC_N(arena_malloc)
#define arena_malloc_large JEMALLOC_N(arena_malloc_large)
#define arena_malloc_small JEMALLOC_N(arena_malloc_small)
#define arena_new JEMALLOC_N(arena_new)
#define arena_palloc JEMALLOC_N(arena_palloc)
#define arena_prof_accum JEMALLOC_N(arena_prof_accum)
#define arena_prof_ctx_get JEMALLOC_N(arena_prof_ctx_get)
#define arena_prof_ctx_set JEMALLOC_N(arena_prof_ctx_set)
#define arena_prof_promoted JEMALLOC_N(arena_prof_promoted)
#define arena_purge_all JEMALLOC_N(arena_purge_all)
#define arena_ralloc JEMALLOC_N(arena_ralloc)
#define arena_ralloc_no_move JEMALLOC_N(arena_ralloc_no_move)
#define arena_run_regind JEMALLOC_N(arena_run_regind)
#define arena_salloc JEMALLOC_N(arena_salloc)
#define arena_salloc_demote JEMALLOC_N(arena_salloc_demote)
#define arena_stats_merge JEMALLOC_N(arena_stats_merge)
#define arena_tcache_fill_small JEMALLOC_N(arena_tcache_fill_small)
#define arenas_bin_i_index JEMALLOC_N(arenas_bin_i_index)
#define arenas_extend JEMALLOC_N(arenas_extend)
#define arenas_lrun_i_index JEMALLOC_N(arenas_lrun_i_index)
#define atomic_add_uint32 JEMALLOC_N(atomic_add_uint32)
#define atomic_add_uint64 JEMALLOC_N(atomic_add_uint64)
#define atomic_sub_uint32 JEMALLOC_N(atomic_sub_uint32)
#define atomic_sub_uint64 JEMALLOC_N(atomic_sub_uint64)
#define base_alloc JEMALLOC_N(base_alloc)
#define base_boot JEMALLOC_N(base_boot)
#define base_node_alloc JEMALLOC_N(base_node_alloc)
#define base_node_dealloc JEMALLOC_N(base_node_dealloc)
#define bitmap_full JEMALLOC_N(bitmap_full)
#define bitmap_get JEMALLOC_N(bitmap_get)
#define bitmap_info_init JEMALLOC_N(bitmap_info_init)
#define bitmap_info_ngroups JEMALLOC_N(bitmap_info_ngroups)
#define bitmap_init JEMALLOC_N(bitmap_init)
#define bitmap_set JEMALLOC_N(bitmap_set)
#define bitmap_sfu JEMALLOC_N(bitmap_sfu)
#define bitmap_size JEMALLOC_N(bitmap_size)
#define bitmap_unset JEMALLOC_N(bitmap_unset)
#define bt_init JEMALLOC_N(bt_init)
#define buferror JEMALLOC_N(buferror)
#define choose_arena JEMALLOC_N(choose_arena)
#define choose_arena_hard JEMALLOC_N(choose_arena_hard)
#define chunk_alloc JEMALLOC_N(chunk_alloc)
#define chunk_alloc_dss JEMALLOC_N(chunk_alloc_dss)
#define chunk_alloc_mmap JEMALLOC_N(chunk_alloc_mmap)
#define chunk_alloc_mmap_noreserve JEMALLOC_N(chunk_alloc_mmap_noreserve)
#define chunk_alloc_swap JEMALLOC_N(chunk_alloc_swap)
#define chunk_boot JEMALLOC_N(chunk_boot)
#define chunk_dealloc JEMALLOC_N(chunk_dealloc)
#define chunk_dealloc_dss JEMALLOC_N(chunk_dealloc_dss)
#define chunk_dealloc_mmap JEMALLOC_N(chunk_dealloc_mmap)
#define chunk_dealloc_swap JEMALLOC_N(chunk_dealloc_swap)
#define chunk_dss_boot JEMALLOC_N(chunk_dss_boot)
#define chunk_in_dss JEMALLOC_N(chunk_in_dss)
#define chunk_in_swap JEMALLOC_N(chunk_in_swap)
#define chunk_mmap_boot JEMALLOC_N(chunk_mmap_boot)
#define chunk_swap_boot JEMALLOC_N(chunk_swap_boot)
#define chunk_swap_enable JEMALLOC_N(chunk_swap_enable)
#define ckh_bucket_search JEMALLOC_N(ckh_bucket_search)
#define ckh_count JEMALLOC_N(ckh_count)
#define ckh_delete JEMALLOC_N(ckh_delete)
#define ckh_evict_reloc_insert JEMALLOC_N(ckh_evict_reloc_insert)
#define ckh_insert JEMALLOC_N(ckh_insert)
#define ckh_isearch JEMALLOC_N(ckh_isearch)
#define ckh_iter JEMALLOC_N(ckh_iter)
#define ckh_new JEMALLOC_N(ckh_new)
#define ckh_pointer_hash JEMALLOC_N(ckh_pointer_hash)
#define ckh_pointer_keycomp JEMALLOC_N(ckh_pointer_keycomp)
#define ckh_rebuild JEMALLOC_N(ckh_rebuild)
#define ckh_remove JEMALLOC_N(ckh_remove)
#define ckh_search JEMALLOC_N(ckh_search)
#define ckh_string_hash JEMALLOC_N(ckh_string_hash)
#define ckh_string_keycomp JEMALLOC_N(ckh_string_keycomp)
#define ckh_try_bucket_insert JEMALLOC_N(ckh_try_bucket_insert)
#define ckh_try_insert JEMALLOC_N(ckh_try_insert)
#define create_zone JEMALLOC_N(create_zone)
#define ctl_boot JEMALLOC_N(ctl_boot)
#define ctl_bymib JEMALLOC_N(ctl_bymib)
#define ctl_byname JEMALLOC_N(ctl_byname)
#define ctl_nametomib JEMALLOC_N(ctl_nametomib)
#define extent_tree_ad_first JEMALLOC_N(extent_tree_ad_first)
#define extent_tree_ad_insert JEMALLOC_N(extent_tree_ad_insert)
#define extent_tree_ad_iter JEMALLOC_N(extent_tree_ad_iter)
#define extent_tree_ad_iter_recurse JEMALLOC_N(extent_tree_ad_iter_recurse)
#define extent_tree_ad_iter_start JEMALLOC_N(extent_tree_ad_iter_start)
#define extent_tree_ad_last JEMALLOC_N(extent_tree_ad_last)
#define extent_tree_ad_new JEMALLOC_N(extent_tree_ad_new)
#define extent_tree_ad_next JEMALLOC_N(extent_tree_ad_next)
#define extent_tree_ad_nsearch JEMALLOC_N(extent_tree_ad_nsearch)
#define extent_tree_ad_prev JEMALLOC_N(extent_tree_ad_prev)
#define extent_tree_ad_psearch JEMALLOC_N(extent_tree_ad_psearch)
#define extent_tree_ad_remove JEMALLOC_N(extent_tree_ad_remove)
#define extent_tree_ad_reverse_iter JEMALLOC_N(extent_tree_ad_reverse_iter)
#define extent_tree_ad_reverse_iter_recurse JEMALLOC_N(extent_tree_ad_reverse_iter_recurse)
#define extent_tree_ad_reverse_iter_start JEMALLOC_N(extent_tree_ad_reverse_iter_start)
#define extent_tree_ad_search JEMALLOC_N(extent_tree_ad_search)
#define extent_tree_szad_first JEMALLOC_N(extent_tree_szad_first)
#define extent_tree_szad_insert JEMALLOC_N(extent_tree_szad_insert)
#define extent_tree_szad_iter JEMALLOC_N(extent_tree_szad_iter)
#define extent_tree_szad_iter_recurse JEMALLOC_N(extent_tree_szad_iter_recurse)
#define extent_tree_szad_iter_start JEMALLOC_N(extent_tree_szad_iter_start)
#define extent_tree_szad_last JEMALLOC_N(extent_tree_szad_last)
#define extent_tree_szad_new JEMALLOC_N(extent_tree_szad_new)
#define extent_tree_szad_next JEMALLOC_N(extent_tree_szad_next)
#define extent_tree_szad_nsearch JEMALLOC_N(extent_tree_szad_nsearch)
#define extent_tree_szad_prev JEMALLOC_N(extent_tree_szad_prev)
#define extent_tree_szad_psearch JEMALLOC_N(extent_tree_szad_psearch)
#define extent_tree_szad_remove JEMALLOC_N(extent_tree_szad_remove)
#define extent_tree_szad_reverse_iter JEMALLOC_N(extent_tree_szad_reverse_iter)
#define extent_tree_szad_reverse_iter_recurse JEMALLOC_N(extent_tree_szad_reverse_iter_recurse)
#define extent_tree_szad_reverse_iter_start JEMALLOC_N(extent_tree_szad_reverse_iter_start)
#define extent_tree_szad_search JEMALLOC_N(extent_tree_szad_search)
#define hash JEMALLOC_N(hash)
#define huge_boot JEMALLOC_N(huge_boot)
#define huge_dalloc JEMALLOC_N(huge_dalloc)
#define huge_malloc JEMALLOC_N(huge_malloc)
#define huge_palloc JEMALLOC_N(huge_palloc)
#define huge_prof_ctx_get JEMALLOC_N(huge_prof_ctx_get)
#define huge_prof_ctx_set JEMALLOC_N(huge_prof_ctx_set)
#define huge_ralloc JEMALLOC_N(huge_ralloc)
#define huge_ralloc_no_move JEMALLOC_N(huge_ralloc_no_move)
#define huge_salloc JEMALLOC_N(huge_salloc)
#define iallocm JEMALLOC_N(iallocm)
#define icalloc JEMALLOC_N(icalloc)
#define idalloc JEMALLOC_N(idalloc)
#define imalloc JEMALLOC_N(imalloc)
#define ipalloc JEMALLOC_N(ipalloc)
#define iralloc JEMALLOC_N(iralloc)
#define isalloc JEMALLOC_N(isalloc)
#define ivsalloc JEMALLOC_N(ivsalloc)
#define jemalloc_darwin_init JEMALLOC_N(jemalloc_darwin_init)
#define jemalloc_postfork JEMALLOC_N(jemalloc_postfork)
#define jemalloc_prefork JEMALLOC_N(jemalloc_prefork)
#define malloc_cprintf JEMALLOC_N(malloc_cprintf)
#define malloc_mutex_destroy JEMALLOC_N(malloc_mutex_destroy)
#define malloc_mutex_init JEMALLOC_N(malloc_mutex_init)
#define malloc_mutex_lock JEMALLOC_N(malloc_mutex_lock)
#define malloc_mutex_trylock JEMALLOC_N(malloc_mutex_trylock)
#define malloc_mutex_unlock JEMALLOC_N(malloc_mutex_unlock)
#define malloc_printf JEMALLOC_N(malloc_printf)
#define malloc_write JEMALLOC_N(malloc_write)
#define mb_write JEMALLOC_N(mb_write)
#define pow2_ceil JEMALLOC_N(pow2_ceil)
#define prof_backtrace JEMALLOC_N(prof_backtrace)
#define prof_boot0 JEMALLOC_N(prof_boot0)
#define prof_boot1 JEMALLOC_N(prof_boot1)
#define prof_boot2 JEMALLOC_N(prof_boot2)
#define prof_ctx_get JEMALLOC_N(prof_ctx_get)
#define prof_ctx_set JEMALLOC_N(prof_ctx_set)
#define prof_free JEMALLOC_N(prof_free)
#define prof_gdump JEMALLOC_N(prof_gdump)
#define prof_idump JEMALLOC_N(prof_idump)
#define prof_lookup JEMALLOC_N(prof_lookup)
#define prof_malloc JEMALLOC_N(prof_malloc)
#define prof_mdump JEMALLOC_N(prof_mdump)
#define prof_realloc JEMALLOC_N(prof_realloc)
#define prof_sample_accum_update JEMALLOC_N(prof_sample_accum_update)
#define prof_sample_threshold_update JEMALLOC_N(prof_sample_threshold_update)
#define prof_tdata_init JEMALLOC_N(prof_tdata_init)
#define pthread_create JEMALLOC_N(pthread_create)
#define rtree_get JEMALLOC_N(rtree_get)
#define rtree_get_locked JEMALLOC_N(rtree_get_locked)
#define rtree_new JEMALLOC_N(rtree_new)
#define rtree_set JEMALLOC_N(rtree_set)
#define s2u JEMALLOC_N(s2u)
#define sa2u JEMALLOC_N(sa2u)
#define stats_arenas_i_bins_j_index JEMALLOC_N(stats_arenas_i_bins_j_index)
#define stats_arenas_i_index JEMALLOC_N(stats_arenas_i_index)
#define stats_arenas_i_lruns_j_index JEMALLOC_N(stats_arenas_i_lruns_j_index)
#define stats_cactive_add JEMALLOC_N(stats_cactive_add)
#define stats_cactive_get JEMALLOC_N(stats_cactive_get)
#define stats_cactive_sub JEMALLOC_N(stats_cactive_sub)
#define stats_print JEMALLOC_N(stats_print)
#define szone2ozone JEMALLOC_N(szone2ozone)
#define tcache_alloc_easy JEMALLOC_N(tcache_alloc_easy)
#define tcache_alloc_large JEMALLOC_N(tcache_alloc_large)
#define tcache_alloc_small JEMALLOC_N(tcache_alloc_small)
#define tcache_alloc_small_hard JEMALLOC_N(tcache_alloc_small_hard)
#define tcache_bin_flush_large JEMALLOC_N(tcache_bin_flush_large)
#define tcache_bin_flush_small JEMALLOC_N(tcache_bin_flush_small)
#define tcache_boot JEMALLOC_N(tcache_boot)
#define tcache_create JEMALLOC_N(tcache_create)
#define tcache_dalloc_large JEMALLOC_N(tcache_dalloc_large)
#define tcache_dalloc_small JEMALLOC_N(tcache_dalloc_small)
#define tcache_destroy JEMALLOC_N(tcache_destroy)
#define tcache_event JEMALLOC_N(tcache_event)
#define tcache_get JEMALLOC_N(tcache_get)
#define tcache_stats_merge JEMALLOC_N(tcache_stats_merge)
#define thread_allocated_get JEMALLOC_N(thread_allocated_get)
#define thread_allocated_get_hard JEMALLOC_N(thread_allocated_get_hard)
#define u2s JEMALLOC_N(u2s)
@@ -1,5 +0,0 @@
#!/bin/sh
for symbol in `cat $1` ; do
echo "#define ${symbol} JEMALLOC_N(${symbol})"
done
@@ -1,413 +0,0 @@
a0calloc
a0free
a0malloc
arena_alloc_junk_small
arena_bin_index
arena_bin_info
arena_boot
arena_dalloc
arena_dalloc_bin
arena_dalloc_bin_locked
arena_dalloc_junk_large
arena_dalloc_junk_small
arena_dalloc_large
arena_dalloc_large_locked
arena_dalloc_small
arena_dss_prec_get
arena_dss_prec_set
arena_malloc
arena_malloc_large
arena_malloc_small
arena_mapbits_allocated_get
arena_mapbits_binind_get
arena_mapbits_dirty_get
arena_mapbits_get
arena_mapbits_large_binind_set
arena_mapbits_large_get
arena_mapbits_large_set
arena_mapbits_large_size_get
arena_mapbits_small_runind_get
arena_mapbits_small_set
arena_mapbits_unallocated_set
arena_mapbits_unallocated_size_get
arena_mapbits_unallocated_size_set
arena_mapbits_unzeroed_get
arena_mapbits_unzeroed_set
arena_mapbitsp_get
arena_mapbitsp_read
arena_mapbitsp_write
arena_mapp_get
arena_maxclass
arena_new
arena_palloc
arena_postfork_child
arena_postfork_parent
arena_prefork
arena_prof_accum
arena_prof_accum_impl
arena_prof_accum_locked
arena_prof_ctx_get
arena_prof_ctx_set
arena_prof_promoted
arena_ptr_small_binind_get
arena_purge_all
arena_quarantine_junk_small
arena_ralloc
arena_ralloc_junk_large
arena_ralloc_no_move
arena_redzone_corruption
arena_run_regind
arena_salloc
arena_stats_merge
arena_tcache_fill_small
arenas
arenas_booted
arenas_cleanup
arenas_extend
arenas_initialized
arenas_lock
arenas_tls
arenas_tsd
arenas_tsd_boot
arenas_tsd_cleanup_wrapper
arenas_tsd_get
arenas_tsd_get_wrapper
arenas_tsd_init_head
arenas_tsd_set
atomic_add_u
atomic_add_uint32
atomic_add_uint64
atomic_add_z
atomic_sub_u
atomic_sub_uint32
atomic_sub_uint64
atomic_sub_z
base_alloc
base_boot
base_calloc
base_node_alloc
base_node_dealloc
base_postfork_child
base_postfork_parent
base_prefork
bitmap_full
bitmap_get
bitmap_info_init
bitmap_info_ngroups
bitmap_init
bitmap_set
bitmap_sfu
bitmap_size
bitmap_unset
bt_init
buferror
choose_arena
choose_arena_hard
chunk_alloc
chunk_alloc_dss
chunk_alloc_mmap
chunk_boot
chunk_dealloc
chunk_dealloc_mmap
chunk_dss_boot
chunk_dss_postfork_child
chunk_dss_postfork_parent
chunk_dss_prec_get
chunk_dss_prec_set
chunk_dss_prefork
chunk_in_dss
chunk_npages
chunk_postfork_child
chunk_postfork_parent
chunk_prefork
chunk_unmap
chunks_mtx
chunks_rtree
chunksize
chunksize_mask
ckh_bucket_search
ckh_count
ckh_delete
ckh_evict_reloc_insert
ckh_insert
ckh_isearch
ckh_iter
ckh_new
ckh_pointer_hash
ckh_pointer_keycomp
ckh_rebuild
ckh_remove
ckh_search
ckh_string_hash
ckh_string_keycomp
ckh_try_bucket_insert
ckh_try_insert
ctl_boot
ctl_bymib
ctl_byname
ctl_nametomib
ctl_postfork_child
ctl_postfork_parent
ctl_prefork
dss_prec_names
extent_tree_ad_first
extent_tree_ad_insert
extent_tree_ad_iter
extent_tree_ad_iter_recurse
extent_tree_ad_iter_start
extent_tree_ad_last
extent_tree_ad_new
extent_tree_ad_next
extent_tree_ad_nsearch
extent_tree_ad_prev
extent_tree_ad_psearch
extent_tree_ad_remove
extent_tree_ad_reverse_iter
extent_tree_ad_reverse_iter_recurse
extent_tree_ad_reverse_iter_start
extent_tree_ad_search
extent_tree_szad_first
extent_tree_szad_insert
extent_tree_szad_iter
extent_tree_szad_iter_recurse
extent_tree_szad_iter_start
extent_tree_szad_last
extent_tree_szad_new
extent_tree_szad_next
extent_tree_szad_nsearch
extent_tree_szad_prev
extent_tree_szad_psearch
extent_tree_szad_remove
extent_tree_szad_reverse_iter
extent_tree_szad_reverse_iter_recurse
extent_tree_szad_reverse_iter_start
extent_tree_szad_search
get_errno
hash
hash_fmix_32
hash_fmix_64
hash_get_block_32
hash_get_block_64
hash_rotl_32
hash_rotl_64
hash_x64_128
hash_x86_128
hash_x86_32
huge_allocated
huge_boot
huge_dalloc
huge_dalloc_junk
huge_dss_prec_get
huge_malloc
huge_mtx
huge_ndalloc
huge_nmalloc
huge_palloc
huge_postfork_child
huge_postfork_parent
huge_prefork
huge_prof_ctx_get
huge_prof_ctx_set
huge_ralloc
huge_ralloc_no_move
huge_salloc
iallocm
icalloc
icalloct
idalloc
idalloct
imalloc
imalloct
ipalloc
ipalloct
iqalloc
iqalloct
iralloc
iralloct
iralloct_realign
isalloc
isthreaded
ivsalloc
ixalloc
jemalloc_postfork_child
jemalloc_postfork_parent
jemalloc_prefork
malloc_cprintf
malloc_mutex_init
malloc_mutex_lock
malloc_mutex_postfork_child
malloc_mutex_postfork_parent
malloc_mutex_prefork
malloc_mutex_unlock
malloc_printf
malloc_snprintf
malloc_strtoumax
malloc_tsd_boot
malloc_tsd_cleanup_register
malloc_tsd_dalloc
malloc_tsd_malloc
malloc_tsd_no_cleanup
malloc_vcprintf
malloc_vsnprintf
malloc_write
map_bias
mb_write
mutex_boot
narenas_auto
narenas_total
narenas_total_get
ncpus
nhbins
opt_abort
opt_dss
opt_junk
opt_lg_chunk
opt_lg_dirty_mult
opt_lg_prof_interval
opt_lg_prof_sample
opt_lg_tcache_max
opt_narenas
opt_prof
opt_prof_accum
opt_prof_active
opt_prof_final
opt_prof_gdump
opt_prof_leak
opt_prof_prefix
opt_quarantine
opt_redzone
opt_stats_print
opt_tcache
opt_utrace
opt_valgrind
opt_xmalloc
opt_zero
p2rz
pages_purge
pow2_ceil
prof_backtrace
prof_boot0
prof_boot1
prof_boot2
prof_bt_count
prof_ctx_get
prof_ctx_set
prof_dump_open
prof_free
prof_gdump
prof_idump
prof_interval
prof_lookup
prof_malloc
prof_mdump
prof_postfork_child
prof_postfork_parent
prof_prefork
prof_promote
prof_realloc
prof_sample_accum_update
prof_sample_threshold_update
prof_tdata_booted
prof_tdata_cleanup
prof_tdata_get
prof_tdata_init
prof_tdata_initialized
prof_tdata_tls
prof_tdata_tsd
prof_tdata_tsd_boot
prof_tdata_tsd_cleanup_wrapper
prof_tdata_tsd_get
prof_tdata_tsd_get_wrapper
prof_tdata_tsd_init_head
prof_tdata_tsd_set
quarantine
quarantine_alloc_hook
quarantine_boot
quarantine_booted
quarantine_cleanup
quarantine_init
quarantine_tls
quarantine_tsd
quarantine_tsd_boot
quarantine_tsd_cleanup_wrapper
quarantine_tsd_get
quarantine_tsd_get_wrapper
quarantine_tsd_init_head
quarantine_tsd_set
register_zone
rtree_delete
rtree_get
rtree_get_locked
rtree_new
rtree_postfork_child
rtree_postfork_parent
rtree_prefork
rtree_set
s2u
sa2u
set_errno
small_size2bin
stats_cactive
stats_cactive_add
stats_cactive_get
stats_cactive_sub
stats_chunks
stats_print
tcache_alloc_easy
tcache_alloc_large
tcache_alloc_small
tcache_alloc_small_hard
tcache_arena_associate
tcache_arena_dissociate
tcache_bin_flush_large
tcache_bin_flush_small
tcache_bin_info
tcache_boot0
tcache_boot1
tcache_booted
tcache_create
tcache_dalloc_large
tcache_dalloc_small
tcache_destroy
tcache_enabled_booted
tcache_enabled_get
tcache_enabled_initialized
tcache_enabled_set
tcache_enabled_tls
tcache_enabled_tsd
tcache_enabled_tsd_boot
tcache_enabled_tsd_cleanup_wrapper
tcache_enabled_tsd_get
tcache_enabled_tsd_get_wrapper
tcache_enabled_tsd_init_head
tcache_enabled_tsd_set
tcache_event
tcache_event_hard
tcache_flush
tcache_get
tcache_initialized
tcache_maxclass
tcache_salloc
tcache_stats_merge
tcache_thread_cleanup
tcache_tls
tcache_tsd
tcache_tsd_boot
tcache_tsd_cleanup_wrapper
tcache_tsd_get
tcache_tsd_get_wrapper
tcache_tsd_init_head
tcache_tsd_set
thread_allocated_booted
thread_allocated_initialized
thread_allocated_tls
thread_allocated_tsd
thread_allocated_tsd_boot
thread_allocated_tsd_cleanup_wrapper
thread_allocated_tsd_get
thread_allocated_tsd_get_wrapper
thread_allocated_tsd_init_head
thread_allocated_tsd_set
tsd_init_check_recursion
tsd_init_finish
u2rz
@@ -1,5 +0,0 @@
#!/bin/sh
for symbol in `cat $1` ; do
echo "#undef ${symbol}"
done
@@ -4,7 +4,7 @@
/*
* Simple linear congruential pseudo-random number generator:
*
* prng(y) = (a*x + c) % m
* prn(y) = (a*x + c) % m
*
* where the following constants ensure maximal period:
*
@@ -25,7 +25,7 @@
* uint32_t state : Seed value.
* const uint32_t a, c : See above discussion.
*/
#define prng32(r, lg_range, state, a, c) do { \
#define prn32(r, lg_range, state, a, c) do { \
assert(lg_range > 0); \
assert(lg_range <= 32); \
\
@@ -34,8 +34,8 @@
r >>= (32 - lg_range); \
} while (false)
/* Same as prng32(), but 64 bits of pseudo-randomness, using uint64_t. */
#define prng64(r, lg_range, state, a, c) do { \
/* Same as prn32(), but 64 bits of pseudo-randomness, using uint64_t. */
#define prn64(r, lg_range, state, a, c) do { \
assert(lg_range > 0); \
assert(lg_range <= 64); \
\
+102 -168
View File
@@ -1,3 +1,4 @@
#ifdef JEMALLOC_PROF
/******************************************************************************/
#ifdef JEMALLOC_H_TYPES
@@ -8,46 +9,29 @@ typedef struct prof_ctx_s prof_ctx_t;
typedef struct prof_tdata_s prof_tdata_t;
/* Option defaults. */
#ifdef JEMALLOC_PROF
# define PROF_PREFIX_DEFAULT "jeprof"
#else
# define PROF_PREFIX_DEFAULT ""
#endif
#define LG_PROF_SAMPLE_DEFAULT 19
#define PROF_PREFIX_DEFAULT "jeprof"
#define LG_PROF_BT_MAX_DEFAULT 7
#define LG_PROF_SAMPLE_DEFAULT 0
#define LG_PROF_INTERVAL_DEFAULT -1
#define LG_PROF_TCMAX_DEFAULT -1
/*
* Hard limit on stack backtrace depth. The version of prof_backtrace() that
* is based on __builtin_return_address() necessarily has a hard-coded number
* of backtrace frame handlers, and should be kept in sync with this setting.
* Hard limit on stack backtrace depth. Note that the version of
* prof_backtrace() that is based on __builtin_return_address() necessarily has
* a hard-coded number of backtrace frame handlers.
*/
#define PROF_BT_MAX 128
/* Maximum number of backtraces to store in each per thread LRU cache. */
#define PROF_TCMAX 1024
#if (defined(JEMALLOC_PROF_LIBGCC) || defined(JEMALLOC_PROF_LIBUNWIND))
# define LG_PROF_BT_MAX ((ZU(1) << (LG_SIZEOF_PTR+3)) - 1)
#else
# define LG_PROF_BT_MAX 7 /* >= LG_PROF_BT_MAX_DEFAULT */
#endif
#define PROF_BT_MAX (1U << LG_PROF_BT_MAX)
/* Initial hash table size. */
#define PROF_CKH_MINITEMS 64
#define PROF_CKH_MINITEMS 64
/* Size of memory buffer to use when writing dump files. */
#define PROF_DUMP_BUFSIZE 65536
/* Size of stack-allocated buffer used by prof_printf(). */
#define PROF_PRINTF_BUFSIZE 128
/*
* Number of mutexes shared among all ctx's. No space is allocated for these
* unless profiling is enabled, so it's okay to over-provision.
*/
#define PROF_NCTX_LOCKS 1024
/*
* prof_tdata pointers close to NULL are used to encode state information that
* is used for cleaning up during thread shutdown.
*/
#define PROF_TDATA_STATE_REINCARNATED ((prof_tdata_t *)(uintptr_t)1)
#define PROF_TDATA_STATE_PURGATORY ((prof_tdata_t *)(uintptr_t)2)
#define PROF_TDATA_STATE_MAX PROF_TDATA_STATE_PURGATORY
#define PROF_DUMP_BUF_SIZE 65536
#endif /* JEMALLOC_H_TYPES */
/******************************************************************************/
@@ -125,19 +109,8 @@ struct prof_ctx_s {
/* Associated backtrace. */
prof_bt_t *bt;
/* Protects nlimbo, cnt_merged, and cnts_ql. */
malloc_mutex_t *lock;
/*
* Number of threads that currently cause this ctx to be in a state of
* limbo due to one of:
* - Initializing per thread counters associated with this ctx.
* - Preparing to destroy this ctx.
* - Dumping a heap profile that includes this ctx.
* nlimbo must be 1 (single destroyer) in order to safely destroy the
* ctx.
*/
unsigned nlimbo;
/* Protects cnt_merged and cnts_ql. */
malloc_mutex_t lock;
/* Temporary storage for summation during dump. */
prof_cnt_t cnt_summed;
@@ -150,11 +123,7 @@ struct prof_ctx_s {
* this context.
*/
ql_head(prof_thr_cnt_t) cnts_ql;
/* Linkage for list of contexts to be dumped. */
ql_elm(prof_ctx_t) dump_link;
};
typedef ql_head(prof_ctx_t) prof_ctx_list_t;
struct prof_tdata_s {
/*
@@ -176,14 +145,9 @@ struct prof_tdata_s {
void **vec;
/* Sampling state. */
uint64_t prng_state;
uint64_t prn_state;
uint64_t threshold;
uint64_t accum;
/* State used to avoid dumping while operating on prof internals. */
bool enq;
bool enq_idump;
bool enq_gdump;
};
#endif /* JEMALLOC_H_STRUCTS */
@@ -198,18 +162,14 @@ extern bool opt_prof;
* to notice state changes.
*/
extern bool opt_prof_active;
extern size_t opt_lg_prof_bt_max; /* Maximum backtrace depth. */
extern size_t opt_lg_prof_sample; /* Mean bytes between samples. */
extern ssize_t opt_lg_prof_interval; /* lg(prof_interval). */
extern bool opt_prof_gdump; /* High-water memory dumping. */
extern bool opt_prof_final; /* Final profile dumping. */
extern bool opt_prof_leak; /* Dump leak summary at exit. */
extern bool opt_prof_accum; /* Report cumulative bytes. */
extern char opt_prof_prefix[
/* Minimize memory bloat for non-prof builds. */
#ifdef JEMALLOC_PROF
PATH_MAX +
#endif
1];
extern ssize_t opt_lg_prof_tcmax; /* lg(max per thread bactrace cache) */
extern char opt_prof_prefix[PATH_MAX + 1];
/*
* Profile dump interval, measured in bytes allocated. Each arena triggers a
@@ -226,25 +186,42 @@ extern uint64_t prof_interval;
*/
extern bool prof_promote;
void bt_init(prof_bt_t *bt, void **vec);
void prof_backtrace(prof_bt_t *bt, unsigned nignore);
prof_thr_cnt_t *prof_lookup(prof_bt_t *bt);
#ifdef JEMALLOC_JET
size_t prof_bt_count(void);
typedef int (prof_dump_open_t)(bool, const char *);
extern prof_dump_open_t *prof_dump_open;
/* (1U << opt_lg_prof_bt_max). */
extern unsigned prof_bt_max;
/* Thread-specific backtrace cache, used to reduce bt2ctx contention. */
#ifndef NO_TLS
extern __thread prof_tdata_t *prof_tdata_tls
JEMALLOC_ATTR(tls_model("initial-exec"));
# define PROF_TCACHE_GET() prof_tdata_tls
# define PROF_TCACHE_SET(v) do { \
prof_tdata_tls = (v); \
pthread_setspecific(prof_tdata_tsd, (void *)(v)); \
} while (0)
#else
# define PROF_TCACHE_GET() \
((prof_tdata_t *)pthread_getspecific(prof_tdata_tsd))
# define PROF_TCACHE_SET(v) do { \
pthread_setspecific(prof_tdata_tsd, (void *)(v)); \
} while (0)
#endif
/*
* Same contents as b2cnt_tls, but initialized such that the TSD destructor is
* called when a thread exits, so that prof_tdata_tls contents can be merged,
* unlinked, and deallocated.
*/
extern pthread_key_t prof_tdata_tsd;
void bt_init(prof_bt_t *bt, void **vec);
void prof_backtrace(prof_bt_t *bt, unsigned nignore, unsigned max);
prof_thr_cnt_t *prof_lookup(prof_bt_t *bt);
void prof_idump(void);
bool prof_mdump(const char *filename);
void prof_gdump(void);
prof_tdata_t *prof_tdata_init(void);
void prof_tdata_cleanup(void *arg);
void prof_boot0(void);
void prof_boot1(void);
bool prof_boot2(void);
void prof_prefork(void);
void prof_postfork_parent(void);
void prof_postfork_child(void);
#endif /* JEMALLOC_H_EXTERNS */
/******************************************************************************/
@@ -256,13 +233,13 @@ void prof_postfork_child(void);
\
assert(size == s2u(size)); \
\
prof_tdata = prof_tdata_get(true); \
if ((uintptr_t)prof_tdata <= (uintptr_t)PROF_TDATA_STATE_MAX) { \
if (prof_tdata != NULL) \
ret = (prof_thr_cnt_t *)(uintptr_t)1U; \
else \
prof_tdata = PROF_TCACHE_GET(); \
if (prof_tdata == NULL) { \
prof_tdata = prof_tdata_init(); \
if (prof_tdata == NULL) { \
ret = NULL; \
break; \
break; \
} \
} \
\
if (opt_prof_active == false) { \
@@ -272,13 +249,13 @@ void prof_postfork_child(void);
/* Don't bother with sampling logic, since sampling */\
/* interval is 1. */\
bt_init(&bt, prof_tdata->vec); \
prof_backtrace(&bt, nignore); \
prof_backtrace(&bt, nignore, prof_bt_max); \
ret = prof_lookup(&bt); \
} else { \
if (prof_tdata->threshold == 0) { \
/* Initialize. Seed the prng differently for */\
/* each thread. */\
prof_tdata->prng_state = \
prof_tdata->prn_state = \
(uint64_t)(uintptr_t)&size; \
prof_sample_threshold_update(prof_tdata); \
} \
@@ -295,7 +272,7 @@ void prof_postfork_child(void);
if (size >= prof_tdata->threshold - \
prof_tdata->accum) { \
bt_init(&bt, prof_tdata->vec); \
prof_backtrace(&bt, nignore); \
prof_backtrace(&bt, nignore, prof_bt_max); \
ret = prof_lookup(&bt); \
} else \
ret = (prof_thr_cnt_t *)(uintptr_t)1U; \
@@ -303,61 +280,23 @@ void prof_postfork_child(void);
} while (0)
#ifndef JEMALLOC_ENABLE_INLINE
malloc_tsd_protos(JEMALLOC_ATTR(unused), prof_tdata, prof_tdata_t *)
prof_tdata_t *prof_tdata_get(bool create);
void prof_sample_threshold_update(prof_tdata_t *prof_tdata);
prof_ctx_t *prof_ctx_get(const void *ptr);
void prof_ctx_set(const void *ptr, size_t usize, prof_ctx_t *ctx);
void prof_ctx_set(const void *ptr, prof_ctx_t *ctx);
bool prof_sample_accum_update(size_t size);
void prof_malloc(const void *ptr, size_t usize, prof_thr_cnt_t *cnt);
void prof_realloc(const void *ptr, size_t usize, prof_thr_cnt_t *cnt,
size_t old_usize, prof_ctx_t *old_ctx);
void prof_malloc(const void *ptr, size_t size, prof_thr_cnt_t *cnt);
void prof_realloc(const void *ptr, size_t size, prof_thr_cnt_t *cnt,
size_t old_size, prof_ctx_t *old_ctx);
void prof_free(const void *ptr, size_t size);
#endif
#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_PROF_C_))
/* Thread-specific backtrace cache, used to reduce bt2ctx contention. */
malloc_tsd_externs(prof_tdata, prof_tdata_t *)
malloc_tsd_funcs(JEMALLOC_INLINE, prof_tdata, prof_tdata_t *, NULL,
prof_tdata_cleanup)
JEMALLOC_INLINE prof_tdata_t *
prof_tdata_get(bool create)
{
prof_tdata_t *prof_tdata;
cassert(config_prof);
prof_tdata = *prof_tdata_tsd_get();
if (create && prof_tdata == NULL)
prof_tdata = prof_tdata_init();
return (prof_tdata);
}
JEMALLOC_INLINE void
prof_sample_threshold_update(prof_tdata_t *prof_tdata)
{
/*
* The body of this function is compiled out unless heap profiling is
* enabled, so that it is possible to compile jemalloc with floating
* point support completely disabled. Avoiding floating point code is
* important on memory-constrained systems, but it also enables a
* workaround for versions of glibc that don't properly save/restore
* floating point registers during dynamic lazy symbol loading (which
* internally calls into whatever malloc implementation happens to be
* integrated into the application). Note that some compilers (e.g.
* gcc 4.8) may use floating point registers for fast memory moves, so
* jemalloc must be compiled with such optimizations disabled (e.g.
* -mno-sse) in order for the workaround to be complete.
*/
#ifdef JEMALLOC_PROF
uint64_t r;
double u;
cassert(config_prof);
/*
* Compute sample threshold as a geometrically distributed random
* variable with mean (2^opt_lg_prof_sample).
@@ -374,15 +313,14 @@ prof_sample_threshold_update(prof_tdata_t *prof_tdata)
* Luc Devroye
* Springer-Verlag, New York, 1986
* pp 500
* (http://luc.devroye.org/rnbookindex.html)
* (http://cg.scs.carleton.ca/~luc/rnbookindex.html)
*/
prng64(r, 53, prof_tdata->prng_state,
UINT64_C(6364136223846793005), UINT64_C(1442695040888963407));
prn64(r, 53, prof_tdata->prn_state,
(uint64_t)6364136223846793005LLU, (uint64_t)1442695040888963407LLU);
u = (double)r * (1.0/9007199254740992.0L);
prof_tdata->threshold = (uint64_t)(log(u) /
log(1.0 - (1.0 / (double)((uint64_t)1U << opt_lg_prof_sample))))
+ (uint64_t)1U;
#endif
}
JEMALLOC_INLINE prof_ctx_t *
@@ -391,12 +329,13 @@ prof_ctx_get(const void *ptr)
prof_ctx_t *ret;
arena_chunk_t *chunk;
cassert(config_prof);
assert(ptr != NULL);
chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
if (chunk != ptr) {
/* Region. */
dassert(chunk->arena->magic == ARENA_MAGIC);
ret = arena_prof_ctx_get(ptr);
} else
ret = huge_prof_ctx_get(ptr);
@@ -405,17 +344,18 @@ prof_ctx_get(const void *ptr)
}
JEMALLOC_INLINE void
prof_ctx_set(const void *ptr, size_t usize, prof_ctx_t *ctx)
prof_ctx_set(const void *ptr, prof_ctx_t *ctx)
{
arena_chunk_t *chunk;
cassert(config_prof);
assert(ptr != NULL);
chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
if (chunk != ptr) {
/* Region. */
arena_prof_ctx_set(ptr, usize, ctx);
dassert(chunk->arena->magic == ARENA_MAGIC);
arena_prof_ctx_set(ptr, ctx);
} else
huge_prof_ctx_set(ptr, ctx);
}
@@ -425,13 +365,11 @@ prof_sample_accum_update(size_t size)
{
prof_tdata_t *prof_tdata;
cassert(config_prof);
/* Sampling logic is unnecessary if the interval is 1. */
assert(opt_lg_prof_sample != 0);
prof_tdata = prof_tdata_get(false);
if ((uintptr_t)prof_tdata <= (uintptr_t)PROF_TDATA_STATE_MAX)
return (true);
prof_tdata = PROF_TCACHE_GET();
assert(prof_tdata != NULL);
/* Take care to avoid integer overflow. */
if (size >= prof_tdata->threshold - prof_tdata->accum) {
@@ -450,20 +388,19 @@ prof_sample_accum_update(size_t size)
}
JEMALLOC_INLINE void
prof_malloc(const void *ptr, size_t usize, prof_thr_cnt_t *cnt)
prof_malloc(const void *ptr, size_t size, prof_thr_cnt_t *cnt)
{
cassert(config_prof);
assert(ptr != NULL);
assert(usize == isalloc(ptr, true));
assert(size == isalloc(ptr));
if (opt_lg_prof_sample != 0) {
if (prof_sample_accum_update(usize)) {
if (prof_sample_accum_update(size)) {
/*
* Don't sample. For malloc()-like allocation, it is
* always possible to tell in advance how large an
* object's usable size will be, so there should never
* be a difference between the usize passed to
* be a difference between the size passed to
* PROF_ALLOC_PREP() and prof_malloc().
*/
assert((uintptr_t)cnt == (uintptr_t)1U);
@@ -471,17 +408,17 @@ prof_malloc(const void *ptr, size_t usize, prof_thr_cnt_t *cnt)
}
if ((uintptr_t)cnt > (uintptr_t)1U) {
prof_ctx_set(ptr, usize, cnt->ctx);
prof_ctx_set(ptr, cnt->ctx);
cnt->epoch++;
/*********/
mb_write();
/*********/
cnt->cnts.curobjs++;
cnt->cnts.curbytes += usize;
cnt->cnts.curbytes += size;
if (opt_prof_accum) {
cnt->cnts.accumobjs++;
cnt->cnts.accumbytes += usize;
cnt->cnts.accumbytes += size;
}
/*********/
mb_write();
@@ -491,28 +428,27 @@ prof_malloc(const void *ptr, size_t usize, prof_thr_cnt_t *cnt)
mb_write();
/*********/
} else
prof_ctx_set(ptr, usize, (prof_ctx_t *)(uintptr_t)1U);
prof_ctx_set(ptr, (prof_ctx_t *)(uintptr_t)1U);
}
JEMALLOC_INLINE void
prof_realloc(const void *ptr, size_t usize, prof_thr_cnt_t *cnt,
size_t old_usize, prof_ctx_t *old_ctx)
prof_realloc(const void *ptr, size_t size, prof_thr_cnt_t *cnt,
size_t old_size, prof_ctx_t *old_ctx)
{
prof_thr_cnt_t *told_cnt;
cassert(config_prof);
assert(ptr != NULL || (uintptr_t)cnt <= (uintptr_t)1U);
if (ptr != NULL) {
assert(usize == isalloc(ptr, true));
assert(size == isalloc(ptr));
if (opt_lg_prof_sample != 0) {
if (prof_sample_accum_update(usize)) {
if (prof_sample_accum_update(size)) {
/*
* Don't sample. The usize passed to
* Don't sample. The size passed to
* PROF_ALLOC_PREP() was larger than what
* actually got allocated, so a backtrace was
* captured for this allocation, even though
* its actual usize was insufficient to cross
* its actual size was insufficient to cross
* the sample threshold.
*/
cnt = (prof_thr_cnt_t *)(uintptr_t)1U;
@@ -527,10 +463,10 @@ prof_realloc(const void *ptr, size_t usize, prof_thr_cnt_t *cnt,
* It's too late to propagate OOM for this realloc(),
* so operate directly on old_cnt->ctx->cnt_merged.
*/
malloc_mutex_lock(old_ctx->lock);
malloc_mutex_lock(&old_ctx->lock);
old_ctx->cnt_merged.curobjs--;
old_ctx->cnt_merged.curbytes -= old_usize;
malloc_mutex_unlock(old_ctx->lock);
old_ctx->cnt_merged.curbytes -= old_size;
malloc_mutex_unlock(&old_ctx->lock);
told_cnt = (prof_thr_cnt_t *)(uintptr_t)1U;
}
} else
@@ -539,23 +475,23 @@ prof_realloc(const void *ptr, size_t usize, prof_thr_cnt_t *cnt,
if ((uintptr_t)told_cnt > (uintptr_t)1U)
told_cnt->epoch++;
if ((uintptr_t)cnt > (uintptr_t)1U) {
prof_ctx_set(ptr, usize, cnt->ctx);
prof_ctx_set(ptr, cnt->ctx);
cnt->epoch++;
} else if (ptr != NULL)
prof_ctx_set(ptr, usize, (prof_ctx_t *)(uintptr_t)1U);
} else
prof_ctx_set(ptr, (prof_ctx_t *)(uintptr_t)1U);
/*********/
mb_write();
/*********/
if ((uintptr_t)told_cnt > (uintptr_t)1U) {
told_cnt->cnts.curobjs--;
told_cnt->cnts.curbytes -= old_usize;
told_cnt->cnts.curbytes -= old_size;
}
if ((uintptr_t)cnt > (uintptr_t)1U) {
cnt->cnts.curobjs++;
cnt->cnts.curbytes += usize;
cnt->cnts.curbytes += size;
if (opt_prof_accum) {
cnt->cnts.accumobjs++;
cnt->cnts.accumbytes += usize;
cnt->cnts.accumbytes += size;
}
}
/*********/
@@ -574,12 +510,9 @@ prof_free(const void *ptr, size_t size)
{
prof_ctx_t *ctx = prof_ctx_get(ptr);
cassert(config_prof);
if ((uintptr_t)ctx > (uintptr_t)1) {
prof_thr_cnt_t *tcnt;
assert(size == isalloc(ptr, true));
tcnt = prof_lookup(ctx->bt);
assert(size == isalloc(ptr));
prof_thr_cnt_t *tcnt = prof_lookup(ctx->bt);
if (tcnt != NULL) {
tcnt->epoch++;
@@ -600,10 +533,10 @@ prof_free(const void *ptr, size_t size)
* OOM during free() cannot be propagated, so operate
* directly on cnt->ctx->cnt_merged.
*/
malloc_mutex_lock(ctx->lock);
malloc_mutex_lock(&ctx->lock);
ctx->cnt_merged.curobjs--;
ctx->cnt_merged.curbytes -= size;
malloc_mutex_unlock(ctx->lock);
malloc_mutex_unlock(&ctx->lock);
}
}
}
@@ -611,3 +544,4 @@ prof_free(const void *ptr, size_t size)
#endif /* JEMALLOC_H_INLINES */
/******************************************************************************/
#endif /* JEMALLOC_PROF */
@@ -1,6 +0,0 @@
#!/bin/sh
for nm in `cat $1` ; do
n=`echo ${nm} |tr ':' ' ' |awk '{print $1}'`
echo "#define je_${n} JEMALLOC_N(${n})"
done
@@ -1,6 +0,0 @@
#!/bin/sh
for nm in `cat $1` ; do
n=`echo ${nm} |tr ':' ' ' |awk '{print $1}'`
echo "#undef je_${n}"
done
+18 -18
View File
@@ -1,61 +1,61 @@
/*
* List definitions.
*/
#define ql_head(a_type) \
#define ql_head(a_type) \
struct { \
a_type *qlh_first; \
}
#define ql_head_initializer(a_head) {NULL}
#define ql_head_initializer(a_head) {NULL}
#define ql_elm(a_type) qr(a_type)
#define ql_elm(a_type) qr(a_type)
/* List functions. */
#define ql_new(a_head) do { \
#define ql_new(a_head) do { \
(a_head)->qlh_first = NULL; \
} while (0)
#define ql_elm_new(a_elm, a_field) qr_new((a_elm), a_field)
#define ql_elm_new(a_elm, a_field) qr_new((a_elm), a_field)
#define ql_first(a_head) ((a_head)->qlh_first)
#define ql_first(a_head) ((a_head)->qlh_first)
#define ql_last(a_head, a_field) \
#define ql_last(a_head, a_field) \
((ql_first(a_head) != NULL) \
? qr_prev(ql_first(a_head), a_field) : NULL)
#define ql_next(a_head, a_elm, a_field) \
#define ql_next(a_head, a_elm, a_field) \
((ql_last(a_head, a_field) != (a_elm)) \
? qr_next((a_elm), a_field) : NULL)
#define ql_prev(a_head, a_elm, a_field) \
#define ql_prev(a_head, a_elm, a_field) \
((ql_first(a_head) != (a_elm)) ? qr_prev((a_elm), a_field) \
: NULL)
#define ql_before_insert(a_head, a_qlelm, a_elm, a_field) do { \
#define ql_before_insert(a_head, a_qlelm, a_elm, a_field) do { \
qr_before_insert((a_qlelm), (a_elm), a_field); \
if (ql_first(a_head) == (a_qlelm)) { \
ql_first(a_head) = (a_elm); \
} \
} while (0)
#define ql_after_insert(a_qlelm, a_elm, a_field) \
#define ql_after_insert(a_qlelm, a_elm, a_field) \
qr_after_insert((a_qlelm), (a_elm), a_field)
#define ql_head_insert(a_head, a_elm, a_field) do { \
#define ql_head_insert(a_head, a_elm, a_field) do { \
if (ql_first(a_head) != NULL) { \
qr_before_insert(ql_first(a_head), (a_elm), a_field); \
} \
ql_first(a_head) = (a_elm); \
} while (0)
#define ql_tail_insert(a_head, a_elm, a_field) do { \
#define ql_tail_insert(a_head, a_elm, a_field) do { \
if (ql_first(a_head) != NULL) { \
qr_before_insert(ql_first(a_head), (a_elm), a_field); \
} \
ql_first(a_head) = qr_next((a_elm), a_field); \
} while (0)
#define ql_remove(a_head, a_elm, a_field) do { \
#define ql_remove(a_head, a_elm, a_field) do { \
if (ql_first(a_head) == (a_elm)) { \
ql_first(a_head) = qr_next(ql_first(a_head), a_field); \
} \
@@ -66,18 +66,18 @@ struct { \
} \
} while (0)
#define ql_head_remove(a_head, a_type, a_field) do { \
#define ql_head_remove(a_head, a_type, a_field) do { \
a_type *t = ql_first(a_head); \
ql_remove((a_head), t, a_field); \
} while (0)
#define ql_tail_remove(a_head, a_type, a_field) do { \
#define ql_tail_remove(a_head, a_type, a_field) do { \
a_type *t = ql_last(a_head, a_field); \
ql_remove((a_head), t, a_field); \
} while (0)
#define ql_foreach(a_var, a_head, a_field) \
#define ql_foreach(a_var, a_head, a_field) \
qr_foreach((a_var), ql_first(a_head), a_field)
#define ql_reverse_foreach(a_var, a_head, a_field) \
#define ql_reverse_foreach(a_var, a_head, a_field) \
qr_reverse_foreach((a_var), ql_first(a_head), a_field)
+11 -11
View File
@@ -1,28 +1,28 @@
/* Ring definitions. */
#define qr(a_type) \
#define qr(a_type) \
struct { \
a_type *qre_next; \
a_type *qre_prev; \
}
/* Ring functions. */
#define qr_new(a_qr, a_field) do { \
#define qr_new(a_qr, a_field) do { \
(a_qr)->a_field.qre_next = (a_qr); \
(a_qr)->a_field.qre_prev = (a_qr); \
} while (0)
#define qr_next(a_qr, a_field) ((a_qr)->a_field.qre_next)
#define qr_next(a_qr, a_field) ((a_qr)->a_field.qre_next)
#define qr_prev(a_qr, a_field) ((a_qr)->a_field.qre_prev)
#define qr_prev(a_qr, a_field) ((a_qr)->a_field.qre_prev)
#define qr_before_insert(a_qrelm, a_qr, a_field) do { \
#define qr_before_insert(a_qrelm, a_qr, a_field) do { \
(a_qr)->a_field.qre_prev = (a_qrelm)->a_field.qre_prev; \
(a_qr)->a_field.qre_next = (a_qrelm); \
(a_qr)->a_field.qre_prev->a_field.qre_next = (a_qr); \
(a_qrelm)->a_field.qre_prev = (a_qr); \
} while (0)
#define qr_after_insert(a_qrelm, a_qr, a_field) \
#define qr_after_insert(a_qrelm, a_qr, a_field) \
do \
{ \
(a_qr)->a_field.qre_next = (a_qrelm)->a_field.qre_next; \
@@ -31,7 +31,7 @@ struct { \
(a_qrelm)->a_field.qre_next = (a_qr); \
} while (0)
#define qr_meld(a_qr_a, a_qr_b, a_field) do { \
#define qr_meld(a_qr_a, a_qr_b, a_field) do { \
void *t; \
(a_qr_a)->a_field.qre_prev->a_field.qre_next = (a_qr_b); \
(a_qr_b)->a_field.qre_prev->a_field.qre_next = (a_qr_a); \
@@ -42,10 +42,10 @@ struct { \
/* qr_meld() and qr_split() are functionally equivalent, so there's no need to
* have two copies of the code. */
#define qr_split(a_qr_a, a_qr_b, a_field) \
#define qr_split(a_qr_a, a_qr_b, a_field) \
qr_meld((a_qr_a), (a_qr_b), a_field)
#define qr_remove(a_qr, a_field) do { \
#define qr_remove(a_qr, a_field) do { \
(a_qr)->a_field.qre_prev->a_field.qre_next \
= (a_qr)->a_field.qre_next; \
(a_qr)->a_field.qre_next->a_field.qre_prev \
@@ -54,13 +54,13 @@ struct { \
(a_qr)->a_field.qre_prev = (a_qr); \
} while (0)
#define qr_foreach(var, a_qr, a_field) \
#define qr_foreach(var, a_qr, a_field) \
for ((var) = (a_qr); \
(var) != NULL; \
(var) = (((var)->a_field.qre_next != (a_qr)) \
? (var)->a_field.qre_next : NULL))
#define qr_reverse_foreach(var, a_qr, a_field) \
#define qr_reverse_foreach(var, a_qr, a_field) \
for ((var) = ((a_qr) != NULL) ? qr_prev(a_qr, a_field) : NULL; \
(var) != NULL; \
(var) = (((var) != (a_qr)) \
-67
View File
@@ -1,67 +0,0 @@
/******************************************************************************/
#ifdef JEMALLOC_H_TYPES
typedef struct quarantine_obj_s quarantine_obj_t;
typedef struct quarantine_s quarantine_t;
/* Default per thread quarantine size if valgrind is enabled. */
#define JEMALLOC_VALGRIND_QUARANTINE_DEFAULT (ZU(1) << 24)
#endif /* JEMALLOC_H_TYPES */
/******************************************************************************/
#ifdef JEMALLOC_H_STRUCTS
struct quarantine_obj_s {
void *ptr;
size_t usize;
};
struct quarantine_s {
size_t curbytes;
size_t curobjs;
size_t first;
#define LG_MAXOBJS_INIT 10
size_t lg_maxobjs;
quarantine_obj_t objs[1]; /* Dynamically sized ring buffer. */
};
#endif /* JEMALLOC_H_STRUCTS */
/******************************************************************************/
#ifdef JEMALLOC_H_EXTERNS
quarantine_t *quarantine_init(size_t lg_maxobjs);
void quarantine(void *ptr);
void quarantine_cleanup(void *arg);
bool quarantine_boot(void);
#endif /* JEMALLOC_H_EXTERNS */
/******************************************************************************/
#ifdef JEMALLOC_H_INLINES
#ifndef JEMALLOC_ENABLE_INLINE
malloc_tsd_protos(JEMALLOC_ATTR(unused), quarantine, quarantine_t *)
void quarantine_alloc_hook(void);
#endif
#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_QUARANTINE_C_))
malloc_tsd_externs(quarantine, quarantine_t *)
malloc_tsd_funcs(JEMALLOC_ALWAYS_INLINE, quarantine, quarantine_t *, NULL,
quarantine_cleanup)
JEMALLOC_ALWAYS_INLINE void
quarantine_alloc_hook(void)
{
quarantine_t *quarantine;
assert(config_fill && opt_quarantine);
quarantine = *quarantine_tsd_get();
if (quarantine == NULL)
quarantine_init(LG_MAXOBJS_INIT);
}
#endif
#endif /* JEMALLOC_H_INLINES */
/******************************************************************************/
+50 -46
View File
@@ -22,6 +22,10 @@
#ifndef RB_H_
#define RB_H_
#if 0
__FBSDID("$FreeBSD: head/lib/libc/stdlib/rb.h 204493 2010-02-28 22:57:13Z jasone $");
#endif
#ifdef RB_COMPACT
/* Node structure. */
#define rb_node(a_type) \
@@ -219,88 +223,88 @@ a_prefix##reverse_iter(a_rbt_type *rbtree, a_type *start, \
* The following API is generated:
*
* static void
* ex_new(ex_t *tree);
* ex_new(ex_t *extree);
* Description: Initialize a red-black tree structure.
* Args:
* tree: Pointer to an uninitialized red-black tree object.
* extree: Pointer to an uninitialized red-black tree object.
*
* static ex_node_t *
* ex_first(ex_t *tree);
* ex_first(ex_t *extree);
* static ex_node_t *
* ex_last(ex_t *tree);
* Description: Get the first/last node in tree.
* ex_last(ex_t *extree);
* Description: Get the first/last node in extree.
* Args:
* tree: Pointer to an initialized red-black tree object.
* Ret: First/last node in tree, or NULL if tree is empty.
* extree: Pointer to an initialized red-black tree object.
* Ret: First/last node in extree, or NULL if extree is empty.
*
* static ex_node_t *
* ex_next(ex_t *tree, ex_node_t *node);
* ex_next(ex_t *extree, ex_node_t *node);
* static ex_node_t *
* ex_prev(ex_t *tree, ex_node_t *node);
* ex_prev(ex_t *extree, ex_node_t *node);
* Description: Get node's successor/predecessor.
* Args:
* tree: Pointer to an initialized red-black tree object.
* node: A node in tree.
* Ret: node's successor/predecessor in tree, or NULL if node is
* extree: Pointer to an initialized red-black tree object.
* node : A node in extree.
* Ret: node's successor/predecessor in extree, or NULL if node is
* last/first.
*
* static ex_node_t *
* ex_search(ex_t *tree, ex_node_t *key);
* ex_search(ex_t *extree, ex_node_t *key);
* Description: Search for node that matches key.
* Args:
* tree: Pointer to an initialized red-black tree object.
* key : Search key.
* Ret: Node in tree that matches key, or NULL if no match.
* extree: Pointer to an initialized red-black tree object.
* key : Search key.
* Ret: Node in extree that matches key, or NULL if no match.
*
* static ex_node_t *
* ex_nsearch(ex_t *tree, ex_node_t *key);
* ex_nsearch(ex_t *extree, ex_node_t *key);
* static ex_node_t *
* ex_psearch(ex_t *tree, ex_node_t *key);
* ex_psearch(ex_t *extree, ex_node_t *key);
* Description: Search for node that matches key. If no match is found,
* return what would be key's successor/predecessor, were
* key in tree.
* key in extree.
* Args:
* tree: Pointer to an initialized red-black tree object.
* key : Search key.
* Ret: Node in tree that matches key, or if no match, hypothetical node's
* successor/predecessor (NULL if no successor/predecessor).
* extree: Pointer to an initialized red-black tree object.
* key : Search key.
* Ret: Node in extree that matches key, or if no match, hypothetical
* node's successor/predecessor (NULL if no successor/predecessor).
*
* static void
* ex_insert(ex_t *tree, ex_node_t *node);
* Description: Insert node into tree.
* ex_insert(ex_t *extree, ex_node_t *node);
* Description: Insert node into extree.
* Args:
* tree: Pointer to an initialized red-black tree object.
* node: Node to be inserted into tree.
* extree: Pointer to an initialized red-black tree object.
* node : Node to be inserted into extree.
*
* static void
* ex_remove(ex_t *tree, ex_node_t *node);
* Description: Remove node from tree.
* ex_remove(ex_t *extree, ex_node_t *node);
* Description: Remove node from extree.
* Args:
* tree: Pointer to an initialized red-black tree object.
* node: Node in tree to be removed.
* extree: Pointer to an initialized red-black tree object.
* node : Node in extree to be removed.
*
* static ex_node_t *
* ex_iter(ex_t *tree, ex_node_t *start, ex_node_t *(*cb)(ex_t *,
* ex_iter(ex_t *extree, ex_node_t *start, ex_node_t *(*cb)(ex_t *,
* ex_node_t *, void *), void *arg);
* static ex_node_t *
* ex_reverse_iter(ex_t *tree, ex_node_t *start, ex_node *(*cb)(ex_t *,
* ex_reverse_iter(ex_t *extree, ex_node_t *start, ex_node *(*cb)(ex_t *,
* ex_node_t *, void *), void *arg);
* Description: Iterate forward/backward over tree, starting at node. If
* tree is modified, iteration must be immediately
* Description: Iterate forward/backward over extree, starting at node.
* If extree is modified, iteration must be immediately
* terminated by the callback function that causes the
* modification.
* Args:
* tree : Pointer to an initialized red-black tree object.
* start: Node at which to start iteration, or NULL to start at
* first/last node.
* cb : Callback function, which is called for each node during
* iteration. Under normal circumstances the callback function
* should return NULL, which causes iteration to continue. If a
* callback function returns non-NULL, iteration is immediately
* terminated and the non-NULL return value is returned by the
* iterator. This is useful for re-starting iteration after
* modifying tree.
* arg : Opaque pointer passed to cb().
* extree: Pointer to an initialized red-black tree object.
* start : Node at which to start iteration, or NULL to start at
* first/last node.
* cb : Callback function, which is called for each node during
* iteration. Under normal circumstances the callback function
* should return NULL, which causes iteration to continue. If a
* callback function returns non-NULL, iteration is immediately
* terminated and the non-NULL return value is returned by the
* iterator. This is useful for re-starting iteration after
* modifying extree.
* arg : Opaque pointer passed to cb().
* Ret: NULL if iteration completed, or the non-NULL callback return value
* that caused termination of the iteration.
*/
+21 -32
View File
@@ -14,18 +14,17 @@ typedef struct rtree_s rtree_t;
* Size of each radix tree node (must be a power of 2). This impacts tree
* depth.
*/
#define RTREE_NODESIZE (1U << 16)
typedef void *(rtree_alloc_t)(size_t);
typedef void (rtree_dalloc_t)(void *);
#if (LG_SIZEOF_PTR == 2)
# define RTREE_NODESIZE (1U << 14)
#else
# define RTREE_NODESIZE CACHELINE
#endif
#endif /* JEMALLOC_H_TYPES */
/******************************************************************************/
#ifdef JEMALLOC_H_STRUCTS
struct rtree_s {
rtree_alloc_t *alloc;
rtree_dalloc_t *dalloc;
malloc_mutex_t mutex;
void **root;
unsigned height;
@@ -36,31 +35,27 @@ struct rtree_s {
/******************************************************************************/
#ifdef JEMALLOC_H_EXTERNS
rtree_t *rtree_new(unsigned bits, rtree_alloc_t *alloc, rtree_dalloc_t *dalloc);
void rtree_delete(rtree_t *rtree);
void rtree_prefork(rtree_t *rtree);
void rtree_postfork_parent(rtree_t *rtree);
void rtree_postfork_child(rtree_t *rtree);
rtree_t *rtree_new(unsigned bits);
#endif /* JEMALLOC_H_EXTERNS */
/******************************************************************************/
#ifdef JEMALLOC_H_INLINES
#ifndef JEMALLOC_ENABLE_INLINE
#ifdef JEMALLOC_DEBUG
uint8_t rtree_get_locked(rtree_t *rtree, uintptr_t key);
#ifndef JEMALLOC_DEBUG
void *rtree_get_locked(rtree_t *rtree, uintptr_t key);
#endif
uint8_t rtree_get(rtree_t *rtree, uintptr_t key);
bool rtree_set(rtree_t *rtree, uintptr_t key, uint8_t val);
void *rtree_get(rtree_t *rtree, uintptr_t key);
bool rtree_set(rtree_t *rtree, uintptr_t key, void *val);
#endif
#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_RTREE_C_))
#define RTREE_GET_GENERATE(f) \
/* The least significant bits of the key are ignored. */ \
JEMALLOC_INLINE uint8_t \
JEMALLOC_INLINE void * \
f(rtree_t *rtree, uintptr_t key) \
{ \
uint8_t ret; \
void *ret; \
uintptr_t subkey; \
unsigned i, lshift, height, bits; \
void **node, **child; \
@@ -70,12 +65,12 @@ f(rtree_t *rtree, uintptr_t key) \
i < height - 1; \
i++, lshift += bits, node = child) { \
bits = rtree->level2bits[i]; \
subkey = (key << lshift) >> ((ZU(1) << (LG_SIZEOF_PTR + \
subkey = (key << lshift) >> ((ZU(1) << (LG_SIZEOF_PTR + \
3)) - bits); \
child = (void**)node[subkey]; \
if (child == NULL) { \
RTREE_UNLOCK(&rtree->mutex); \
return (0); \
return (NULL); \
} \
} \
\
@@ -86,10 +81,7 @@ f(rtree_t *rtree, uintptr_t key) \
bits = rtree->level2bits[i]; \
subkey = (key << lshift) >> ((ZU(1) << (LG_SIZEOF_PTR+3)) - \
bits); \
{ \
uint8_t *leaf = (uint8_t *)node; \
ret = leaf[subkey]; \
} \
ret = node[subkey]; \
RTREE_UNLOCK(&rtree->mutex); \
\
RTREE_GET_VALIDATE \
@@ -128,7 +120,7 @@ RTREE_GET_GENERATE(rtree_get)
#undef RTREE_GET_VALIDATE
JEMALLOC_INLINE bool
rtree_set(rtree_t *rtree, uintptr_t key, uint8_t val)
rtree_set(rtree_t *rtree, uintptr_t key, void *val)
{
uintptr_t subkey;
unsigned i, lshift, height, bits;
@@ -143,14 +135,14 @@ rtree_set(rtree_t *rtree, uintptr_t key, uint8_t val)
bits);
child = (void**)node[subkey];
if (child == NULL) {
size_t size = ((i + 1 < height - 1) ? sizeof(void *)
: (sizeof(uint8_t))) << rtree->level2bits[i+1];
child = (void**)rtree->alloc(size);
child = (void**)base_alloc(sizeof(void *) <<
rtree->level2bits[i+1]);
if (child == NULL) {
malloc_mutex_unlock(&rtree->mutex);
return (true);
}
memset(child, 0, size);
memset(child, 0, sizeof(void *) <<
rtree->level2bits[i+1]);
node[subkey] = child;
}
}
@@ -158,10 +150,7 @@ rtree_set(rtree_t *rtree, uintptr_t key, uint8_t val)
/* node is a leaf, so it contains values rather than node pointers. */
bits = rtree->level2bits[i];
subkey = (key << lshift) >> ((ZU(1) << (LG_SIZEOF_PTR+3)) - bits);
{
uint8_t *leaf = (uint8_t *)node;
leaf[subkey] = val;
}
node[subkey] = val;
malloc_mutex_unlock(&rtree->mutex);
return (false);
-122
View File
@@ -1,122 +0,0 @@
#!/bin/sh
# The following limits are chosen such that they cover all supported platforms.
# Range of quanta.
lg_qmin=3
lg_qmax=4
# The range of tiny size classes is [2^lg_tmin..2^(lg_q-1)].
lg_tmin=3
# Range of page sizes.
lg_pmin=12
lg_pmax=16
pow2() {
e=$1
pow2_result=1
while [ ${e} -gt 0 ] ; do
pow2_result=$((${pow2_result} + ${pow2_result}))
e=$((${e} - 1))
done
}
cat <<EOF
/* This file was automatically generated by size_classes.sh. */
/******************************************************************************/
#ifdef JEMALLOC_H_TYPES
EOF
lg_q=${lg_qmin}
while [ ${lg_q} -le ${lg_qmax} ] ; do
lg_t=${lg_tmin}
while [ ${lg_t} -le ${lg_q} ] ; do
lg_p=${lg_pmin}
while [ ${lg_p} -le ${lg_pmax} ] ; do
echo "#if (LG_TINY_MIN == ${lg_t} && LG_QUANTUM == ${lg_q} && LG_PAGE == ${lg_p})"
echo "#define SIZE_CLASSES_DEFINED"
pow2 ${lg_q}; q=${pow2_result}
pow2 ${lg_t}; t=${pow2_result}
pow2 ${lg_p}; p=${pow2_result}
bin=0
psz=0
sz=${t}
delta=$((${sz} - ${psz}))
echo "/* SIZE_CLASS(bin, delta, sz) */"
echo "#define SIZE_CLASSES \\"
# Tiny size classes.
while [ ${sz} -lt ${q} ] ; do
echo " SIZE_CLASS(${bin}, ${delta}, ${sz}) \\"
bin=$((${bin} + 1))
psz=${sz}
sz=$((${sz} + ${sz}))
delta=$((${sz} - ${psz}))
done
# Quantum-multiple size classes. For each doubling of sz, as many as 4
# size classes exist. Their spacing is the greater of:
# - q
# - sz/4, where sz is a power of 2
while [ ${sz} -lt ${p} ] ; do
if [ ${sz} -ge $((${q} * 4)) ] ; then
i=$((${sz} / 4))
else
i=${q}
fi
next_2pow=$((${sz} * 2))
while [ ${sz} -lt $next_2pow ] ; do
echo " SIZE_CLASS(${bin}, ${delta}, ${sz}) \\"
bin=$((${bin} + 1))
psz=${sz}
sz=$((${sz} + ${i}))
delta=$((${sz} - ${psz}))
done
done
echo
echo "#define NBINS ${bin}"
echo "#define SMALL_MAXCLASS ${psz}"
echo "#endif"
echo
lg_p=$((${lg_p} + 1))
done
lg_t=$((${lg_t} + 1))
done
lg_q=$((${lg_q} + 1))
done
cat <<EOF
#ifndef SIZE_CLASSES_DEFINED
# error "No size class definitions match configuration"
#endif
#undef SIZE_CLASSES_DEFINED
/*
* The small_size2bin lookup table uses uint8_t to encode each bin index, so we
* cannot support more than 256 small size classes. Further constrain NBINS to
* 255 to support prof_promote, since all small size classes, plus a "not
* small" size class must be stored in 8 bits of arena_chunk_map_t's bits
* field.
*/
#if (NBINS > 255)
# error "Too many small size classes"
#endif
#endif /* JEMALLOC_H_TYPES */
/******************************************************************************/
#ifdef JEMALLOC_H_STRUCTS
#endif /* JEMALLOC_H_STRUCTS */
/******************************************************************************/
#ifdef JEMALLOC_H_EXTERNS
#endif /* JEMALLOC_H_EXTERNS */
/******************************************************************************/
#ifdef JEMALLOC_H_INLINES
#endif /* JEMALLOC_H_INLINES */
/******************************************************************************/
EOF
+34
View File
@@ -1,16 +1,25 @@
/******************************************************************************/
#ifdef JEMALLOC_H_TYPES
#define UMAX2S_BUFSIZE 65
#ifdef JEMALLOC_STATS
typedef struct tcache_bin_stats_s tcache_bin_stats_t;
typedef struct malloc_bin_stats_s malloc_bin_stats_t;
typedef struct malloc_large_stats_s malloc_large_stats_t;
typedef struct arena_stats_s arena_stats_t;
#endif
#if (defined(JEMALLOC_STATS) || defined(JEMALLOC_PROF))
typedef struct chunk_stats_s chunk_stats_t;
#endif
#endif /* JEMALLOC_H_TYPES */
/******************************************************************************/
#ifdef JEMALLOC_H_STRUCTS
#ifdef JEMALLOC_STATS
#ifdef JEMALLOC_TCACHE
struct tcache_bin_stats_s {
/*
* Number of allocation requests that corresponded to the size of this
@@ -18,6 +27,7 @@ struct tcache_bin_stats_s {
*/
uint64_t nrequests;
};
#endif
struct malloc_bin_stats_s {
/*
@@ -42,11 +52,13 @@ struct malloc_bin_stats_s {
*/
uint64_t nrequests;
#ifdef JEMALLOC_TCACHE
/* Number of tcache fills from this bin. */
uint64_t nfills;
/* Number of tcache flushes to this bin. */
uint64_t nflushes;
#endif
/* Total number of runs created for this bin's size class. */
uint64_t nruns;
@@ -57,6 +69,9 @@ struct malloc_bin_stats_s {
*/
uint64_t reruns;
/* High-water mark for this bin. */
size_t highruns;
/* Current number of runs in this bin. */
size_t curruns;
};
@@ -78,6 +93,9 @@ struct malloc_large_stats_s {
*/
uint64_t nrequests;
/* High-water mark for this size class. */
size_t highruns;
/* Current number of runs of this size class. */
size_t curruns;
};
@@ -109,10 +127,14 @@ struct arena_stats_s {
*/
malloc_large_stats_t *lstats;
};
#endif /* JEMALLOC_STATS */
#if (defined(JEMALLOC_STATS) || defined(JEMALLOC_PROF))
struct chunk_stats_s {
# ifdef JEMALLOC_STATS
/* Number of chunks that were allocated. */
uint64_t nchunks;
# endif
/* High-water mark for number of chunks allocated. */
size_t highchunks;
@@ -124,6 +146,7 @@ struct chunk_stats_s {
*/
size_t curchunks;
};
#endif /* JEMALLOC_STATS */
#endif /* JEMALLOC_H_STRUCTS */
/******************************************************************************/
@@ -131,14 +154,24 @@ struct chunk_stats_s {
extern bool opt_stats_print;
#ifdef JEMALLOC_STATS
extern size_t stats_cactive;
#endif
char *u2s(uint64_t x, unsigned base, char *s);
#ifdef JEMALLOC_STATS
void malloc_cprintf(void (*write)(void *, const char *), void *cbopaque,
const char *format, ...) JEMALLOC_ATTR(format(printf, 3, 4));
void malloc_printf(const char *format, ...)
JEMALLOC_ATTR(format(printf, 1, 2));
#endif
void stats_print(void (*write)(void *, const char *), void *cbopaque,
const char *opts);
#endif /* JEMALLOC_H_EXTERNS */
/******************************************************************************/
#ifdef JEMALLOC_H_INLINES
#ifdef JEMALLOC_STATS
#ifndef JEMALLOC_ENABLE_INLINE
size_t stats_cactive_get(void);
@@ -169,5 +202,6 @@ stats_cactive_sub(size_t size)
}
#endif
#endif /* JEMALLOC_STATS */
#endif /* JEMALLOC_H_INLINES */
/******************************************************************************/
+203 -215
View File
@@ -1,3 +1,4 @@
#ifdef JEMALLOC_TCACHE
/******************************************************************************/
#ifdef JEMALLOC_H_TYPES
@@ -5,16 +6,6 @@ typedef struct tcache_bin_info_s tcache_bin_info_t;
typedef struct tcache_bin_s tcache_bin_t;
typedef struct tcache_s tcache_t;
/*
* tcache pointers close to NULL are used to encode state information that is
* used for two purposes: preventing thread caching on a per thread basis and
* cleaning up during thread shutdown.
*/
#define TCACHE_STATE_DISABLED ((tcache_t *)(uintptr_t)1)
#define TCACHE_STATE_REINCARNATED ((tcache_t *)(uintptr_t)2)
#define TCACHE_STATE_PURGATORY ((tcache_t *)(uintptr_t)3)
#define TCACHE_STATE_MAX TCACHE_STATE_PURGATORY
/*
* Absolute maximum number of cache slots for each small bin in the thread
* cache. This is an additional constraint beyond that imposed as: twice the
@@ -31,26 +22,17 @@ typedef struct tcache_s tcache_t;
#define LG_TCACHE_MAXCLASS_DEFAULT 15
/*
* TCACHE_GC_SWEEP is the approximate number of allocation events between
* full GC sweeps. Integer rounding may cause the actual number to be
* slightly higher, since GC is performed incrementally.
* (1U << opt_lg_tcache_gc_sweep) is the approximate number of allocation
* events between full GC sweeps (-1: disabled). Integer rounding may cause
* the actual number to be slightly higher, since GC is performed
* incrementally.
*/
#define TCACHE_GC_SWEEP 8192
/* Number of tcache allocation/deallocation events between incremental GCs. */
#define TCACHE_GC_INCR \
((TCACHE_GC_SWEEP / NBINS) + ((TCACHE_GC_SWEEP / NBINS == 0) ? 0 : 1))
#define LG_TCACHE_GC_SWEEP_DEFAULT 13
#endif /* JEMALLOC_H_TYPES */
/******************************************************************************/
#ifdef JEMALLOC_H_STRUCTS
typedef enum {
tcache_enabled_false = 0, /* Enable cast to/from bool. */
tcache_enabled_true = 1,
tcache_enabled_default = 2
} tcache_enabled_t;
/*
* Read-only information associated with each element of tcache_t's tbins array
* is stored separately, mainly to reduce memory usage.
@@ -60,7 +42,9 @@ struct tcache_bin_info_s {
};
struct tcache_bin_s {
# ifdef JEMALLOC_STATS
tcache_bin_stats_t tstats;
# endif
int low_water; /* Min # cached since last GC. */
unsigned lg_fill_div; /* Fill (ncached_max >> lg_fill_div). */
unsigned ncached; /* # of cached objects. */
@@ -68,8 +52,12 @@ struct tcache_bin_s {
};
struct tcache_s {
# ifdef JEMALLOC_STATS
ql_elm(tcache_t) link; /* Used for aggregating stats. */
# endif
# ifdef JEMALLOC_PROF
uint64_t prof_accumbytes;/* Cleared after arena_prof_accum() */
# endif
arena_t *arena; /* This thread's arena. */
unsigned ev_cnt; /* Event count since incremental GC. */
unsigned next_gc_bin; /* Next bin to GC. */
@@ -88,11 +76,29 @@ struct tcache_s {
extern bool opt_tcache;
extern ssize_t opt_lg_tcache_max;
extern ssize_t opt_lg_tcache_gc_sweep;
extern tcache_bin_info_t *tcache_bin_info;
/* Map of thread-specific caches. */
#ifndef NO_TLS
extern __thread tcache_t *tcache_tls
JEMALLOC_ATTR(tls_model("initial-exec"));
# define TCACHE_GET() tcache_tls
# define TCACHE_SET(v) do { \
tcache_tls = (tcache_t *)(v); \
pthread_setspecific(tcache_tsd, (void *)(v)); \
} while (0)
#else
# define TCACHE_GET() ((tcache_t *)pthread_getspecific(tcache_tsd))
# define TCACHE_SET(v) do { \
pthread_setspecific(tcache_tsd, (void *)(v)); \
} while (0)
#endif
extern pthread_key_t tcache_tsd;
/*
* Number of tcache bins. There are NBINS small-object bins, plus 0 or more
* Number of tcache bins. There are nbins small-object bins, plus 0 or more
* large-object bins.
*/
extern size_t nhbins;
@@ -100,178 +106,134 @@ extern size_t nhbins;
/* Maximum cached size class. */
extern size_t tcache_maxclass;
size_t tcache_salloc(const void *ptr);
void tcache_event_hard(tcache_t *tcache);
/* Number of tcache allocation/deallocation events between incremental GCs. */
extern unsigned tcache_gc_incr;
void tcache_bin_flush_small(tcache_bin_t *tbin, size_t binind, unsigned rem
#if (defined(JEMALLOC_STATS) || defined(JEMALLOC_PROF))
, tcache_t *tcache
#endif
);
void tcache_bin_flush_large(tcache_bin_t *tbin, size_t binind, unsigned rem
#if (defined(JEMALLOC_STATS) || defined(JEMALLOC_PROF))
, tcache_t *tcache
#endif
);
tcache_t *tcache_create(arena_t *arena);
void *tcache_alloc_small_hard(tcache_t *tcache, tcache_bin_t *tbin,
size_t binind);
void tcache_bin_flush_small(tcache_bin_t *tbin, size_t binind, unsigned rem,
tcache_t *tcache);
void tcache_bin_flush_large(tcache_bin_t *tbin, size_t binind, unsigned rem,
tcache_t *tcache);
void tcache_arena_associate(tcache_t *tcache, arena_t *arena);
void tcache_arena_dissociate(tcache_t *tcache);
tcache_t *tcache_create(arena_t *arena);
void tcache_destroy(tcache_t *tcache);
void tcache_thread_cleanup(void *arg);
#ifdef JEMALLOC_STATS
void tcache_stats_merge(tcache_t *tcache, arena_t *arena);
bool tcache_boot0(void);
bool tcache_boot1(void);
#endif
bool tcache_boot(void);
#endif /* JEMALLOC_H_EXTERNS */
/******************************************************************************/
#ifdef JEMALLOC_H_INLINES
#ifndef JEMALLOC_ENABLE_INLINE
malloc_tsd_protos(JEMALLOC_ATTR(unused), tcache, tcache_t *)
malloc_tsd_protos(JEMALLOC_ATTR(unused), tcache_enabled, tcache_enabled_t)
void tcache_event(tcache_t *tcache);
void tcache_flush(void);
bool tcache_enabled_get(void);
tcache_t *tcache_get(bool create);
void tcache_enabled_set(bool enabled);
tcache_t *tcache_get(void);
void *tcache_alloc_easy(tcache_bin_t *tbin);
void *tcache_alloc_small(tcache_t *tcache, size_t size, bool zero);
void *tcache_alloc_large(tcache_t *tcache, size_t size, bool zero);
void tcache_dalloc_small(tcache_t *tcache, void *ptr, size_t binind);
void tcache_dalloc_small(tcache_t *tcache, void *ptr);
void tcache_dalloc_large(tcache_t *tcache, void *ptr, size_t size);
#endif
#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_TCACHE_C_))
/* Map of thread-specific caches. */
malloc_tsd_externs(tcache, tcache_t *)
malloc_tsd_funcs(JEMALLOC_ALWAYS_INLINE, tcache, tcache_t *, NULL,
tcache_thread_cleanup)
/* Per thread flag that allows thread caches to be disabled. */
malloc_tsd_externs(tcache_enabled, tcache_enabled_t)
malloc_tsd_funcs(JEMALLOC_ALWAYS_INLINE, tcache_enabled, tcache_enabled_t,
tcache_enabled_default, malloc_tsd_no_cleanup)
JEMALLOC_INLINE void
tcache_flush(void)
JEMALLOC_INLINE tcache_t *
tcache_get(void)
{
tcache_t *tcache;
cassert(config_tcache);
tcache = *tcache_tsd_get();
if ((uintptr_t)tcache <= (uintptr_t)TCACHE_STATE_MAX)
return;
tcache_destroy(tcache);
tcache = NULL;
tcache_tsd_set(&tcache);
}
JEMALLOC_INLINE bool
tcache_enabled_get(void)
{
tcache_enabled_t tcache_enabled;
cassert(config_tcache);
tcache_enabled = *tcache_enabled_tsd_get();
if (tcache_enabled == tcache_enabled_default) {
tcache_enabled = (tcache_enabled_t)opt_tcache;
tcache_enabled_tsd_set(&tcache_enabled);
}
return ((bool)tcache_enabled);
}
JEMALLOC_INLINE void
tcache_enabled_set(bool enabled)
{
tcache_enabled_t tcache_enabled;
tcache_t *tcache;
cassert(config_tcache);
tcache_enabled = (tcache_enabled_t)enabled;
tcache_enabled_tsd_set(&tcache_enabled);
tcache = *tcache_tsd_get();
if (enabled) {
if (tcache == TCACHE_STATE_DISABLED) {
tcache = NULL;
tcache_tsd_set(&tcache);
}
} else /* disabled */ {
if (tcache > TCACHE_STATE_MAX) {
tcache_destroy(tcache);
tcache = NULL;
}
if (tcache == NULL) {
tcache = TCACHE_STATE_DISABLED;
tcache_tsd_set(&tcache);
}
}
}
JEMALLOC_ALWAYS_INLINE tcache_t *
tcache_get(bool create)
{
tcache_t *tcache;
if (config_tcache == false)
return (NULL);
if (config_lazy_lock && isthreaded == false)
if ((isthreaded & opt_tcache) == false)
return (NULL);
tcache = *tcache_tsd_get();
if ((uintptr_t)tcache <= (uintptr_t)TCACHE_STATE_MAX) {
if (tcache == TCACHE_STATE_DISABLED)
return (NULL);
tcache = TCACHE_GET();
if ((uintptr_t)tcache <= (uintptr_t)2) {
if (tcache == NULL) {
if (create == false) {
tcache = tcache_create(choose_arena());
if (tcache == NULL)
return (NULL);
} else {
if (tcache == (void *)(uintptr_t)1) {
/*
* Creating a tcache here would cause
* allocation as a side effect of free().
* Ordinarily that would be okay since
* tcache_create() failure is a soft failure
* that doesn't propagate. However, if TLS
* data are freed via free() as in glibc,
* subtle corruption could result from setting
* a TLS variable after its backing memory is
* freed.
* Make a note that an allocator function was
* called after the tcache_thread_cleanup() was
* called.
*/
return (NULL);
TCACHE_SET((uintptr_t)2);
}
if (tcache_enabled_get() == false) {
tcache_enabled_set(false); /* Memoize. */
return (NULL);
}
return (tcache_create(choose_arena(NULL)));
}
if (tcache == TCACHE_STATE_PURGATORY) {
/*
* Make a note that an allocator function was called
* after tcache_thread_cleanup() was called.
*/
tcache = TCACHE_STATE_REINCARNATED;
tcache_tsd_set(&tcache);
return (NULL);
}
if (tcache == TCACHE_STATE_REINCARNATED)
return (NULL);
not_reached();
}
return (tcache);
}
JEMALLOC_ALWAYS_INLINE void
JEMALLOC_INLINE void
tcache_event(tcache_t *tcache)
{
if (TCACHE_GC_INCR == 0)
if (tcache_gc_incr == 0)
return;
tcache->ev_cnt++;
assert(tcache->ev_cnt <= TCACHE_GC_INCR);
if (tcache->ev_cnt == TCACHE_GC_INCR)
tcache_event_hard(tcache);
assert(tcache->ev_cnt <= tcache_gc_incr);
if (tcache->ev_cnt == tcache_gc_incr) {
size_t binind = tcache->next_gc_bin;
tcache_bin_t *tbin = &tcache->tbins[binind];
tcache_bin_info_t *tbin_info = &tcache_bin_info[binind];
if (tbin->low_water > 0) {
/*
* Flush (ceiling) 3/4 of the objects below the low
* water mark.
*/
if (binind < nbins) {
tcache_bin_flush_small(tbin, binind,
tbin->ncached - tbin->low_water +
(tbin->low_water >> 2)
#if (defined(JEMALLOC_STATS) || defined(JEMALLOC_PROF))
, tcache
#endif
);
} else {
tcache_bin_flush_large(tbin, binind,
tbin->ncached - tbin->low_water +
(tbin->low_water >> 2)
#if (defined(JEMALLOC_STATS) || defined(JEMALLOC_PROF))
, tcache
#endif
);
}
/*
* Reduce fill count by 2X. Limit lg_fill_div such that
* the fill count is always at least 1.
*/
if ((tbin_info->ncached_max >> (tbin->lg_fill_div+1))
>= 1)
tbin->lg_fill_div++;
} else if (tbin->low_water < 0) {
/*
* Increase fill count by 2X. Make sure lg_fill_div
* stays greater than 0.
*/
if (tbin->lg_fill_div > 1)
tbin->lg_fill_div--;
}
tbin->low_water = tbin->ncached;
tcache->next_gc_bin++;
if (tcache->next_gc_bin == nhbins)
tcache->next_gc_bin = 0;
tcache->ev_cnt = 0;
}
}
JEMALLOC_ALWAYS_INLINE void *
JEMALLOC_INLINE void *
tcache_alloc_easy(tcache_bin_t *tbin)
{
void *ret;
@@ -287,7 +249,7 @@ tcache_alloc_easy(tcache_bin_t *tbin)
return (ret);
}
JEMALLOC_ALWAYS_INLINE void *
JEMALLOC_INLINE void *
tcache_alloc_small(tcache_t *tcache, size_t size, bool zero)
{
void *ret;
@@ -295,44 +257,37 @@ tcache_alloc_small(tcache_t *tcache, size_t size, bool zero)
tcache_bin_t *tbin;
binind = SMALL_SIZE2BIN(size);
assert(binind < NBINS);
assert(binind < nbins);
tbin = &tcache->tbins[binind];
size = arena_bin_info[binind].reg_size;
ret = tcache_alloc_easy(tbin);
if (ret == NULL) {
ret = tcache_alloc_small_hard(tcache, tbin, binind);
if (ret == NULL)
return (NULL);
}
assert(tcache_salloc(ret) == arena_bin_info[binind].reg_size);
assert(arena_salloc(ret) == arena_bin_info[binind].reg_size);
if (zero == false) {
if (config_fill) {
if (opt_junk) {
arena_alloc_junk_small(ret,
&arena_bin_info[binind], false);
} else if (opt_zero)
memset(ret, 0, size);
}
VALGRIND_MAKE_MEM_UNDEFINED(ret, size);
} else {
if (config_fill && opt_junk) {
arena_alloc_junk_small(ret, &arena_bin_info[binind],
true);
}
VALGRIND_MAKE_MEM_UNDEFINED(ret, size);
#ifdef JEMALLOC_FILL
if (opt_junk)
memset(ret, 0xa5, size);
else if (opt_zero)
memset(ret, 0, size);
#endif
} else
memset(ret, 0, size);
}
if (config_stats)
tbin->tstats.nrequests++;
if (config_prof)
tcache->prof_accumbytes += arena_bin_info[binind].reg_size;
#ifdef JEMALLOC_STATS
tbin->tstats.nrequests++;
#endif
#ifdef JEMALLOC_PROF
tcache->prof_accumbytes += arena_bin_info[binind].reg_size;
#endif
tcache_event(tcache);
return (ret);
}
JEMALLOC_ALWAYS_INLINE void *
JEMALLOC_INLINE void *
tcache_alloc_large(tcache_t *tcache, size_t size, bool zero)
{
void *ret;
@@ -341,7 +296,7 @@ tcache_alloc_large(tcache_t *tcache, size_t size, bool zero)
size = PAGE_CEILING(size);
assert(size <= tcache_maxclass);
binind = NBINS + (size >> LG_PAGE) - 1;
binind = nbins + (size >> PAGE_SHIFT) - 1;
assert(binind < nhbins);
tbin = &tcache->tbins[binind];
ret = tcache_alloc_easy(tbin);
@@ -354,53 +309,74 @@ tcache_alloc_large(tcache_t *tcache, size_t size, bool zero)
if (ret == NULL)
return (NULL);
} else {
if (config_prof && prof_promote && size == PAGE) {
arena_chunk_t *chunk =
(arena_chunk_t *)CHUNK_ADDR2BASE(ret);
size_t pageind = (((uintptr_t)ret - (uintptr_t)chunk) >>
LG_PAGE);
arena_mapbits_large_binind_set(chunk, pageind,
BININD_INVALID);
}
#ifdef JEMALLOC_PROF
arena_chunk_t *chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ret);
size_t pageind = (((uintptr_t)ret - (uintptr_t)chunk) >>
PAGE_SHIFT);
chunk->map[pageind-map_bias].bits &= ~CHUNK_MAP_CLASS_MASK;
#endif
if (zero == false) {
if (config_fill) {
if (opt_junk)
memset(ret, 0xa5, size);
else if (opt_zero)
memset(ret, 0, size);
}
VALGRIND_MAKE_MEM_UNDEFINED(ret, size);
} else {
VALGRIND_MAKE_MEM_UNDEFINED(ret, size);
#ifdef JEMALLOC_FILL
if (opt_junk)
memset(ret, 0xa5, size);
else if (opt_zero)
memset(ret, 0, size);
#endif
} else
memset(ret, 0, size);
}
if (config_stats)
tbin->tstats.nrequests++;
if (config_prof)
tcache->prof_accumbytes += size;
#ifdef JEMALLOC_STATS
tbin->tstats.nrequests++;
#endif
#ifdef JEMALLOC_PROF
tcache->prof_accumbytes += size;
#endif
}
tcache_event(tcache);
return (ret);
}
JEMALLOC_ALWAYS_INLINE void
tcache_dalloc_small(tcache_t *tcache, void *ptr, size_t binind)
JEMALLOC_INLINE void
tcache_dalloc_small(tcache_t *tcache, void *ptr)
{
arena_t *arena;
arena_chunk_t *chunk;
arena_run_t *run;
arena_bin_t *bin;
tcache_bin_t *tbin;
tcache_bin_info_t *tbin_info;
size_t pageind, binind;
arena_chunk_map_t *mapelm;
assert(tcache_salloc(ptr) <= SMALL_MAXCLASS);
assert(arena_salloc(ptr) <= small_maxclass);
if (config_fill && opt_junk)
arena_dalloc_junk_small(ptr, &arena_bin_info[binind]);
chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
arena = chunk->arena;
pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> PAGE_SHIFT;
mapelm = &chunk->map[pageind-map_bias];
run = (arena_run_t *)((uintptr_t)chunk + (uintptr_t)((pageind -
(mapelm->bits >> PAGE_SHIFT)) << PAGE_SHIFT));
dassert(run->magic == ARENA_RUN_MAGIC);
bin = run->bin;
binind = ((uintptr_t)bin - (uintptr_t)&arena->bins) /
sizeof(arena_bin_t);
assert(binind < nbins);
#ifdef JEMALLOC_FILL
if (opt_junk)
memset(ptr, 0x5a, arena_bin_info[binind].reg_size);
#endif
tbin = &tcache->tbins[binind];
tbin_info = &tcache_bin_info[binind];
if (tbin->ncached == tbin_info->ncached_max) {
tcache_bin_flush_small(tbin, binind, (tbin_info->ncached_max >>
1), tcache);
1)
#if (defined(JEMALLOC_STATS) || defined(JEMALLOC_PROF))
, tcache
#endif
);
}
assert(tbin->ncached < tbin_info->ncached_max);
tbin->avail[tbin->ncached] = ptr;
@@ -409,27 +385,38 @@ tcache_dalloc_small(tcache_t *tcache, void *ptr, size_t binind)
tcache_event(tcache);
}
JEMALLOC_ALWAYS_INLINE void
JEMALLOC_INLINE void
tcache_dalloc_large(tcache_t *tcache, void *ptr, size_t size)
{
size_t binind;
arena_t *arena;
arena_chunk_t *chunk;
size_t pageind, binind;
tcache_bin_t *tbin;
tcache_bin_info_t *tbin_info;
assert((size & PAGE_MASK) == 0);
assert(tcache_salloc(ptr) > SMALL_MAXCLASS);
assert(tcache_salloc(ptr) <= tcache_maxclass);
assert(arena_salloc(ptr) > small_maxclass);
assert(arena_salloc(ptr) <= tcache_maxclass);
binind = NBINS + (size >> LG_PAGE) - 1;
chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
arena = chunk->arena;
pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> PAGE_SHIFT;
binind = nbins + (size >> PAGE_SHIFT) - 1;
if (config_fill && opt_junk)
#ifdef JEMALLOC_FILL
if (opt_junk)
memset(ptr, 0x5a, size);
#endif
tbin = &tcache->tbins[binind];
tbin_info = &tcache_bin_info[binind];
if (tbin->ncached == tbin_info->ncached_max) {
tcache_bin_flush_large(tbin, binind, (tbin_info->ncached_max >>
1), tcache);
1)
#if (defined(JEMALLOC_STATS) || defined(JEMALLOC_PROF))
, tcache
#endif
);
}
assert(tbin->ncached < tbin_info->ncached_max);
tbin->avail[tbin->ncached] = ptr;
@@ -441,3 +428,4 @@ tcache_dalloc_large(tcache_t *tcache, void *ptr, size_t size)
#endif /* JEMALLOC_H_INLINES */
/******************************************************************************/
#endif /* JEMALLOC_TCACHE */
-434
View File
@@ -1,434 +0,0 @@
/******************************************************************************/
#ifdef JEMALLOC_H_TYPES
/* Maximum number of malloc_tsd users with cleanup functions. */
#define MALLOC_TSD_CLEANUPS_MAX 8
typedef bool (*malloc_tsd_cleanup_t)(void);
#if (!defined(JEMALLOC_MALLOC_THREAD_CLEANUP) && !defined(JEMALLOC_TLS) && \
!defined(_WIN32))
typedef struct tsd_init_block_s tsd_init_block_t;
typedef struct tsd_init_head_s tsd_init_head_t;
#endif
/*
* TLS/TSD-agnostic macro-based implementation of thread-specific data. There
* are four macros that support (at least) three use cases: file-private,
* library-private, and library-private inlined. Following is an example
* library-private tsd variable:
*
* In example.h:
* typedef struct {
* int x;
* int y;
* } example_t;
* #define EX_INITIALIZER JEMALLOC_CONCAT({0, 0})
* malloc_tsd_protos(, example, example_t *)
* malloc_tsd_externs(example, example_t *)
* In example.c:
* malloc_tsd_data(, example, example_t *, EX_INITIALIZER)
* malloc_tsd_funcs(, example, example_t *, EX_INITIALIZER,
* example_tsd_cleanup)
*
* The result is a set of generated functions, e.g.:
*
* bool example_tsd_boot(void) {...}
* example_t **example_tsd_get() {...}
* void example_tsd_set(example_t **val) {...}
*
* Note that all of the functions deal in terms of (a_type *) rather than
* (a_type) so that it is possible to support non-pointer types (unlike
* pthreads TSD). example_tsd_cleanup() is passed an (a_type *) pointer that is
* cast to (void *). This means that the cleanup function needs to cast *and*
* dereference the function argument, e.g.:
*
* void
* example_tsd_cleanup(void *arg)
* {
* example_t *example = *(example_t **)arg;
*
* [...]
* if ([want the cleanup function to be called again]) {
* example_tsd_set(&example);
* }
* }
*
* If example_tsd_set() is called within example_tsd_cleanup(), it will be
* called again. This is similar to how pthreads TSD destruction works, except
* that pthreads only calls the cleanup function again if the value was set to
* non-NULL.
*/
/* malloc_tsd_protos(). */
#define malloc_tsd_protos(a_attr, a_name, a_type) \
a_attr bool \
a_name##_tsd_boot(void); \
a_attr a_type * \
a_name##_tsd_get(void); \
a_attr void \
a_name##_tsd_set(a_type *val);
/* malloc_tsd_externs(). */
#ifdef JEMALLOC_MALLOC_THREAD_CLEANUP
#define malloc_tsd_externs(a_name, a_type) \
extern __thread a_type a_name##_tls; \
extern __thread bool a_name##_initialized; \
extern bool a_name##_booted;
#elif (defined(JEMALLOC_TLS))
#define malloc_tsd_externs(a_name, a_type) \
extern __thread a_type a_name##_tls; \
extern pthread_key_t a_name##_tsd; \
extern bool a_name##_booted;
#elif (defined(_WIN32))
#define malloc_tsd_externs(a_name, a_type) \
extern DWORD a_name##_tsd; \
extern bool a_name##_booted;
#else
#define malloc_tsd_externs(a_name, a_type) \
extern pthread_key_t a_name##_tsd; \
extern tsd_init_head_t a_name##_tsd_init_head; \
extern bool a_name##_booted;
#endif
/* malloc_tsd_data(). */
#ifdef JEMALLOC_MALLOC_THREAD_CLEANUP
#define malloc_tsd_data(a_attr, a_name, a_type, a_initializer) \
a_attr __thread a_type JEMALLOC_TLS_MODEL \
a_name##_tls = a_initializer; \
a_attr __thread bool JEMALLOC_TLS_MODEL \
a_name##_initialized = false; \
a_attr bool a_name##_booted = false;
#elif (defined(JEMALLOC_TLS))
#define malloc_tsd_data(a_attr, a_name, a_type, a_initializer) \
a_attr __thread a_type JEMALLOC_TLS_MODEL \
a_name##_tls = a_initializer; \
a_attr pthread_key_t a_name##_tsd; \
a_attr bool a_name##_booted = false;
#elif (defined(_WIN32))
#define malloc_tsd_data(a_attr, a_name, a_type, a_initializer) \
a_attr DWORD a_name##_tsd; \
a_attr bool a_name##_booted = false;
#else
#define malloc_tsd_data(a_attr, a_name, a_type, a_initializer) \
a_attr pthread_key_t a_name##_tsd; \
a_attr tsd_init_head_t a_name##_tsd_init_head = { \
ql_head_initializer(blocks), \
MALLOC_MUTEX_INITIALIZER \
}; \
a_attr bool a_name##_booted = false;
#endif
/* malloc_tsd_funcs(). */
#ifdef JEMALLOC_MALLOC_THREAD_CLEANUP
#define malloc_tsd_funcs(a_attr, a_name, a_type, a_initializer, \
a_cleanup) \
/* Initialization/cleanup. */ \
a_attr bool \
a_name##_tsd_cleanup_wrapper(void) \
{ \
\
if (a_name##_initialized) { \
a_name##_initialized = false; \
a_cleanup(&a_name##_tls); \
} \
return (a_name##_initialized); \
} \
a_attr bool \
a_name##_tsd_boot(void) \
{ \
\
if (a_cleanup != malloc_tsd_no_cleanup) { \
malloc_tsd_cleanup_register( \
&a_name##_tsd_cleanup_wrapper); \
} \
a_name##_booted = true; \
return (false); \
} \
/* Get/set. */ \
a_attr a_type * \
a_name##_tsd_get(void) \
{ \
\
assert(a_name##_booted); \
return (&a_name##_tls); \
} \
a_attr void \
a_name##_tsd_set(a_type *val) \
{ \
\
assert(a_name##_booted); \
a_name##_tls = (*val); \
if (a_cleanup != malloc_tsd_no_cleanup) \
a_name##_initialized = true; \
}
#elif (defined(JEMALLOC_TLS))
#define malloc_tsd_funcs(a_attr, a_name, a_type, a_initializer, \
a_cleanup) \
/* Initialization/cleanup. */ \
a_attr bool \
a_name##_tsd_boot(void) \
{ \
\
if (a_cleanup != malloc_tsd_no_cleanup) { \
if (pthread_key_create(&a_name##_tsd, a_cleanup) != 0) \
return (true); \
} \
a_name##_booted = true; \
return (false); \
} \
/* Get/set. */ \
a_attr a_type * \
a_name##_tsd_get(void) \
{ \
\
assert(a_name##_booted); \
return (&a_name##_tls); \
} \
a_attr void \
a_name##_tsd_set(a_type *val) \
{ \
\
assert(a_name##_booted); \
a_name##_tls = (*val); \
if (a_cleanup != malloc_tsd_no_cleanup) { \
if (pthread_setspecific(a_name##_tsd, \
(void *)(&a_name##_tls))) { \
malloc_write("<jemalloc>: Error" \
" setting TSD for "#a_name"\n"); \
if (opt_abort) \
abort(); \
} \
} \
}
#elif (defined(_WIN32))
#define malloc_tsd_funcs(a_attr, a_name, a_type, a_initializer, \
a_cleanup) \
/* Data structure. */ \
typedef struct { \
bool initialized; \
a_type val; \
} a_name##_tsd_wrapper_t; \
/* Initialization/cleanup. */ \
a_attr bool \
a_name##_tsd_cleanup_wrapper(void) \
{ \
a_name##_tsd_wrapper_t *wrapper; \
\
wrapper = (a_name##_tsd_wrapper_t *) TlsGetValue(a_name##_tsd); \
if (wrapper == NULL) \
return (false); \
if (a_cleanup != malloc_tsd_no_cleanup && \
wrapper->initialized) { \
a_type val = wrapper->val; \
a_type tsd_static_data = a_initializer; \
wrapper->initialized = false; \
wrapper->val = tsd_static_data; \
a_cleanup(&val); \
if (wrapper->initialized) { \
/* Trigger another cleanup round. */ \
return (true); \
} \
} \
malloc_tsd_dalloc(wrapper); \
return (false); \
} \
a_attr bool \
a_name##_tsd_boot(void) \
{ \
\
a_name##_tsd = TlsAlloc(); \
if (a_name##_tsd == TLS_OUT_OF_INDEXES) \
return (true); \
if (a_cleanup != malloc_tsd_no_cleanup) { \
malloc_tsd_cleanup_register( \
&a_name##_tsd_cleanup_wrapper); \
} \
a_name##_booted = true; \
return (false); \
} \
/* Get/set. */ \
a_attr a_name##_tsd_wrapper_t * \
a_name##_tsd_get_wrapper(void) \
{ \
a_name##_tsd_wrapper_t *wrapper = (a_name##_tsd_wrapper_t *) \
TlsGetValue(a_name##_tsd); \
\
if (wrapper == NULL) { \
wrapper = (a_name##_tsd_wrapper_t *) \
malloc_tsd_malloc(sizeof(a_name##_tsd_wrapper_t)); \
if (wrapper == NULL) { \
malloc_write("<jemalloc>: Error allocating" \
" TSD for "#a_name"\n"); \
abort(); \
} else { \
static a_type tsd_static_data = a_initializer; \
wrapper->initialized = false; \
wrapper->val = tsd_static_data; \
} \
if (!TlsSetValue(a_name##_tsd, (void *)wrapper)) { \
malloc_write("<jemalloc>: Error setting" \
" TSD for "#a_name"\n"); \
abort(); \
} \
} \
return (wrapper); \
} \
a_attr a_type * \
a_name##_tsd_get(void) \
{ \
a_name##_tsd_wrapper_t *wrapper; \
\
assert(a_name##_booted); \
wrapper = a_name##_tsd_get_wrapper(); \
return (&wrapper->val); \
} \
a_attr void \
a_name##_tsd_set(a_type *val) \
{ \
a_name##_tsd_wrapper_t *wrapper; \
\
assert(a_name##_booted); \
wrapper = a_name##_tsd_get_wrapper(); \
wrapper->val = *(val); \
if (a_cleanup != malloc_tsd_no_cleanup) \
wrapper->initialized = true; \
}
#else
#define malloc_tsd_funcs(a_attr, a_name, a_type, a_initializer, \
a_cleanup) \
/* Data structure. */ \
typedef struct { \
bool initialized; \
a_type val; \
} a_name##_tsd_wrapper_t; \
/* Initialization/cleanup. */ \
a_attr void \
a_name##_tsd_cleanup_wrapper(void *arg) \
{ \
a_name##_tsd_wrapper_t *wrapper = (a_name##_tsd_wrapper_t *)arg;\
\
if (a_cleanup != malloc_tsd_no_cleanup && \
wrapper->initialized) { \
wrapper->initialized = false; \
a_cleanup(&wrapper->val); \
if (wrapper->initialized) { \
/* Trigger another cleanup round. */ \
if (pthread_setspecific(a_name##_tsd, \
(void *)wrapper)) { \
malloc_write("<jemalloc>: Error" \
" setting TSD for "#a_name"\n"); \
if (opt_abort) \
abort(); \
} \
return; \
} \
} \
malloc_tsd_dalloc(wrapper); \
} \
a_attr bool \
a_name##_tsd_boot(void) \
{ \
\
if (pthread_key_create(&a_name##_tsd, \
a_name##_tsd_cleanup_wrapper) != 0) \
return (true); \
a_name##_booted = true; \
return (false); \
} \
/* Get/set. */ \
a_attr a_name##_tsd_wrapper_t * \
a_name##_tsd_get_wrapper(void) \
{ \
a_name##_tsd_wrapper_t *wrapper = (a_name##_tsd_wrapper_t *) \
pthread_getspecific(a_name##_tsd); \
\
if (wrapper == NULL) { \
tsd_init_block_t block; \
wrapper = tsd_init_check_recursion( \
&a_name##_tsd_init_head, &block); \
if (wrapper) \
return (wrapper); \
wrapper = (a_name##_tsd_wrapper_t *) \
malloc_tsd_malloc(sizeof(a_name##_tsd_wrapper_t)); \
block.data = wrapper; \
if (wrapper == NULL) { \
malloc_write("<jemalloc>: Error allocating" \
" TSD for "#a_name"\n"); \
abort(); \
} else { \
static a_type tsd_static_data = a_initializer; \
wrapper->initialized = false; \
wrapper->val = tsd_static_data; \
} \
if (pthread_setspecific(a_name##_tsd, \
(void *)wrapper)) { \
malloc_write("<jemalloc>: Error setting" \
" TSD for "#a_name"\n"); \
abort(); \
} \
tsd_init_finish(&a_name##_tsd_init_head, &block); \
} \
return (wrapper); \
} \
a_attr a_type * \
a_name##_tsd_get(void) \
{ \
a_name##_tsd_wrapper_t *wrapper; \
\
assert(a_name##_booted); \
wrapper = a_name##_tsd_get_wrapper(); \
return (&wrapper->val); \
} \
a_attr void \
a_name##_tsd_set(a_type *val) \
{ \
a_name##_tsd_wrapper_t *wrapper; \
\
assert(a_name##_booted); \
wrapper = a_name##_tsd_get_wrapper(); \
wrapper->val = *(val); \
if (a_cleanup != malloc_tsd_no_cleanup) \
wrapper->initialized = true; \
}
#endif
#endif /* JEMALLOC_H_TYPES */
/******************************************************************************/
#ifdef JEMALLOC_H_STRUCTS
#if (!defined(JEMALLOC_MALLOC_THREAD_CLEANUP) && !defined(JEMALLOC_TLS) && \
!defined(_WIN32))
struct tsd_init_block_s {
ql_elm(tsd_init_block_t) link;
pthread_t thread;
void *data;
};
struct tsd_init_head_s {
ql_head(tsd_init_block_t) blocks;
malloc_mutex_t lock;
};
#endif
#endif /* JEMALLOC_H_STRUCTS */
/******************************************************************************/
#ifdef JEMALLOC_H_EXTERNS
void *malloc_tsd_malloc(size_t size);
void malloc_tsd_dalloc(void *wrapper);
void malloc_tsd_no_cleanup(void *);
void malloc_tsd_cleanup_register(bool (*f)(void));
void malloc_tsd_boot(void);
#if (!defined(JEMALLOC_MALLOC_THREAD_CLEANUP) && !defined(JEMALLOC_TLS) && \
!defined(_WIN32))
void *tsd_init_check_recursion(tsd_init_head_t *head,
tsd_init_block_t *block);
void tsd_init_finish(tsd_init_head_t *head, tsd_init_block_t *block);
#endif
#endif /* JEMALLOC_H_EXTERNS */
/******************************************************************************/
#ifdef JEMALLOC_H_INLINES
#endif /* JEMALLOC_H_INLINES */
/******************************************************************************/
-162
View File
@@ -1,162 +0,0 @@
/******************************************************************************/
#ifdef JEMALLOC_H_TYPES
/* Size of stack-allocated buffer passed to buferror(). */
#define BUFERROR_BUF 64
/*
* Size of stack-allocated buffer used by malloc_{,v,vc}printf(). This must be
* large enough for all possible uses within jemalloc.
*/
#define MALLOC_PRINTF_BUFSIZE 4096
/*
* Wrap a cpp argument that contains commas such that it isn't broken up into
* multiple arguments.
*/
#define JEMALLOC_ARG_CONCAT(...) __VA_ARGS__
/*
* Silence compiler warnings due to uninitialized values. This is used
* wherever the compiler fails to recognize that the variable is never used
* uninitialized.
*/
#ifdef JEMALLOC_CC_SILENCE
# define JEMALLOC_CC_SILENCE_INIT(v) = v
#else
# define JEMALLOC_CC_SILENCE_INIT(v)
#endif
/*
* Define a custom assert() in order to reduce the chances of deadlock during
* assertion failure.
*/
#ifndef assert
#define assert(e) do { \
if (config_debug && !(e)) { \
malloc_printf( \
"<jemalloc>: %s:%d: Failed assertion: \"%s\"\n", \
__FILE__, __LINE__, #e); \
abort(); \
} \
} while (0)
#endif
#ifndef not_reached
#define not_reached() do { \
if (config_debug) { \
malloc_printf( \
"<jemalloc>: %s:%d: Unreachable code reached\n", \
__FILE__, __LINE__); \
abort(); \
} \
} while (0)
#endif
#ifndef not_implemented
#define not_implemented() do { \
if (config_debug) { \
malloc_printf("<jemalloc>: %s:%d: Not implemented\n", \
__FILE__, __LINE__); \
abort(); \
} \
} while (0)
#endif
#ifndef assert_not_implemented
#define assert_not_implemented(e) do { \
if (config_debug && !(e)) \
not_implemented(); \
} while (0)
#endif
/* Use to assert a particular configuration, e.g., cassert(config_debug). */
#define cassert(c) do { \
if ((c) == false) \
not_reached(); \
} while (0)
#endif /* JEMALLOC_H_TYPES */
/******************************************************************************/
#ifdef JEMALLOC_H_STRUCTS
#endif /* JEMALLOC_H_STRUCTS */
/******************************************************************************/
#ifdef JEMALLOC_H_EXTERNS
int buferror(int err, char *buf, size_t buflen);
uintmax_t malloc_strtoumax(const char *restrict nptr,
char **restrict endptr, int base);
void malloc_write(const char *s);
/*
* malloc_vsnprintf() supports a subset of snprintf(3) that avoids floating
* point math.
*/
int malloc_vsnprintf(char *str, size_t size, const char *format,
va_list ap);
int malloc_snprintf(char *str, size_t size, const char *format, ...)
JEMALLOC_ATTR(format(printf, 3, 4));
void malloc_vcprintf(void (*write_cb)(void *, const char *), void *cbopaque,
const char *format, va_list ap);
void malloc_cprintf(void (*write)(void *, const char *), void *cbopaque,
const char *format, ...) JEMALLOC_ATTR(format(printf, 3, 4));
void malloc_printf(const char *format, ...)
JEMALLOC_ATTR(format(printf, 1, 2));
#endif /* JEMALLOC_H_EXTERNS */
/******************************************************************************/
#ifdef JEMALLOC_H_INLINES
#ifndef JEMALLOC_ENABLE_INLINE
size_t pow2_ceil(size_t x);
void set_errno(int errnum);
int get_errno(void);
#endif
#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_UTIL_C_))
/* Compute the smallest power of 2 that is >= x. */
JEMALLOC_INLINE size_t
pow2_ceil(size_t x)
{
x--;
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
#if (LG_SIZEOF_PTR == 3)
x |= x >> 32;
#endif
x++;
return (x);
}
/* Sets error code */
JEMALLOC_INLINE void
set_errno(int errnum)
{
#ifdef _WIN32
SetLastError(errnum);
#else
errno = errnum;
#endif
}
/* Get last error code */
JEMALLOC_INLINE int
get_errno(void)
{
#ifdef _WIN32
return (GetLastError());
#else
return (errno);
#endif
}
#endif
#endif /* JEMALLOC_H_INLINES */
/******************************************************************************/
+23
View File
@@ -0,0 +1,23 @@
#ifndef JEMALLOC_ZONE
# error "This source file is for zones on Darwin (OS X)."
#endif
/******************************************************************************/
#ifdef JEMALLOC_H_TYPES
#endif /* JEMALLOC_H_TYPES */
/******************************************************************************/
#ifdef JEMALLOC_H_STRUCTS
#endif /* JEMALLOC_H_STRUCTS */
/******************************************************************************/
#ifdef JEMALLOC_H_EXTERNS
malloc_zone_t *create_zone(void);
void szone2ozone(malloc_zone_t *zone);
#endif /* JEMALLOC_H_EXTERNS */
/******************************************************************************/
#ifdef JEMALLOC_H_INLINES
#endif /* JEMALLOC_H_INLINES */
/******************************************************************************/
+66
View File
@@ -0,0 +1,66 @@
#ifndef JEMALLOC_H_
#define JEMALLOC_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <limits.h>
#include <strings.h>
#define JEMALLOC_VERSION "@jemalloc_version@"
#define JEMALLOC_VERSION_MAJOR @jemalloc_version_major@
#define JEMALLOC_VERSION_MINOR @jemalloc_version_minor@
#define JEMALLOC_VERSION_BUGFIX @jemalloc_version_bugfix@
#define JEMALLOC_VERSION_NREV @jemalloc_version_nrev@
#define JEMALLOC_VERSION_GID "@jemalloc_version_gid@"
#include "jemalloc_defs@install_suffix@.h"
#ifndef JEMALLOC_P
# define JEMALLOC_P(s) s
#endif
#define ALLOCM_LG_ALIGN(la) (la)
#if LG_SIZEOF_PTR == 2
#define ALLOCM_ALIGN(a) (ffs(a)-1)
#else
#define ALLOCM_ALIGN(a) ((a < (size_t)INT_MAX) ? ffs(a)-1 : ffs(a>>32)+31)
#endif
#define ALLOCM_ZERO ((int)0x40)
#define ALLOCM_NO_MOVE ((int)0x80)
#define ALLOCM_SUCCESS 0
#define ALLOCM_ERR_OOM 1
#define ALLOCM_ERR_NOT_MOVED 2
extern const char *JEMALLOC_P(malloc_conf);
extern void (*JEMALLOC_P(malloc_message))(void *, const char *);
void *JEMALLOC_P(malloc)(size_t size) JEMALLOC_ATTR(malloc);
void *JEMALLOC_P(calloc)(size_t num, size_t size) JEMALLOC_ATTR(malloc);
int JEMALLOC_P(posix_memalign)(void **memptr, size_t alignment, size_t size)
JEMALLOC_ATTR(nonnull(1));
void *JEMALLOC_P(realloc)(void *ptr, size_t size);
void JEMALLOC_P(free)(void *ptr);
size_t JEMALLOC_P(malloc_usable_size)(const void *ptr);
void JEMALLOC_P(malloc_stats_print)(void (*write_cb)(void *, const char *),
void *cbopaque, const char *opts);
int JEMALLOC_P(mallctl)(const char *name, void *oldp, size_t *oldlenp,
void *newp, size_t newlen);
int JEMALLOC_P(mallctlnametomib)(const char *name, size_t *mibp,
size_t *miblenp);
int JEMALLOC_P(mallctlbymib)(const size_t *mib, size_t miblen, void *oldp,
size_t *oldlenp, void *newp, size_t newlen);
int JEMALLOC_P(allocm)(void **ptr, size_t *rsize, size_t size, int flags)
JEMALLOC_ATTR(nonnull(1));
int JEMALLOC_P(rallocm)(void **ptr, size_t *rsize, size_t size,
size_t extra, int flags) JEMALLOC_ATTR(nonnull(1));
int JEMALLOC_P(sallocm)(const void *ptr, size_t *rsize, int flags)
JEMALLOC_ATTR(nonnull(1));
int JEMALLOC_P(dallocm)(void *ptr, int flags) JEMALLOC_ATTR(nonnull(1));
#ifdef __cplusplus
};
#endif
#endif /* JEMALLOC_H_ */
-28
View File
@@ -1,28 +0,0 @@
#!/bin/sh
objroot=$1
cat <<EOF
#ifndef JEMALLOC_H_
#define JEMALLOC_H_
#ifdef __cplusplus
extern "C" {
#endif
EOF
for hdr in jemalloc_defs.h jemalloc_rename.h jemalloc_macros.h \
jemalloc_protos.h jemalloc_mangle.h ; do
cat "${objroot}include/jemalloc/${hdr}" \
| grep -v 'Generated from .* by configure\.' \
| sed -e 's/^#define /#define /g' \
| sed -e 's/ $//g'
echo
done
cat <<EOF
#ifdef __cplusplus
};
#endif
#endif /* JEMALLOC_H_ */
EOF
+156 -13
View File
@@ -1,24 +1,167 @@
/* Defined if __attribute__((...)) syntax is supported. */
#undef JEMALLOC_HAVE_ATTR
/* Support the experimental API. */
#undef JEMALLOC_EXPERIMENTAL
#ifndef JEMALLOC_DEFS_H_
#define JEMALLOC_DEFS_H_
/*
* Define overrides for non-standard allocator-related functions if they are
* present on the system.
* If JEMALLOC_PREFIX is defined, it will cause all public APIs to be prefixed.
* This makes it possible, with some care, to use multiple allocators
* simultaneously.
*
* In many cases it is more convenient to manually prefix allocator function
* calls than to let macros do it automatically, particularly when using
* multiple allocators simultaneously. Define JEMALLOC_MANGLE before
* #include'ing jemalloc.h in order to cause name mangling that corresponds to
* the API prefixing.
*/
#undef JEMALLOC_PREFIX
#undef JEMALLOC_CPREFIX
#if (defined(JEMALLOC_PREFIX) && defined(JEMALLOC_MANGLE))
#undef JEMALLOC_P
#endif
/*
* JEMALLOC_PRIVATE_NAMESPACE is used as a prefix for all library-private APIs.
* For shared libraries, symbol visibility mechanisms prevent these symbols
* from being exported, but for static libraries, naming collisions are a real
* possibility.
*/
#undef JEMALLOC_PRIVATE_NAMESPACE
#undef JEMALLOC_N
/*
* Hyper-threaded CPUs may need a special instruction inside spin loops in
* order to yield to another virtual CPU.
*/
#undef CPU_SPINWAIT
/*
* Defined if OSAtomic*() functions are available, as provided by Darwin, and
* documented in the atomic(3) manual page.
*/
#undef JEMALLOC_OSATOMIC
/*
* Defined if OSSpin*() functions are available, as provided by Darwin, and
* documented in the spinlock(3) manual page.
*/
#undef JEMALLOC_OSSPIN
/* Defined if __attribute__((...)) syntax is supported. */
#undef JEMALLOC_HAVE_ATTR
#ifdef JEMALLOC_HAVE_ATTR
# define JEMALLOC_ATTR(s) __attribute__((s))
#else
# define JEMALLOC_ATTR(s)
#endif
/* JEMALLOC_CC_SILENCE enables code that silences unuseful compiler warnings. */
#undef JEMALLOC_CC_SILENCE
/*
* JEMALLOC_DEBUG enables assertions and other sanity checks, and disables
* inline functions.
*/
#undef JEMALLOC_DEBUG
/* JEMALLOC_STATS enables statistics calculation. */
#undef JEMALLOC_STATS
/* JEMALLOC_PROF enables allocation profiling. */
#undef JEMALLOC_PROF
/* Use libunwind for profile backtracing if defined. */
#undef JEMALLOC_PROF_LIBUNWIND
/* Use libgcc for profile backtracing if defined. */
#undef JEMALLOC_PROF_LIBGCC
/* Use gcc intrinsics for profile backtracing if defined. */
#undef JEMALLOC_PROF_GCC
/*
* JEMALLOC_TINY enables support for tiny objects, which are smaller than one
* quantum.
*/
#undef JEMALLOC_TINY
/*
* JEMALLOC_TCACHE enables a thread-specific caching layer for small objects.
* This makes it possible to allocate/deallocate objects without any locking
* when the cache is in the steady state.
*/
#undef JEMALLOC_TCACHE
/*
* JEMALLOC_DSS enables use of sbrk(2) to allocate chunks from the data storage
* segment (DSS).
*/
#undef JEMALLOC_DSS
/* JEMALLOC_SWAP enables mmap()ed swap file support. */
#undef JEMALLOC_SWAP
/* Support memory filling (junk/zero). */
#undef JEMALLOC_FILL
/* Support optional abort() on OOM. */
#undef JEMALLOC_XMALLOC
/* Support SYSV semantics. */
#undef JEMALLOC_SYSV
/* Support lazy locking (avoid locking unless a second thread is launched). */
#undef JEMALLOC_LAZY_LOCK
/* Determine page size at run time if defined. */
#undef DYNAMIC_PAGE_SHIFT
/* One page is 2^STATIC_PAGE_SHIFT bytes. */
#undef STATIC_PAGE_SHIFT
/* TLS is used to map arenas and magazine caches to threads. */
#undef NO_TLS
/*
* JEMALLOC_IVSALLOC enables ivsalloc(), which verifies that pointers reside
* within jemalloc-owned chunks before dereferencing them.
*/
#undef JEMALLOC_IVSALLOC
/*
* Define overrides for non-standard allocator-related functions if they
* are present on the system.
*/
#undef JEMALLOC_OVERRIDE_MEMALIGN
#undef JEMALLOC_OVERRIDE_VALLOC
/*
* At least Linux omits the "const" in:
*
* size_t malloc_usable_size(const void *ptr);
*
* Match the operating system's prototype.
* Darwin (OS X) uses zones to work around Mach-O symbol override shortcomings.
*/
#undef JEMALLOC_USABLE_SIZE_CONST
#undef JEMALLOC_ZONE
#undef JEMALLOC_ZONE_VERSION
/* If defined, use mremap(...MREMAP_FIXED...) for huge realloc(). */
#undef JEMALLOC_MREMAP_FIXED
/*
* Methods for purging unused pages differ between operating systems.
*
* madvise(..., MADV_DONTNEED) : On Linux, this immediately discards pages,
* such that new pages will be demand-zeroed if
* the address region is later touched.
* madvise(..., MADV_FREE) : On FreeBSD and Darwin, this marks pages as being
* unused, such that they will be discarded rather
* than swapped out.
*/
#undef JEMALLOC_PURGE_MADVISE_DONTNEED
#undef JEMALLOC_PURGE_MADVISE_FREE
/* sizeof(void *) == 2^LG_SIZEOF_PTR. */
#undef LG_SIZEOF_PTR
/* sizeof(int) == 2^LG_SIZEOF_INT. */
#undef LG_SIZEOF_INT
/* sizeof(long) == 2^LG_SIZEOF_LONG. */
#undef LG_SIZEOF_LONG
#endif /* JEMALLOC_DEFS_H_ */
-61
View File
@@ -1,61 +0,0 @@
#include <limits.h>
#include <strings.h>
#define JEMALLOC_VERSION "@jemalloc_version@"
#define JEMALLOC_VERSION_MAJOR @jemalloc_version_major@
#define JEMALLOC_VERSION_MINOR @jemalloc_version_minor@
#define JEMALLOC_VERSION_BUGFIX @jemalloc_version_bugfix@
#define JEMALLOC_VERSION_NREV @jemalloc_version_nrev@
#define JEMALLOC_VERSION_GID "@jemalloc_version_gid@"
# define MALLOCX_LG_ALIGN(la) (la)
# if LG_SIZEOF_PTR == 2
# define MALLOCX_ALIGN(a) (ffs(a)-1)
# else
# define MALLOCX_ALIGN(a) \
((a < (size_t)INT_MAX) ? ffs(a)-1 : ffs(a>>32)+31)
# endif
# define MALLOCX_ZERO ((int)0x40)
/* Bias arena index bits so that 0 encodes "MALLOCX_ARENA() unspecified". */
# define MALLOCX_ARENA(a) ((int)(((a)+1) << 8))
#ifdef JEMALLOC_EXPERIMENTAL
# define ALLOCM_LG_ALIGN(la) (la)
# if LG_SIZEOF_PTR == 2
# define ALLOCM_ALIGN(a) (ffs(a)-1)
# else
# define ALLOCM_ALIGN(a) \
((a < (size_t)INT_MAX) ? ffs(a)-1 : ffs(a>>32)+31)
# endif
# define ALLOCM_ZERO ((int)0x40)
# define ALLOCM_NO_MOVE ((int)0x80)
/* Bias arena index bits so that 0 encodes "ALLOCM_ARENA() unspecified". */
# define ALLOCM_ARENA(a) ((int)(((a)+1) << 8))
# define ALLOCM_SUCCESS 0
# define ALLOCM_ERR_OOM 1
# define ALLOCM_ERR_NOT_MOVED 2
#endif
#ifdef JEMALLOC_HAVE_ATTR
# define JEMALLOC_ATTR(s) __attribute__((s))
# define JEMALLOC_EXPORT JEMALLOC_ATTR(visibility("default"))
# define JEMALLOC_ALIGNED(s) JEMALLOC_ATTR(aligned(s))
# define JEMALLOC_SECTION(s) JEMALLOC_ATTR(section(s))
# define JEMALLOC_NOINLINE JEMALLOC_ATTR(noinline)
#elif _MSC_VER
# define JEMALLOC_ATTR(s)
# ifdef DLLEXPORT
# define JEMALLOC_EXPORT __declspec(dllexport)
# else
# define JEMALLOC_EXPORT __declspec(dllimport)
# endif
# define JEMALLOC_ALIGNED(s) __declspec(align(s))
# define JEMALLOC_SECTION(s) __declspec(allocate(s))
# define JEMALLOC_NOINLINE __declspec(noinline)
#else
# define JEMALLOC_ATTR(s)
# define JEMALLOC_EXPORT
# define JEMALLOC_ALIGNED(s)
# define JEMALLOC_SECTION(s)
# define JEMALLOC_NOINLINE
#endif
-45
View File
@@ -1,45 +0,0 @@
#!/bin/sh
public_symbols_txt=$1
symbol_prefix=$2
cat <<EOF
/*
* By default application code must explicitly refer to mangled symbol names,
* so that it is possible to use jemalloc in conjunction with another allocator
* in the same application. Define JEMALLOC_MANGLE in order to cause automatic
* name mangling that matches the API prefixing that happened as a result of
* --with-mangling and/or --with-jemalloc-prefix configuration settings.
*/
#ifdef JEMALLOC_MANGLE
# ifndef JEMALLOC_NO_DEMANGLE
# define JEMALLOC_NO_DEMANGLE
# endif
EOF
for nm in `cat ${public_symbols_txt}` ; do
n=`echo ${nm} |tr ':' ' ' |awk '{print $1}'`
echo "# define ${n} ${symbol_prefix}${n}"
done
cat <<EOF
#endif
/*
* The ${symbol_prefix}* macros can be used as stable alternative names for the
* public jemalloc API if JEMALLOC_NO_DEMANGLE is defined. This is primarily
* meant for use in jemalloc itself, but it can be used by application code to
* provide isolation from the name mangling specified via --with-mangling
* and/or --with-jemalloc-prefix.
*/
#ifndef JEMALLOC_NO_DEMANGLE
EOF
for nm in `cat ${public_symbols_txt}` ; do
n=`echo ${nm} |tr ':' ' ' |awk '{print $1}'`
echo "# undef ${symbol_prefix}${n}"
done
cat <<EOF
#endif
EOF
-58
View File
@@ -1,58 +0,0 @@
/*
* The @je_@ prefix on the following public symbol declarations is an artifact
* of namespace management, and should be omitted in application code unless
* JEMALLOC_NO_DEMANGLE is defined (see jemalloc_mangle@install_suffix@.h).
*/
extern JEMALLOC_EXPORT const char *@je_@malloc_conf;
extern JEMALLOC_EXPORT void (*@je_@malloc_message)(void *cbopaque,
const char *s);
JEMALLOC_EXPORT void *@je_@malloc(size_t size) JEMALLOC_ATTR(malloc);
JEMALLOC_EXPORT void *@je_@calloc(size_t num, size_t size)
JEMALLOC_ATTR(malloc);
JEMALLOC_EXPORT int @je_@posix_memalign(void **memptr, size_t alignment,
size_t size) JEMALLOC_ATTR(nonnull(1));
JEMALLOC_EXPORT void *@je_@aligned_alloc(size_t alignment, size_t size)
JEMALLOC_ATTR(malloc);
JEMALLOC_EXPORT void *@je_@realloc(void *ptr, size_t size);
JEMALLOC_EXPORT void @je_@free(void *ptr);
JEMALLOC_EXPORT void *@je_@mallocx(size_t size, int flags);
JEMALLOC_EXPORT void *@je_@rallocx(void *ptr, size_t size, int flags);
JEMALLOC_EXPORT size_t @je_@xallocx(void *ptr, size_t size, size_t extra,
int flags);
JEMALLOC_EXPORT size_t @je_@sallocx(const void *ptr, int flags);
JEMALLOC_EXPORT void @je_@dallocx(void *ptr, int flags);
JEMALLOC_EXPORT size_t @je_@nallocx(size_t size, int flags);
JEMALLOC_EXPORT int @je_@mallctl(const char *name, void *oldp,
size_t *oldlenp, void *newp, size_t newlen);
JEMALLOC_EXPORT int @je_@mallctlnametomib(const char *name, size_t *mibp,
size_t *miblenp);
JEMALLOC_EXPORT int @je_@mallctlbymib(const size_t *mib, size_t miblen,
void *oldp, size_t *oldlenp, void *newp, size_t newlen);
JEMALLOC_EXPORT void @je_@malloc_stats_print(void (*write_cb)(void *,
const char *), void *@je_@cbopaque, const char *opts);
JEMALLOC_EXPORT size_t @je_@malloc_usable_size(
JEMALLOC_USABLE_SIZE_CONST void *ptr);
#ifdef JEMALLOC_OVERRIDE_MEMALIGN
JEMALLOC_EXPORT void * @je_@memalign(size_t alignment, size_t size)
JEMALLOC_ATTR(malloc);
#endif
#ifdef JEMALLOC_OVERRIDE_VALLOC
JEMALLOC_EXPORT void * @je_@valloc(size_t size) JEMALLOC_ATTR(malloc);
#endif
#ifdef JEMALLOC_EXPERIMENTAL
JEMALLOC_EXPORT int @je_@allocm(void **ptr, size_t *rsize, size_t size,
int flags) JEMALLOC_ATTR(nonnull(1));
JEMALLOC_EXPORT int @je_@rallocm(void **ptr, size_t *rsize, size_t size,
size_t extra, int flags) JEMALLOC_ATTR(nonnull(1));
JEMALLOC_EXPORT int @je_@sallocm(const void *ptr, size_t *rsize, int flags)
JEMALLOC_ATTR(nonnull(1));
JEMALLOC_EXPORT int @je_@dallocm(void *ptr, int flags)
JEMALLOC_ATTR(nonnull(1));
JEMALLOC_EXPORT int @je_@nallocm(size_t *rsize, size_t size, int flags);
#endif
-22
View File
@@ -1,22 +0,0 @@
#!/bin/sh
public_symbols_txt=$1
cat <<EOF
/*
* Name mangling for public symbols is controlled by --with-mangling and
* --with-jemalloc-prefix. With default settings the je_ prefix is stripped by
* these macro definitions.
*/
#ifndef JEMALLOC_NO_RENAME
EOF
for nm in `cat ${public_symbols_txt}` ; do
n=`echo ${nm} |tr ':' ' ' |awk '{print $1}'`
m=`echo ${nm} |tr ':' ' ' |awk '{print $2}'`
echo "# define je_${n} ${m}"
done
cat <<EOF
#endif
EOF
-313
View File
@@ -1,313 +0,0 @@
// ISO C9x compliant inttypes.h for Microsoft Visual Studio
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
//
// Copyright (c) 2006 Alexander Chemeris
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. The name of the author may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _MSC_VER // [
#error "Use this header only with Microsoft Visual C++ compilers!"
#endif // _MSC_VER ]
#ifndef _MSC_INTTYPES_H_ // [
#define _MSC_INTTYPES_H_
#if _MSC_VER > 1000
#pragma once
#endif
#include "stdint.h"
// 7.8 Format conversion of integer types
typedef struct {
intmax_t quot;
intmax_t rem;
} imaxdiv_t;
// 7.8.1 Macros for format specifiers
#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198
#ifdef _WIN64
# define __PRI64_PREFIX "l"
# define __PRIPTR_PREFIX "l"
#else
# define __PRI64_PREFIX "ll"
# define __PRIPTR_PREFIX
#endif
// The fprintf macros for signed integers are:
#define PRId8 "d"
#define PRIi8 "i"
#define PRIdLEAST8 "d"
#define PRIiLEAST8 "i"
#define PRIdFAST8 "d"
#define PRIiFAST8 "i"
#define PRId16 "hd"
#define PRIi16 "hi"
#define PRIdLEAST16 "hd"
#define PRIiLEAST16 "hi"
#define PRIdFAST16 "hd"
#define PRIiFAST16 "hi"
#define PRId32 "d"
#define PRIi32 "i"
#define PRIdLEAST32 "d"
#define PRIiLEAST32 "i"
#define PRIdFAST32 "d"
#define PRIiFAST32 "i"
#define PRId64 __PRI64_PREFIX "d"
#define PRIi64 __PRI64_PREFIX "i"
#define PRIdLEAST64 __PRI64_PREFIX "d"
#define PRIiLEAST64 __PRI64_PREFIX "i"
#define PRIdFAST64 __PRI64_PREFIX "d"
#define PRIiFAST64 __PRI64_PREFIX "i"
#define PRIdMAX __PRI64_PREFIX "d"
#define PRIiMAX __PRI64_PREFIX "i"
#define PRIdPTR __PRIPTR_PREFIX "d"
#define PRIiPTR __PRIPTR_PREFIX "i"
// The fprintf macros for unsigned integers are:
#define PRIo8 "o"
#define PRIu8 "u"
#define PRIx8 "x"
#define PRIX8 "X"
#define PRIoLEAST8 "o"
#define PRIuLEAST8 "u"
#define PRIxLEAST8 "x"
#define PRIXLEAST8 "X"
#define PRIoFAST8 "o"
#define PRIuFAST8 "u"
#define PRIxFAST8 "x"
#define PRIXFAST8 "X"
#define PRIo16 "ho"
#define PRIu16 "hu"
#define PRIx16 "hx"
#define PRIX16 "hX"
#define PRIoLEAST16 "ho"
#define PRIuLEAST16 "hu"
#define PRIxLEAST16 "hx"
#define PRIXLEAST16 "hX"
#define PRIoFAST16 "ho"
#define PRIuFAST16 "hu"
#define PRIxFAST16 "hx"
#define PRIXFAST16 "hX"
#define PRIo32 "o"
#define PRIu32 "u"
#define PRIx32 "x"
#define PRIX32 "X"
#define PRIoLEAST32 "o"
#define PRIuLEAST32 "u"
#define PRIxLEAST32 "x"
#define PRIXLEAST32 "X"
#define PRIoFAST32 "o"
#define PRIuFAST32 "u"
#define PRIxFAST32 "x"
#define PRIXFAST32 "X"
#define PRIo64 __PRI64_PREFIX "o"
#define PRIu64 __PRI64_PREFIX "u"
#define PRIx64 __PRI64_PREFIX "x"
#define PRIX64 __PRI64_PREFIX "X"
#define PRIoLEAST64 __PRI64_PREFIX "o"
#define PRIuLEAST64 __PRI64_PREFIX "u"
#define PRIxLEAST64 __PRI64_PREFIX "x"
#define PRIXLEAST64 __PRI64_PREFIX "X"
#define PRIoFAST64 __PRI64_PREFIX "o"
#define PRIuFAST64 __PRI64_PREFIX "u"
#define PRIxFAST64 __PRI64_PREFIX "x"
#define PRIXFAST64 __PRI64_PREFIX "X"
#define PRIoMAX __PRI64_PREFIX "o"
#define PRIuMAX __PRI64_PREFIX "u"
#define PRIxMAX __PRI64_PREFIX "x"
#define PRIXMAX __PRI64_PREFIX "X"
#define PRIoPTR __PRIPTR_PREFIX "o"
#define PRIuPTR __PRIPTR_PREFIX "u"
#define PRIxPTR __PRIPTR_PREFIX "x"
#define PRIXPTR __PRIPTR_PREFIX "X"
// The fscanf macros for signed integers are:
#define SCNd8 "d"
#define SCNi8 "i"
#define SCNdLEAST8 "d"
#define SCNiLEAST8 "i"
#define SCNdFAST8 "d"
#define SCNiFAST8 "i"
#define SCNd16 "hd"
#define SCNi16 "hi"
#define SCNdLEAST16 "hd"
#define SCNiLEAST16 "hi"
#define SCNdFAST16 "hd"
#define SCNiFAST16 "hi"
#define SCNd32 "ld"
#define SCNi32 "li"
#define SCNdLEAST32 "ld"
#define SCNiLEAST32 "li"
#define SCNdFAST32 "ld"
#define SCNiFAST32 "li"
#define SCNd64 "I64d"
#define SCNi64 "I64i"
#define SCNdLEAST64 "I64d"
#define SCNiLEAST64 "I64i"
#define SCNdFAST64 "I64d"
#define SCNiFAST64 "I64i"
#define SCNdMAX "I64d"
#define SCNiMAX "I64i"
#ifdef _WIN64 // [
# define SCNdPTR "I64d"
# define SCNiPTR "I64i"
#else // _WIN64 ][
# define SCNdPTR "ld"
# define SCNiPTR "li"
#endif // _WIN64 ]
// The fscanf macros for unsigned integers are:
#define SCNo8 "o"
#define SCNu8 "u"
#define SCNx8 "x"
#define SCNX8 "X"
#define SCNoLEAST8 "o"
#define SCNuLEAST8 "u"
#define SCNxLEAST8 "x"
#define SCNXLEAST8 "X"
#define SCNoFAST8 "o"
#define SCNuFAST8 "u"
#define SCNxFAST8 "x"
#define SCNXFAST8 "X"
#define SCNo16 "ho"
#define SCNu16 "hu"
#define SCNx16 "hx"
#define SCNX16 "hX"
#define SCNoLEAST16 "ho"
#define SCNuLEAST16 "hu"
#define SCNxLEAST16 "hx"
#define SCNXLEAST16 "hX"
#define SCNoFAST16 "ho"
#define SCNuFAST16 "hu"
#define SCNxFAST16 "hx"
#define SCNXFAST16 "hX"
#define SCNo32 "lo"
#define SCNu32 "lu"
#define SCNx32 "lx"
#define SCNX32 "lX"
#define SCNoLEAST32 "lo"
#define SCNuLEAST32 "lu"
#define SCNxLEAST32 "lx"
#define SCNXLEAST32 "lX"
#define SCNoFAST32 "lo"
#define SCNuFAST32 "lu"
#define SCNxFAST32 "lx"
#define SCNXFAST32 "lX"
#define SCNo64 "I64o"
#define SCNu64 "I64u"
#define SCNx64 "I64x"
#define SCNX64 "I64X"
#define SCNoLEAST64 "I64o"
#define SCNuLEAST64 "I64u"
#define SCNxLEAST64 "I64x"
#define SCNXLEAST64 "I64X"
#define SCNoFAST64 "I64o"
#define SCNuFAST64 "I64u"
#define SCNxFAST64 "I64x"
#define SCNXFAST64 "I64X"
#define SCNoMAX "I64o"
#define SCNuMAX "I64u"
#define SCNxMAX "I64x"
#define SCNXMAX "I64X"
#ifdef _WIN64 // [
# define SCNoPTR "I64o"
# define SCNuPTR "I64u"
# define SCNxPTR "I64x"
# define SCNXPTR "I64X"
#else // _WIN64 ][
# define SCNoPTR "lo"
# define SCNuPTR "lu"
# define SCNxPTR "lx"
# define SCNXPTR "lX"
#endif // _WIN64 ]
#endif // __STDC_FORMAT_MACROS ]
// 7.8.2 Functions for greatest-width integer types
// 7.8.2.1 The imaxabs function
#define imaxabs _abs64
// 7.8.2.2 The imaxdiv function
// This is modified version of div() function from Microsoft's div.c found
// in %MSVC.NET%\crt\src\div.c
#ifdef STATIC_IMAXDIV // [
static
#else // STATIC_IMAXDIV ][
_inline
#endif // STATIC_IMAXDIV ]
imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)
{
imaxdiv_t result;
result.quot = numer / denom;
result.rem = numer % denom;
if (numer < 0 && result.rem > 0) {
// did division wrong; must fix up
++result.quot;
result.rem -= denom;
}
return result;
}
// 7.8.2.3 The strtoimax and strtoumax functions
#define strtoimax _strtoi64
#define strtoumax _strtoui64
// 7.8.2.4 The wcstoimax and wcstoumax functions
#define wcstoimax _wcstoi64
#define wcstoumax _wcstoui64
#endif // _MSC_INTTYPES_H_ ]
-16
View File
@@ -1,16 +0,0 @@
#ifndef stdbool_h
#define stdbool_h
#include <wtypes.h>
/* MSVC doesn't define _Bool or bool in C, but does have BOOL */
/* Note this doesn't pass autoconf's test because (bool) 0.5 != true */
typedef BOOL _Bool;
#define bool _Bool
#define true 1
#define false 0
#define __bool_true_false_are_defined 1
#endif /* stdbool_h */
-247
View File
@@ -1,247 +0,0 @@
// ISO C9x compliant stdint.h for Microsoft Visual Studio
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
//
// Copyright (c) 2006-2008 Alexander Chemeris
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. The name of the author may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _MSC_VER // [
#error "Use this header only with Microsoft Visual C++ compilers!"
#endif // _MSC_VER ]
#ifndef _MSC_STDINT_H_ // [
#define _MSC_STDINT_H_
#if _MSC_VER > 1000
#pragma once
#endif
#include <limits.h>
// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
// or compiler give many errors like this:
// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
#ifdef __cplusplus
extern "C" {
#endif
# include <wchar.h>
#ifdef __cplusplus
}
#endif
// Define _W64 macros to mark types changing their size, like intptr_t.
#ifndef _W64
# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
# define _W64 __w64
# else
# define _W64
# endif
#endif
// 7.18.1 Integer types
// 7.18.1.1 Exact-width integer types
// Visual Studio 6 and Embedded Visual C++ 4 doesn't
// realize that, e.g. char has the same size as __int8
// so we give up on __intX for them.
#if (_MSC_VER < 1300)
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
#else
typedef signed __int8 int8_t;
typedef signed __int16 int16_t;
typedef signed __int32 int32_t;
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
#endif
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
// 7.18.1.2 Minimum-width integer types
typedef int8_t int_least8_t;
typedef int16_t int_least16_t;
typedef int32_t int_least32_t;
typedef int64_t int_least64_t;
typedef uint8_t uint_least8_t;
typedef uint16_t uint_least16_t;
typedef uint32_t uint_least32_t;
typedef uint64_t uint_least64_t;
// 7.18.1.3 Fastest minimum-width integer types
typedef int8_t int_fast8_t;
typedef int16_t int_fast16_t;
typedef int32_t int_fast32_t;
typedef int64_t int_fast64_t;
typedef uint8_t uint_fast8_t;
typedef uint16_t uint_fast16_t;
typedef uint32_t uint_fast32_t;
typedef uint64_t uint_fast64_t;
// 7.18.1.4 Integer types capable of holding object pointers
#ifdef _WIN64 // [
typedef signed __int64 intptr_t;
typedef unsigned __int64 uintptr_t;
#else // _WIN64 ][
typedef _W64 signed int intptr_t;
typedef _W64 unsigned int uintptr_t;
#endif // _WIN64 ]
// 7.18.1.5 Greatest-width integer types
typedef int64_t intmax_t;
typedef uint64_t uintmax_t;
// 7.18.2 Limits of specified-width integer types
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
// 7.18.2.1 Limits of exact-width integer types
#define INT8_MIN ((int8_t)_I8_MIN)
#define INT8_MAX _I8_MAX
#define INT16_MIN ((int16_t)_I16_MIN)
#define INT16_MAX _I16_MAX
#define INT32_MIN ((int32_t)_I32_MIN)
#define INT32_MAX _I32_MAX
#define INT64_MIN ((int64_t)_I64_MIN)
#define INT64_MAX _I64_MAX
#define UINT8_MAX _UI8_MAX
#define UINT16_MAX _UI16_MAX
#define UINT32_MAX _UI32_MAX
#define UINT64_MAX _UI64_MAX
// 7.18.2.2 Limits of minimum-width integer types
#define INT_LEAST8_MIN INT8_MIN
#define INT_LEAST8_MAX INT8_MAX
#define INT_LEAST16_MIN INT16_MIN
#define INT_LEAST16_MAX INT16_MAX
#define INT_LEAST32_MIN INT32_MIN
#define INT_LEAST32_MAX INT32_MAX
#define INT_LEAST64_MIN INT64_MIN
#define INT_LEAST64_MAX INT64_MAX
#define UINT_LEAST8_MAX UINT8_MAX
#define UINT_LEAST16_MAX UINT16_MAX
#define UINT_LEAST32_MAX UINT32_MAX
#define UINT_LEAST64_MAX UINT64_MAX
// 7.18.2.3 Limits of fastest minimum-width integer types
#define INT_FAST8_MIN INT8_MIN
#define INT_FAST8_MAX INT8_MAX
#define INT_FAST16_MIN INT16_MIN
#define INT_FAST16_MAX INT16_MAX
#define INT_FAST32_MIN INT32_MIN
#define INT_FAST32_MAX INT32_MAX
#define INT_FAST64_MIN INT64_MIN
#define INT_FAST64_MAX INT64_MAX
#define UINT_FAST8_MAX UINT8_MAX
#define UINT_FAST16_MAX UINT16_MAX
#define UINT_FAST32_MAX UINT32_MAX
#define UINT_FAST64_MAX UINT64_MAX
// 7.18.2.4 Limits of integer types capable of holding object pointers
#ifdef _WIN64 // [
# define INTPTR_MIN INT64_MIN
# define INTPTR_MAX INT64_MAX
# define UINTPTR_MAX UINT64_MAX
#else // _WIN64 ][
# define INTPTR_MIN INT32_MIN
# define INTPTR_MAX INT32_MAX
# define UINTPTR_MAX UINT32_MAX
#endif // _WIN64 ]
// 7.18.2.5 Limits of greatest-width integer types
#define INTMAX_MIN INT64_MIN
#define INTMAX_MAX INT64_MAX
#define UINTMAX_MAX UINT64_MAX
// 7.18.3 Limits of other integer types
#ifdef _WIN64 // [
# define PTRDIFF_MIN _I64_MIN
# define PTRDIFF_MAX _I64_MAX
#else // _WIN64 ][
# define PTRDIFF_MIN _I32_MIN
# define PTRDIFF_MAX _I32_MAX
#endif // _WIN64 ]
#define SIG_ATOMIC_MIN INT_MIN
#define SIG_ATOMIC_MAX INT_MAX
#ifndef SIZE_MAX // [
# ifdef _WIN64 // [
# define SIZE_MAX _UI64_MAX
# else // _WIN64 ][
# define SIZE_MAX _UI32_MAX
# endif // _WIN64 ]
#endif // SIZE_MAX ]
// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
#ifndef WCHAR_MIN // [
# define WCHAR_MIN 0
#endif // WCHAR_MIN ]
#ifndef WCHAR_MAX // [
# define WCHAR_MAX _UI16_MAX
#endif // WCHAR_MAX ]
#define WINT_MIN 0
#define WINT_MAX _UI16_MAX
#endif // __STDC_LIMIT_MACROS ]
// 7.18.4 Limits of other integer types
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
// 7.18.4.1 Macros for minimum-width integer constants
#define INT8_C(val) val##i8
#define INT16_C(val) val##i16
#define INT32_C(val) val##i32
#define INT64_C(val) val##i64
#define UINT8_C(val) val##ui8
#define UINT16_C(val) val##ui16
#define UINT32_C(val) val##ui32
#define UINT64_C(val) val##ui64
// 7.18.4.2 Macros for greatest-width integer constants
#define INTMAX_C INT64_C
#define UINTMAX_C UINT64_C
#endif // __STDC_CONSTANT_MACROS ]
#endif // _MSC_STDINT_H_ ]
-23
View File
@@ -1,23 +0,0 @@
#ifndef strings_h
#define strings_h
/* MSVC doesn't define ffs/ffsl. This dummy strings.h header is provided
* for both */
#include <intrin.h>
#pragma intrinsic(_BitScanForward)
static __forceinline int ffsl(long x)
{
unsigned long i;
if (_BitScanForward(&i, x))
return (i + 1);
return (0);
}
static __forceinline int ffs(int x)
{
return (ffsl(x));
}
#endif

Some files were not shown because too many files have changed in this diff Show More