mirror of
https://github.com/jemalloc/jemalloc.git
synced 2026-07-23 21:23:06 +00:00
Compare commits
34 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ad11ee6a34 | ||
|
|
0e4d0d13f9 | ||
|
|
a8118233ec | ||
|
|
a7153a0d7d | ||
|
|
814b9bda7f | ||
|
|
e27d134efc | ||
|
|
6e56e5ec6a | ||
|
|
af5d6987f8 | ||
|
|
655f04a5a4 | ||
|
|
9dcad2dfd1 | ||
|
|
6369286f83 | ||
|
|
a73ebd946a | ||
|
|
ada55b2e92 | ||
|
|
31bfb3e7b0 | ||
|
|
f256680f87 | ||
|
|
dbd3832d20 | ||
|
|
10e4523094 | ||
|
|
624f2f3cc9 | ||
|
|
8ad0eacfb3 | ||
|
|
2a6f2af6e4 | ||
|
|
2b769797ce | ||
|
|
50ac670d09 | ||
|
|
1c4b088b08 | ||
|
|
0e8d3d2cb9 | ||
|
|
ecf229a39f | ||
|
|
cfdc8cfbd6 | ||
|
|
aee7fd2b70 | ||
|
|
fc4dcfa2f5 | ||
|
|
1f17bd9395 | ||
|
|
0a36622dd1 | ||
|
|
53806fef53 | ||
|
|
b04a940ee5 | ||
|
|
d4bab21756 | ||
|
|
b059a534f7 |
7
.gitignore
vendored
7
.gitignore
vendored
@@ -3,6 +3,10 @@
|
|||||||
/jemalloc/config.log
|
/jemalloc/config.log
|
||||||
/jemalloc/config.status
|
/jemalloc/config.status
|
||||||
/jemalloc/configure
|
/jemalloc/configure
|
||||||
|
/jemalloc/doc/html.xsl
|
||||||
|
/jemalloc/doc/manpages.xsl
|
||||||
|
/jemalloc/doc/jemalloc.xml
|
||||||
|
/jemalloc/doc/jemalloc.html
|
||||||
/jemalloc/doc/jemalloc.3
|
/jemalloc/doc/jemalloc.3
|
||||||
/jemalloc/lib/
|
/jemalloc/lib/
|
||||||
/jemalloc/Makefile
|
/jemalloc/Makefile
|
||||||
@@ -13,4 +17,7 @@
|
|||||||
/jemalloc/src/*.[od]
|
/jemalloc/src/*.[od]
|
||||||
/jemalloc/test/*.[od]
|
/jemalloc/test/*.[od]
|
||||||
/jemalloc/test/*.out
|
/jemalloc/test/*.out
|
||||||
|
/jemalloc/test/[a-z]*
|
||||||
|
!/jemalloc/test/*.c
|
||||||
|
!/jemalloc/test/*.exp
|
||||||
/jemalloc/VERSION
|
/jemalloc/VERSION
|
||||||
|
|||||||
@@ -6,7 +6,55 @@ found in the git revision history:
|
|||||||
http://www.canonware.com/cgi-bin/gitweb.cgi?p=jemalloc.git
|
http://www.canonware.com/cgi-bin/gitweb.cgi?p=jemalloc.git
|
||||||
git://canonware.com/jemalloc.git
|
git://canonware.com/jemalloc.git
|
||||||
|
|
||||||
* 2.0.0
|
* 2.1.3 (March 14, 2011)
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
- Fix a cpp logic regression (due to the "thread.{de,}allocatedp" mallctl fix
|
||||||
|
for OS X in 2.1.2).
|
||||||
|
- Fix a "thread.arena" mallctl bug.
|
||||||
|
- Fix a thread cache stats merging bug.
|
||||||
|
|
||||||
|
* 2.1.2 (March 2, 2011)
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
- Fix "thread.{de,}allocatedp" mallctl for OS X.
|
||||||
|
- Add missing jemalloc.a to build system.
|
||||||
|
|
||||||
|
* 2.1.1 (January 31, 2011)
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
- Fix aligned huge reallocation (affected allocm()).
|
||||||
|
- Fix the ALLOCM_LG_ALIGN macro definition.
|
||||||
|
- Fix a heap dumping deadlock.
|
||||||
|
- Fix a "thread.arena" mallctl bug.
|
||||||
|
|
||||||
|
* 2.1.0 (December 3, 2010)
|
||||||
|
|
||||||
|
This version incorporates some optimizations that can't quite be considered
|
||||||
|
bug fixes.
|
||||||
|
|
||||||
|
New features:
|
||||||
|
- Use Linux's mremap(2) for huge object reallocation when possible.
|
||||||
|
- Avoid locking in mallctl*() when possible.
|
||||||
|
- Add the "thread.[de]allocatedp" mallctl's.
|
||||||
|
- Convert the manual page source from roff to DocBook, and generate both roff
|
||||||
|
and HTML manuals.
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
- Fix a crash due to incorrect bootstrap ordering. This only impacted
|
||||||
|
--enable-debug --enable-dss configurations.
|
||||||
|
- Fix a minor statistics bug for mallctl("swap.avail", ...).
|
||||||
|
|
||||||
|
* 2.0.1 (October 29, 2010)
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
- Fix a race condition in heap profiling that could cause undefined behavior
|
||||||
|
if "opt.prof_accum" were disabled.
|
||||||
|
- Add missing mutex unlocks for some OOM error paths in the heap profiling
|
||||||
|
code.
|
||||||
|
- Fix a compilation error for non-C99 builds.
|
||||||
|
|
||||||
|
* 2.0.0 (October 24, 2010)
|
||||||
|
|
||||||
This version focuses on the experimental *allocm() API, and on improved
|
This version focuses on the experimental *allocm() API, and on improved
|
||||||
run-time configuration/introspection. Nonetheless, numerous performance
|
run-time configuration/introspection. Nonetheless, numerous performance
|
||||||
@@ -15,24 +63,23 @@ found in the git revision history:
|
|||||||
New features:
|
New features:
|
||||||
- Implement the experimental {,r,s,d}allocm() API, which provides a superset
|
- Implement the experimental {,r,s,d}allocm() API, which provides a superset
|
||||||
of the functionality available via malloc(), calloc(), posix_memalign(),
|
of the functionality available via malloc(), calloc(), posix_memalign(),
|
||||||
realloc(), malloc_usable_size(), and free(). These functions can be used
|
realloc(), malloc_usable_size(), and free(). These functions can be used to
|
||||||
to allocate/reallocate aligned zeroed memory, ask for optional extra
|
allocate/reallocate aligned zeroed memory, ask for optional extra memory
|
||||||
memory during reallocation, prevent object movement during reallocation,
|
during reallocation, prevent object movement during reallocation, etc.
|
||||||
etc.
|
|
||||||
- Replace JEMALLOC_OPTIONS/JEMALLOC_PROF_PREFIX with MALLOC_CONF, which is
|
- Replace JEMALLOC_OPTIONS/JEMALLOC_PROF_PREFIX with MALLOC_CONF, which is
|
||||||
more human-readable, and more flexible. For example:
|
more human-readable, and more flexible. For example:
|
||||||
JEMALLOC_OPTIONS=AJP
|
JEMALLOC_OPTIONS=AJP
|
||||||
is now:
|
is now:
|
||||||
MALLOC_CONF=abort:true,fill:true,stats_print:true
|
MALLOC_CONF=abort:true,fill:true,stats_print:true
|
||||||
- Port to Apple OS X. Sponsored by Mozilla.
|
- Port to Apple OS X. Sponsored by Mozilla.
|
||||||
- Make it possible for the application to control thread-->arena mappings
|
- Make it possible for the application to control thread-->arena mappings via
|
||||||
via the "thread.arena" mallctl.
|
the "thread.arena" mallctl.
|
||||||
- Add compile-time support for all TLS-related functionality via pthreads
|
- Add compile-time support for all TLS-related functionality via pthreads TSD.
|
||||||
TSD. This is mainly of interest for OS X, which does not support TLS, but
|
This is mainly of interest for OS X, which does not support TLS, but has a
|
||||||
has a TSD implementation with similar performance.
|
TSD implementation with similar performance.
|
||||||
- Override memalign() and valloc() if they are provided by the system.
|
- Override memalign() and valloc() if they are provided by the system.
|
||||||
- Add the "arenas.purge" mallctl, which can be used to synchronously purge
|
- Add the "arenas.purge" mallctl, which can be used to synchronously purge all
|
||||||
all dirty unused pages.
|
dirty unused pages.
|
||||||
- Make cumulative heap profiling data optional, so that it is possible to
|
- Make cumulative heap profiling data optional, so that it is possible to
|
||||||
limit the amount of memory consumed by heap profiling data structures.
|
limit the amount of memory consumed by heap profiling data structures.
|
||||||
- Add per thread allocation counters that can be accessed via the
|
- Add per thread allocation counters that can be accessed via the
|
||||||
@@ -59,7 +106,7 @@ found in the git revision history:
|
|||||||
- Fix a heap profiling bug due to sometimes losing track of requested object
|
- Fix a heap profiling bug due to sometimes losing track of requested object
|
||||||
size for sampled objects.
|
size for sampled objects.
|
||||||
|
|
||||||
* 1.0.3
|
* 1.0.3 (August 12, 2010)
|
||||||
|
|
||||||
Bug fixes:
|
Bug fixes:
|
||||||
- Fix the libunwind-based implementation of stack backtracing (used for heap
|
- Fix the libunwind-based implementation of stack backtracing (used for heap
|
||||||
@@ -68,7 +115,7 @@ found in the git revision history:
|
|||||||
threads raced to initialize malloc, some of them could end up permanently
|
threads raced to initialize malloc, some of them could end up permanently
|
||||||
blocked.
|
blocked.
|
||||||
|
|
||||||
* 1.0.2
|
* 1.0.2 (May 11, 2010)
|
||||||
|
|
||||||
Bug fixes:
|
Bug fixes:
|
||||||
- Fix junk filling of large objects, which could cause memory corruption.
|
- Fix junk filling of large objects, which could cause memory corruption.
|
||||||
@@ -76,7 +123,7 @@ found in the git revision history:
|
|||||||
memory limits could cause swap file configuration to fail. Contributed by
|
memory limits could cause swap file configuration to fail. Contributed by
|
||||||
Jordan DeLong.
|
Jordan DeLong.
|
||||||
|
|
||||||
* 1.0.1
|
* 1.0.1 (April 14, 2010)
|
||||||
|
|
||||||
Bug fixes:
|
Bug fixes:
|
||||||
- Fix compilation when --enable-fill is specified.
|
- Fix compilation when --enable-fill is specified.
|
||||||
@@ -85,7 +132,7 @@ found in the git revision history:
|
|||||||
- Fix dirty page purging race conditions that could cause crashes.
|
- Fix dirty page purging race conditions that could cause crashes.
|
||||||
- Fix crash in tcache flushing code during thread destruction.
|
- Fix crash in tcache flushing code during thread destruction.
|
||||||
|
|
||||||
* 1.0.0
|
* 1.0.0 (April 11, 2010)
|
||||||
|
|
||||||
This release focuses on speed and run-time introspection. Numerous
|
This release focuses on speed and run-time introspection. Numerous
|
||||||
algorithmic improvements make this release substantially faster than its
|
algorithmic improvements make this release substantially faster than its
|
||||||
@@ -121,7 +168,7 @@ found in the git revision history:
|
|||||||
- Fix a chunk leak. The leaked chunks were never touched, so this impacted
|
- Fix a chunk leak. The leaked chunks were never touched, so this impacted
|
||||||
virtual memory usage, but not physical memory usage.
|
virtual memory usage, but not physical memory usage.
|
||||||
|
|
||||||
* linux_20080828a, linux_20080827a
|
* linux_2008082[78]a (August 27/28, 2008)
|
||||||
|
|
||||||
These snapshot releases are the simple result of incorporating Linux-specific
|
These snapshot releases are the simple result of incorporating Linux-specific
|
||||||
support into the FreeBSD malloc sources.
|
support into the FreeBSD malloc sources.
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ any of the following arguments (not a definitive list) to 'configure':
|
|||||||
|
|
||||||
--with-jemalloc-prefix=<prefix>
|
--with-jemalloc-prefix=<prefix>
|
||||||
Prefix all public APIs with <prefix>. For example, if <prefix> is
|
Prefix all public APIs with <prefix>. For example, if <prefix> is
|
||||||
"prefix_", the API changes like the following occur:
|
"prefix_", API changes like the following occur:
|
||||||
|
|
||||||
malloc() --> prefix_malloc()
|
malloc() --> prefix_malloc()
|
||||||
malloc_conf --> prefix_malloc_conf
|
malloc_conf --> prefix_malloc_conf
|
||||||
@@ -48,9 +48,9 @@ any of the following arguments (not a definitive list) to 'configure':
|
|||||||
example, libjemalloc.so.0 becomes libjemalloc<suffix>.so.0.
|
example, libjemalloc.so.0 becomes libjemalloc<suffix>.so.0.
|
||||||
|
|
||||||
--enable-cc-silence
|
--enable-cc-silence
|
||||||
Enable code that silences unuseful compiler warnings. This is helpful when
|
Enable code that silences non-useful compiler warnings. This is helpful
|
||||||
trying to tell serious warnings from those due to compiler limitations, but
|
when trying to tell serious warnings from those due to compiler
|
||||||
it potentially incurs a performance penalty.
|
limitations, but it potentially incurs a performance penalty.
|
||||||
|
|
||||||
--enable-debug
|
--enable-debug
|
||||||
Enable assertions and validation code. This incurs a substantial
|
Enable assertions and validation code. This incurs a substantial
|
||||||
@@ -62,7 +62,7 @@ any of the following arguments (not a definitive list) to 'configure':
|
|||||||
|
|
||||||
--enable-prof
|
--enable-prof
|
||||||
Enable heap profiling and leak detection functionality. See the "opt.prof"
|
Enable heap profiling and leak detection functionality. See the "opt.prof"
|
||||||
option documention for usage details.
|
option documentation for usage details.
|
||||||
|
|
||||||
--disable-prof-libgcc
|
--disable-prof-libgcc
|
||||||
Disable the use of libgcc's backtracing functionality. Ordinarily, libgcc's
|
Disable the use of libgcc's backtracing functionality. Ordinarily, libgcc's
|
||||||
@@ -89,7 +89,7 @@ any of the following arguments (not a definitive list) to 'configure':
|
|||||||
--disable-tcache
|
--disable-tcache
|
||||||
Disable thread-specific caches for small objects. Objects are cached and
|
Disable thread-specific caches for small objects. Objects are cached and
|
||||||
released in bulk, thus reducing the total number of mutex operations. See
|
released in bulk, thus reducing the total number of mutex operations. See
|
||||||
the "opt.tcache" option for suage details.
|
the "opt.tcache" option for usage details.
|
||||||
|
|
||||||
--enable-swap
|
--enable-swap
|
||||||
Enable mmap()ed swap file support. When this feature is built in, it is
|
Enable mmap()ed swap file support. When this feature is built in, it is
|
||||||
@@ -132,8 +132,11 @@ any of the following arguments (not a definitive list) to 'configure':
|
|||||||
--disable-tls
|
--disable-tls
|
||||||
Disable thread-local storage (TLS), which allows for fast access to
|
Disable thread-local storage (TLS), which allows for fast access to
|
||||||
thread-local variables via the __thread keyword. If TLS is available,
|
thread-local variables via the __thread keyword. If TLS is available,
|
||||||
jemalloc uses it for several purposes. Note that disabling TLS implies
|
jemalloc uses it for several purposes.
|
||||||
--disable-tcache.
|
|
||||||
|
--with-xslroot=<path>
|
||||||
|
Specify where to find DocBook XSL stylesheets when building the
|
||||||
|
documentation.
|
||||||
|
|
||||||
The following environment variables (not a definitive list) impact configure's
|
The following environment variables (not a definitive list) impact configure's
|
||||||
behavior:
|
behavior:
|
||||||
@@ -172,7 +175,7 @@ To install only parts of jemalloc, use the following targets:
|
|||||||
install_bin
|
install_bin
|
||||||
install_include
|
install_include
|
||||||
install_lib
|
install_lib
|
||||||
install_man
|
install_doc
|
||||||
|
|
||||||
To clean up build results to varying degrees, use the following make targets:
|
To clean up build results to varying degrees, use the following make targets:
|
||||||
|
|
||||||
@@ -195,8 +198,8 @@ MANDIR="?"
|
|||||||
Use this as the installation prefix for man pages.
|
Use this as the installation prefix for man pages.
|
||||||
|
|
||||||
DESTDIR="?"
|
DESTDIR="?"
|
||||||
Prepend DESTDIR to INCLUDEDIR, LIBDIR, and MANDIR. This is useful when
|
Prepend DESTDIR to INCLUDEDIR, LIBDIR, DATADIR, and MANDIR. This is useful
|
||||||
installing to a different path than was specified via --prefix.
|
when installing to a different path than was specified via --prefix.
|
||||||
|
|
||||||
CC="?"
|
CC="?"
|
||||||
Use this to invoke the C compiler.
|
Use this to invoke the C compiler.
|
||||||
@@ -232,11 +235,12 @@ directory, issue configuration and build commands:
|
|||||||
|
|
||||||
=== Documentation ==============================================================
|
=== Documentation ==============================================================
|
||||||
|
|
||||||
The manual page that the configure script generates can be manually formatted
|
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 any of the following commands:
|
prior to installation via any of the following commands:
|
||||||
|
|
||||||
nroff -man -man-ext -t doc/jemalloc.3
|
nroff -man -t doc/jemalloc.3
|
||||||
|
|
||||||
groff -man -man-ext -t -Tps doc/jemalloc.3 | ps2pdf - doc/jemalloc.3.pdf
|
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)
|
(cd doc; groff -man -man-ext -t -Thtml jemalloc.3 > jemalloc.3.html)
|
||||||
|
|||||||
@@ -15,11 +15,12 @@ DESTDIR =
|
|||||||
BINDIR := $(DESTDIR)@BINDIR@
|
BINDIR := $(DESTDIR)@BINDIR@
|
||||||
INCLUDEDIR := $(DESTDIR)@INCLUDEDIR@
|
INCLUDEDIR := $(DESTDIR)@INCLUDEDIR@
|
||||||
LIBDIR := $(DESTDIR)@LIBDIR@
|
LIBDIR := $(DESTDIR)@LIBDIR@
|
||||||
|
DATADIR := $(DESTDIR)@DATADIR@
|
||||||
MANDIR := $(DESTDIR)@MANDIR@
|
MANDIR := $(DESTDIR)@MANDIR@
|
||||||
|
|
||||||
# Build parameters.
|
# Build parameters.
|
||||||
CPPFLAGS := @CPPFLAGS@ -I@srcroot@include -I@objroot@include
|
CPPFLAGS := @CPPFLAGS@ -I@srcroot@include -I@objroot@include
|
||||||
CFLAGS := @CFLAGS@ -fPIC -DPIC
|
CFLAGS := @CFLAGS@
|
||||||
ifeq (macho, @abi@)
|
ifeq (macho, @abi@)
|
||||||
CFLAGS += -dynamic
|
CFLAGS += -dynamic
|
||||||
endif
|
endif
|
||||||
@@ -54,18 +55,40 @@ CSRCS := @srcroot@src/jemalloc.c @srcroot@src/arena.c @srcroot@src/base.c \
|
|||||||
ifeq (macho, @abi@)
|
ifeq (macho, @abi@)
|
||||||
CSRCS += @srcroot@src/zone.c
|
CSRCS += @srcroot@src/zone.c
|
||||||
endif
|
endif
|
||||||
|
STATIC_LIBS := @objroot@lib/libjemalloc@install_suffix@.a
|
||||||
DSOS := @objroot@lib/libjemalloc@install_suffix@.$(SO).$(REV) \
|
DSOS := @objroot@lib/libjemalloc@install_suffix@.$(SO).$(REV) \
|
||||||
@objroot@lib/libjemalloc@install_suffix@.$(SO) \
|
@objroot@lib/libjemalloc@install_suffix@.$(SO) \
|
||||||
@objroot@lib/libjemalloc@install_suffix@_pic.a
|
@objroot@lib/libjemalloc@install_suffix@_pic.a
|
||||||
MAN3 := @objroot@doc/jemalloc@install_suffix@.3
|
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)
|
||||||
CTESTS := @srcroot@test/allocated.c @srcroot@test/allocm.c \
|
CTESTS := @srcroot@test/allocated.c @srcroot@test/allocm.c \
|
||||||
@srcroot@test/posix_memalign.c \
|
@srcroot@test/mremap.c @srcroot@test/posix_memalign.c \
|
||||||
@srcroot@test/rallocm.c @srcroot@test/thread_arena.c
|
@srcroot@test/rallocm.c @srcroot@test/thread_arena.c
|
||||||
|
|
||||||
.PHONY: all dist install check clean distclean relclean
|
.PHONY: all dist doc_html doc_man doc
|
||||||
|
.PHONY: install_bin install_include install_lib
|
||||||
|
.PHONY: install_html install_man install_doc install
|
||||||
|
.PHONY: tests check clean distclean relclean
|
||||||
|
|
||||||
|
.SECONDARY : $(CTESTS:@srcroot@%.c=@objroot@%.o)
|
||||||
|
|
||||||
# Default target.
|
# Default target.
|
||||||
all: $(DSOS)
|
all: $(DSOS) $(STATIC_LIBS)
|
||||||
|
|
||||||
|
dist: doc
|
||||||
|
|
||||||
|
@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 $<
|
||||||
|
|
||||||
|
doc_html: $(DOCS_HTML)
|
||||||
|
doc_man: $(DOCS_MAN3)
|
||||||
|
doc: $(DOCS)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Include generated dependency files.
|
# Include generated dependency files.
|
||||||
@@ -77,15 +100,24 @@ all: $(DSOS)
|
|||||||
$(CC) $(CFLAGS) -c $(CPPFLAGS) -o $@ $<
|
$(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)"
|
@$(SHELL) -ec "$(CC) -MM $(CPPFLAGS) $< | sed \"s/\($(subst /,\/,$(notdir $(basename $@)))\)\.o\([ :]*\)/$(subst /,\/,$(strip $(dir $@)))\1.o \2/g\" > $(@:%.o=%.d)"
|
||||||
|
|
||||||
|
@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 $@)))\)\.o\([ :]*\)/$(subst /,\/,$(strip $(dir $@)))\1.o \2/g\" > $(@:%.o=%.d)"
|
||||||
|
|
||||||
%.$(SO) : %.$(SO).$(REV)
|
%.$(SO) : %.$(SO).$(REV)
|
||||||
@mkdir -p $(@D)
|
@mkdir -p $(@D)
|
||||||
ln -sf $(<F) $@
|
ln -sf $(<F) $@
|
||||||
|
|
||||||
@objroot@lib/libjemalloc@install_suffix@.$(SO).$(REV) : $(CSRCS:@srcroot@%.c=@objroot@%.o)
|
@objroot@lib/libjemalloc@install_suffix@.$(SO).$(REV) : $(CSRCS:@srcroot@%.c=@objroot@%.pic.o)
|
||||||
@mkdir -p $(@D)
|
@mkdir -p $(@D)
|
||||||
$(CC) -shared -Wl,-$(WL_SONAME),$(@F) $(RPATH_EXTRA:%=@RPATH@%) -o $@ $+ $(LDFLAGS) $(LIBS)
|
$(CC) -shared -Wl,-$(WL_SONAME),$(@F) $(RPATH_EXTRA:%=@RPATH@%) -o $@ $+ $(LDFLAGS) $(LIBS)
|
||||||
|
|
||||||
@objroot@lib/libjemalloc@install_suffix@_pic.a : $(CSRCS:@srcroot@%.c=@objroot@%.o)
|
@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)
|
@mkdir -p $(@D)
|
||||||
ar crus $@ $+
|
ar crus $@ $+
|
||||||
|
|
||||||
@@ -117,20 +149,30 @@ install_include:
|
|||||||
install -m 644 $$h $(INCLUDEDIR)/jemalloc; \
|
install -m 644 $$h $(INCLUDEDIR)/jemalloc; \
|
||||||
done
|
done
|
||||||
|
|
||||||
install_lib: $(DSOS)
|
install_lib: $(DSOS) $(STATIC_LIBS)
|
||||||
install -d $(LIBDIR)
|
install -d $(LIBDIR)
|
||||||
install -m 755 @objroot@lib/libjemalloc@install_suffix@.$(SO).$(REV) $(LIBDIR)
|
install -m 755 @objroot@lib/libjemalloc@install_suffix@.$(SO).$(REV) $(LIBDIR)
|
||||||
ln -sf libjemalloc@install_suffix@.$(SO).$(REV) $(LIBDIR)/libjemalloc@install_suffix@.$(SO)
|
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@_pic.a $(LIBDIR)
|
||||||
|
install -m 755 @objroot@lib/libjemalloc@install_suffix@.a $(LIBDIR)
|
||||||
|
|
||||||
|
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@; \
|
||||||
|
done
|
||||||
|
|
||||||
install_man:
|
install_man:
|
||||||
install -d $(MANDIR)/man3
|
install -d $(MANDIR)/man3
|
||||||
@for m in $(MAN3); do \
|
@for d in $(DOCS_MAN3); do \
|
||||||
echo "install -m 644 $$m $(MANDIR)/man3"; \
|
echo "install -m 644 $$d $(MANDIR)/man3"; \
|
||||||
install -m 644 $$m $(MANDIR)/man3; \
|
install -m 644 $$d $(MANDIR)/man3; \
|
||||||
done
|
done
|
||||||
|
|
||||||
install: install_bin install_include install_lib install_man
|
install_doc: install_html install_man
|
||||||
|
|
||||||
|
install: install_bin install_include install_lib install_doc
|
||||||
|
|
||||||
tests: $(CTESTS:@srcroot@%.c=@objroot@%)
|
tests: $(CTESTS:@srcroot@%.c=@objroot@%)
|
||||||
|
|
||||||
@@ -164,12 +206,14 @@ check: tests
|
|||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f $(CSRCS:@srcroot@%.c=@objroot@%.o)
|
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@%.d)
|
||||||
|
rm -f $(CSRCS:@srcroot@%.c=@objroot@%.pic.d)
|
||||||
rm -f $(CTESTS:@srcroot@%.c=@objroot@%)
|
rm -f $(CTESTS:@srcroot@%.c=@objroot@%)
|
||||||
rm -f $(CTESTS:@srcroot@%.c=@objroot@%.o)
|
rm -f $(CTESTS:@srcroot@%.c=@objroot@%.o)
|
||||||
rm -f $(CTESTS:@srcroot@%.c=@objroot@%.d)
|
rm -f $(CTESTS:@srcroot@%.c=@objroot@%.d)
|
||||||
rm -f $(CTESTS:@srcroot@%.c=@objroot@%.out)
|
rm -f $(CTESTS:@srcroot@%.c=@objroot@%.out)
|
||||||
rm -f $(DSOS)
|
rm -f $(DSOS) $(STATIC_LIBS)
|
||||||
|
|
||||||
distclean: clean
|
distclean: clean
|
||||||
rm -rf @objroot@autom4te.cache
|
rm -rf @objroot@autom4te.cache
|
||||||
@@ -182,6 +226,8 @@ distclean: clean
|
|||||||
relclean: distclean
|
relclean: distclean
|
||||||
rm -f @objroot@configure
|
rm -f @objroot@configure
|
||||||
rm -f @srcroot@VERSION
|
rm -f @srcroot@VERSION
|
||||||
|
rm -f $(DOCS_HTML)
|
||||||
|
rm -f $(DOCS_MAN3)
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# Re-configuration rules.
|
# Re-configuration rules.
|
||||||
|
|||||||
@@ -80,6 +80,19 @@ MANDIR=`eval echo $mandir`
|
|||||||
MANDIR=`eval echo $MANDIR`
|
MANDIR=`eval echo $MANDIR`
|
||||||
AC_SUBST([MANDIR])
|
AC_SUBST([MANDIR])
|
||||||
|
|
||||||
|
dnl Support for building documentation.
|
||||||
|
AC_PATH_PROG([XSLTPROC], [xsltproc], , [$PATH])
|
||||||
|
AC_ARG_WITH([xslroot],
|
||||||
|
[AS_HELP_STRING([--with-xslroot=<path>], [XSL stylesheet root path])],
|
||||||
|
if test "x$with_xslroot" = "xno" ; then
|
||||||
|
XSLROOT="/usr/share/xml/docbook/stylesheet/docbook-xsl"
|
||||||
|
else
|
||||||
|
XSLROOT="${with_xslroot}"
|
||||||
|
fi,
|
||||||
|
XSLROOT="/usr/share/xml/docbook/stylesheet/docbook-xsl"
|
||||||
|
)
|
||||||
|
AC_SUBST([XSLROOT])
|
||||||
|
|
||||||
dnl If CFLAGS isn't defined, set CFLAGS to something reasonable. Otherwise,
|
dnl If CFLAGS isn't defined, set CFLAGS to something reasonable. Otherwise,
|
||||||
dnl just prevent autoconf from molesting CFLAGS.
|
dnl just prevent autoconf from molesting CFLAGS.
|
||||||
CFLAGS=$CFLAGS
|
CFLAGS=$CFLAGS
|
||||||
@@ -214,6 +227,16 @@ esac
|
|||||||
AC_SUBST([abi])
|
AC_SUBST([abi])
|
||||||
AC_SUBST([RPATH])
|
AC_SUBST([RPATH])
|
||||||
|
|
||||||
|
JE_COMPILABLE([mremap(...MREMAP_FIXED...)], [
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <sys/mman.h>
|
||||||
|
], [
|
||||||
|
void *p = mremap((void *)0, 0, 0, MREMAP_MAYMOVE|MREMAP_FIXED, (void *)0);
|
||||||
|
], [mremap_fixed])
|
||||||
|
if test "x${mremap_fixed}" = "xyes" ; then
|
||||||
|
AC_DEFINE([JEMALLOC_MREMAP_FIXED])
|
||||||
|
fi
|
||||||
|
|
||||||
dnl Support optional additions to rpath.
|
dnl Support optional additions to rpath.
|
||||||
AC_ARG_WITH([rpath],
|
AC_ARG_WITH([rpath],
|
||||||
[AS_HELP_STRING([--with-rpath=<rpath>], [Colon-separated rpath (ELF systems only)])],
|
[AS_HELP_STRING([--with-rpath=<rpath>], [Colon-separated rpath (ELF systems only)])],
|
||||||
@@ -275,17 +298,26 @@ AC_ARG_WITH([install_suffix],
|
|||||||
install_suffix="$INSTALL_SUFFIX"
|
install_suffix="$INSTALL_SUFFIX"
|
||||||
AC_SUBST([install_suffix])
|
AC_SUBST([install_suffix])
|
||||||
|
|
||||||
cfgoutputs_in="${srcroot}Makefile.in ${srcroot}doc/jemalloc.3.in"
|
cfgoutputs_in="${srcroot}Makefile.in"
|
||||||
|
cfgoutputs_in="${cfgoutputs_in} ${srcroot}doc/html.xsl.in"
|
||||||
|
cfgoutputs_in="${cfgoutputs_in} ${srcroot}doc/manpages.xsl.in"
|
||||||
|
cfgoutputs_in="${cfgoutputs_in} ${srcroot}doc/jemalloc.xml.in"
|
||||||
cfgoutputs_in="${cfgoutputs_in} ${srcroot}include/jemalloc/jemalloc.h.in"
|
cfgoutputs_in="${cfgoutputs_in} ${srcroot}include/jemalloc/jemalloc.h.in"
|
||||||
cfgoutputs_in="${cfgoutputs_in} ${srcroot}include/jemalloc/internal/jemalloc_internal.h.in"
|
cfgoutputs_in="${cfgoutputs_in} ${srcroot}include/jemalloc/internal/jemalloc_internal.h.in"
|
||||||
cfgoutputs_in="${cfgoutputs_in} ${srcroot}test/jemalloc_test.h.in"
|
cfgoutputs_in="${cfgoutputs_in} ${srcroot}test/jemalloc_test.h.in"
|
||||||
|
|
||||||
cfgoutputs_out="Makefile doc/jemalloc${install_suffix}.3"
|
cfgoutputs_out="Makefile"
|
||||||
|
cfgoutputs_out="${cfgoutputs_out} doc/html.xsl"
|
||||||
|
cfgoutputs_out="${cfgoutputs_out} doc/manpages.xsl"
|
||||||
|
cfgoutputs_out="${cfgoutputs_out} doc/jemalloc${install_suffix}.xml"
|
||||||
cfgoutputs_out="${cfgoutputs_out} include/jemalloc/jemalloc${install_suffix}.h"
|
cfgoutputs_out="${cfgoutputs_out} include/jemalloc/jemalloc${install_suffix}.h"
|
||||||
cfgoutputs_out="${cfgoutputs_out} include/jemalloc/internal/jemalloc_internal.h"
|
cfgoutputs_out="${cfgoutputs_out} include/jemalloc/internal/jemalloc_internal.h"
|
||||||
cfgoutputs_out="${cfgoutputs_out} test/jemalloc_test.h"
|
cfgoutputs_out="${cfgoutputs_out} test/jemalloc_test.h"
|
||||||
|
|
||||||
cfgoutputs_tup="Makefile doc/jemalloc${install_suffix}.3:doc/jemalloc.3.in"
|
cfgoutputs_tup="Makefile"
|
||||||
|
cfgoutputs_tup="${cfgoutputs_tup} doc/html.xsl:doc/html.xsl.in"
|
||||||
|
cfgoutputs_tup="${cfgoutputs_tup} doc/manpages.xsl:doc/manpages.xsl.in"
|
||||||
|
cfgoutputs_tup="${cfgoutputs_tup} doc/jemalloc${install_suffix}.xml:doc/jemalloc.xml.in"
|
||||||
cfgoutputs_tup="${cfgoutputs_tup} include/jemalloc/jemalloc${install_suffix}.h:include/jemalloc/jemalloc.h.in"
|
cfgoutputs_tup="${cfgoutputs_tup} include/jemalloc/jemalloc${install_suffix}.h:include/jemalloc/jemalloc.h.in"
|
||||||
cfgoutputs_tup="${cfgoutputs_tup} include/jemalloc/internal/jemalloc_internal.h"
|
cfgoutputs_tup="${cfgoutputs_tup} include/jemalloc/internal/jemalloc_internal.h"
|
||||||
cfgoutputs_tup="${cfgoutputs_tup} test/jemalloc_test.h:test/jemalloc_test.h.in"
|
cfgoutputs_tup="${cfgoutputs_tup} test/jemalloc_test.h:test/jemalloc_test.h.in"
|
||||||
@@ -329,15 +361,6 @@ if test "x$enable_debug" = "x1" ; then
|
|||||||
AC_DEFINE([JEMALLOC_IVSALLOC], [ ])
|
AC_DEFINE([JEMALLOC_IVSALLOC], [ ])
|
||||||
fi
|
fi
|
||||||
AC_SUBST([enable_debug])
|
AC_SUBST([enable_debug])
|
||||||
if test "x$enable_debug" = "x0" ; then
|
|
||||||
roff_debug=".\\\" "
|
|
||||||
roff_no_debug=""
|
|
||||||
else
|
|
||||||
roff_debug=""
|
|
||||||
roff_no_debug=".\\\" "
|
|
||||||
fi
|
|
||||||
AC_SUBST([roff_debug])
|
|
||||||
AC_SUBST([roff_no_debug])
|
|
||||||
|
|
||||||
dnl Only optimize if not debugging.
|
dnl Only optimize if not debugging.
|
||||||
if test "x$enable_debug" = "x0" -a "x$no_CFLAGS" = "xyes" ; then
|
if test "x$enable_debug" = "x0" -a "x$no_CFLAGS" = "xyes" ; then
|
||||||
@@ -369,12 +392,6 @@ if test "x$enable_stats" = "x1" ; then
|
|||||||
AC_DEFINE([JEMALLOC_STATS], [ ])
|
AC_DEFINE([JEMALLOC_STATS], [ ])
|
||||||
fi
|
fi
|
||||||
AC_SUBST([enable_stats])
|
AC_SUBST([enable_stats])
|
||||||
if test "x$enable_stats" = "x0" ; then
|
|
||||||
roff_stats=".\\\" "
|
|
||||||
else
|
|
||||||
roff_stats=""
|
|
||||||
fi
|
|
||||||
AC_SUBST([roff_stats])
|
|
||||||
|
|
||||||
dnl Do not enable profiling by default.
|
dnl Do not enable profiling by default.
|
||||||
AC_ARG_ENABLE([prof],
|
AC_ARG_ENABLE([prof],
|
||||||
@@ -438,15 +455,6 @@ if test "x$enable_prof" = "x1" ; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
AC_SUBST([enable_prof])
|
AC_SUBST([enable_prof])
|
||||||
if test "x$enable_prof" = "x0" ; then
|
|
||||||
roff_prof=".\\\" "
|
|
||||||
roff_no_prof=""
|
|
||||||
else
|
|
||||||
roff_prof=""
|
|
||||||
roff_no_prof=".\\\" "
|
|
||||||
fi
|
|
||||||
AC_SUBST([roff_prof])
|
|
||||||
AC_SUBST([roff_no_prof])
|
|
||||||
|
|
||||||
dnl If libunwind isn't enabled, try to use libgcc rather than gcc intrinsics
|
dnl If libunwind isn't enabled, try to use libgcc rather than gcc intrinsics
|
||||||
dnl for backtracing.
|
dnl for backtracing.
|
||||||
@@ -478,15 +486,6 @@ if test "x$enable_tiny" = "x1" ; then
|
|||||||
AC_DEFINE([JEMALLOC_TINY], [ ])
|
AC_DEFINE([JEMALLOC_TINY], [ ])
|
||||||
fi
|
fi
|
||||||
AC_SUBST([enable_tiny])
|
AC_SUBST([enable_tiny])
|
||||||
if test "x$enable_tiny" = "x0" ; then
|
|
||||||
roff_tiny=".\\\" "
|
|
||||||
roff_no_tiny=""
|
|
||||||
else
|
|
||||||
roff_tiny=""
|
|
||||||
roff_no_tiny=".\\\" "
|
|
||||||
fi
|
|
||||||
AC_SUBST([roff_tiny])
|
|
||||||
AC_SUBST([roff_no_tiny])
|
|
||||||
|
|
||||||
dnl Enable thread-specific caching by default.
|
dnl Enable thread-specific caching by default.
|
||||||
AC_ARG_ENABLE([tcache],
|
AC_ARG_ENABLE([tcache],
|
||||||
@@ -503,15 +502,6 @@ if test "x$enable_tcache" = "x1" ; then
|
|||||||
AC_DEFINE([JEMALLOC_TCACHE], [ ])
|
AC_DEFINE([JEMALLOC_TCACHE], [ ])
|
||||||
fi
|
fi
|
||||||
AC_SUBST([enable_tcache])
|
AC_SUBST([enable_tcache])
|
||||||
if test "x$enable_tcache" = "x0" ; then
|
|
||||||
roff_tcache=".\\\" "
|
|
||||||
roff_no_tcache=""
|
|
||||||
else
|
|
||||||
roff_tcache=""
|
|
||||||
roff_no_tcache=".\\\" "
|
|
||||||
fi
|
|
||||||
AC_SUBST([roff_tcache])
|
|
||||||
AC_SUBST([roff_no_tcache])
|
|
||||||
|
|
||||||
dnl Do not enable mmap()ped swap files by default.
|
dnl Do not enable mmap()ped swap files by default.
|
||||||
AC_ARG_ENABLE([swap],
|
AC_ARG_ENABLE([swap],
|
||||||
@@ -528,12 +518,6 @@ if test "x$enable_swap" = "x1" ; then
|
|||||||
AC_DEFINE([JEMALLOC_SWAP], [ ])
|
AC_DEFINE([JEMALLOC_SWAP], [ ])
|
||||||
fi
|
fi
|
||||||
AC_SUBST([enable_swap])
|
AC_SUBST([enable_swap])
|
||||||
if test "x$enable_swap" = "x0" ; then
|
|
||||||
roff_swap=".\\\" "
|
|
||||||
else
|
|
||||||
roff_swap=""
|
|
||||||
fi
|
|
||||||
AC_SUBST([roff_swap])
|
|
||||||
|
|
||||||
dnl Do not enable allocation from DSS by default.
|
dnl Do not enable allocation from DSS by default.
|
||||||
AC_ARG_ENABLE([dss],
|
AC_ARG_ENABLE([dss],
|
||||||
@@ -550,12 +534,6 @@ if test "x$enable_dss" = "x1" ; then
|
|||||||
AC_DEFINE([JEMALLOC_DSS], [ ])
|
AC_DEFINE([JEMALLOC_DSS], [ ])
|
||||||
fi
|
fi
|
||||||
AC_SUBST([enable_dss])
|
AC_SUBST([enable_dss])
|
||||||
if test "x$enable_dss" = "x0" ; then
|
|
||||||
roff_dss=".\\\" "
|
|
||||||
else
|
|
||||||
roff_dss=""
|
|
||||||
fi
|
|
||||||
AC_SUBST([roff_dss])
|
|
||||||
|
|
||||||
dnl Do not support the junk/zero filling option by default.
|
dnl Do not support the junk/zero filling option by default.
|
||||||
AC_ARG_ENABLE([fill],
|
AC_ARG_ENABLE([fill],
|
||||||
@@ -572,12 +550,6 @@ if test "x$enable_fill" = "x1" ; then
|
|||||||
AC_DEFINE([JEMALLOC_FILL], [ ])
|
AC_DEFINE([JEMALLOC_FILL], [ ])
|
||||||
fi
|
fi
|
||||||
AC_SUBST([enable_fill])
|
AC_SUBST([enable_fill])
|
||||||
if test "x$enable_fill" = "x0" ; then
|
|
||||||
roff_fill=".\\\" "
|
|
||||||
else
|
|
||||||
roff_fill=""
|
|
||||||
fi
|
|
||||||
AC_SUBST([roff_fill])
|
|
||||||
|
|
||||||
dnl Do not support the xmalloc option by default.
|
dnl Do not support the xmalloc option by default.
|
||||||
AC_ARG_ENABLE([xmalloc],
|
AC_ARG_ENABLE([xmalloc],
|
||||||
@@ -594,12 +566,6 @@ if test "x$enable_xmalloc" = "x1" ; then
|
|||||||
AC_DEFINE([JEMALLOC_XMALLOC], [ ])
|
AC_DEFINE([JEMALLOC_XMALLOC], [ ])
|
||||||
fi
|
fi
|
||||||
AC_SUBST([enable_xmalloc])
|
AC_SUBST([enable_xmalloc])
|
||||||
if test "x$enable_xmalloc" = "x0" ; then
|
|
||||||
roff_xmalloc=".\\\" "
|
|
||||||
else
|
|
||||||
roff_xmalloc=""
|
|
||||||
fi
|
|
||||||
AC_SUBST([roff_xmalloc])
|
|
||||||
|
|
||||||
dnl Do not support the SYSV option by default.
|
dnl Do not support the SYSV option by default.
|
||||||
AC_ARG_ENABLE([sysv],
|
AC_ARG_ENABLE([sysv],
|
||||||
@@ -616,12 +582,6 @@ if test "x$enable_sysv" = "x1" ; then
|
|||||||
AC_DEFINE([JEMALLOC_SYSV], [ ])
|
AC_DEFINE([JEMALLOC_SYSV], [ ])
|
||||||
fi
|
fi
|
||||||
AC_SUBST([enable_sysv])
|
AC_SUBST([enable_sysv])
|
||||||
if test "x$enable_sysv" = "x0" ; then
|
|
||||||
roff_sysv=".\\\" "
|
|
||||||
else
|
|
||||||
roff_sysv=""
|
|
||||||
fi
|
|
||||||
AC_SUBST([roff_sysv])
|
|
||||||
|
|
||||||
dnl Do not determine page shift at run time by default.
|
dnl Do not determine page shift at run time by default.
|
||||||
AC_ARG_ENABLE([dynamic_page_shift],
|
AC_ARG_ENABLE([dynamic_page_shift],
|
||||||
@@ -828,6 +788,9 @@ AC_MSG_RESULT([LDFLAGS : ${LDFLAGS}])
|
|||||||
AC_MSG_RESULT([LIBS : ${LIBS}])
|
AC_MSG_RESULT([LIBS : ${LIBS}])
|
||||||
AC_MSG_RESULT([RPATH_EXTRA : ${RPATH_EXTRA}])
|
AC_MSG_RESULT([RPATH_EXTRA : ${RPATH_EXTRA}])
|
||||||
AC_MSG_RESULT([])
|
AC_MSG_RESULT([])
|
||||||
|
AC_MSG_RESULT([XSLTPROC : ${XSLTPROC}])
|
||||||
|
AC_MSG_RESULT([XSLROOT : ${XSLROOT}])
|
||||||
|
AC_MSG_RESULT([])
|
||||||
AC_MSG_RESULT([PREFIX : ${PREFIX}])
|
AC_MSG_RESULT([PREFIX : ${PREFIX}])
|
||||||
AC_MSG_RESULT([BINDIR : ${BINDIR}])
|
AC_MSG_RESULT([BINDIR : ${BINDIR}])
|
||||||
AC_MSG_RESULT([INCLUDEDIR : ${INCLUDEDIR}])
|
AC_MSG_RESULT([INCLUDEDIR : ${INCLUDEDIR}])
|
||||||
|
|||||||
4
jemalloc/doc/html.xsl.in
Normal file
4
jemalloc/doc/html.xsl.in
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
|
||||||
|
<xsl:import href="@XSLROOT@/html/docbook.xsl"/>
|
||||||
|
<xsl:import href="@abs_srcroot@doc/stylesheet.xsl"/>
|
||||||
|
</xsl:stylesheet>
|
||||||
File diff suppressed because it is too large
Load Diff
2251
jemalloc/doc/jemalloc.xml.in
Normal file
2251
jemalloc/doc/jemalloc.xml.in
Normal file
File diff suppressed because it is too large
Load Diff
4
jemalloc/doc/manpages.xsl.in
Normal file
4
jemalloc/doc/manpages.xsl.in
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
|
||||||
|
<xsl:import href="@XSLROOT@/manpages/docbook.xsl"/>
|
||||||
|
<xsl:import href="@abs_srcroot@doc/stylesheet.xsl"/>
|
||||||
|
</xsl:stylesheet>
|
||||||
7
jemalloc/doc/stylesheet.xsl
Normal file
7
jemalloc/doc/stylesheet.xsl
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
|
||||||
|
<xsl:param name="funcsynopsis.style">ansi</xsl:param>
|
||||||
|
<xsl:param name="function.parens" select="1"/>
|
||||||
|
<xsl:template match="mallctl">
|
||||||
|
"<xsl:call-template name="inline.monoseq"/>"
|
||||||
|
</xsl:template>
|
||||||
|
</xsl:stylesheet>
|
||||||
@@ -45,9 +45,10 @@
|
|||||||
* point is implicitly RUN_BFP bits to the left.
|
* point is implicitly RUN_BFP bits to the left.
|
||||||
*
|
*
|
||||||
* Note that it is possible to set RUN_MAX_OVRHD low enough that it cannot be
|
* Note that it is possible to set RUN_MAX_OVRHD low enough that it cannot be
|
||||||
* honored for some/all object sizes, since there is one bit of header overhead
|
* honored for some/all object sizes, since when heap profiling is enabled
|
||||||
* per object (plus a constant). This constraint is relaxed (ignored) for runs
|
* there is one pointer of header overhead per object (plus a constant). This
|
||||||
* that are so small that the per-region overhead is greater than:
|
* constraint is relaxed (ignored) for runs that are so small that the
|
||||||
|
* per-region overhead is greater than:
|
||||||
*
|
*
|
||||||
* (RUN_MAX_OVRHD / (reg_size << (3+RUN_BFP))
|
* (RUN_MAX_OVRHD / (reg_size << (3+RUN_BFP))
|
||||||
*/
|
*/
|
||||||
@@ -105,7 +106,7 @@ struct arena_chunk_map_s {
|
|||||||
* Run address (or size) and various flags are stored together. The bit
|
* Run address (or size) and various flags are stored together. The bit
|
||||||
* layout looks like (assuming 32-bit system):
|
* layout looks like (assuming 32-bit system):
|
||||||
*
|
*
|
||||||
* ???????? ???????? ????---- ----dzla
|
* ???????? ???????? ????---- ----dula
|
||||||
*
|
*
|
||||||
* ? : Unallocated: Run address for first/last pages, unset for internal
|
* ? : Unallocated: Run address for first/last pages, unset for internal
|
||||||
* pages.
|
* pages.
|
||||||
@@ -113,7 +114,7 @@ struct arena_chunk_map_s {
|
|||||||
* Large: Run size for first page, unset for trailing pages.
|
* Large: Run size for first page, unset for trailing pages.
|
||||||
* - : Unused.
|
* - : Unused.
|
||||||
* d : dirty?
|
* d : dirty?
|
||||||
* z : zeroed?
|
* u : unzeroed?
|
||||||
* l : large?
|
* l : large?
|
||||||
* a : allocated?
|
* a : allocated?
|
||||||
*
|
*
|
||||||
@@ -129,30 +130,30 @@ struct arena_chunk_map_s {
|
|||||||
* [dula] : bit unset
|
* [dula] : bit unset
|
||||||
*
|
*
|
||||||
* Unallocated (clean):
|
* Unallocated (clean):
|
||||||
* ssssssss ssssssss ssss---- ----du--
|
* ssssssss ssssssss ssss---- ----du-a
|
||||||
* xxxxxxxx xxxxxxxx xxxx---- -----Uxx
|
* xxxxxxxx xxxxxxxx xxxx---- -----Uxx
|
||||||
* ssssssss ssssssss ssss---- ----dU--
|
* ssssssss ssssssss ssss---- ----dU-a
|
||||||
*
|
*
|
||||||
* Unallocated (dirty):
|
* Unallocated (dirty):
|
||||||
* ssssssss ssssssss ssss---- ----D---
|
* ssssssss ssssssss ssss---- ----D--a
|
||||||
* xxxxxxxx xxxxxxxx xxxx---- ----xxxx
|
* xxxxxxxx xxxxxxxx xxxx---- ----xxxx
|
||||||
* ssssssss ssssssss ssss---- ----D---
|
* ssssssss ssssssss ssss---- ----D--a
|
||||||
*
|
*
|
||||||
* Small:
|
* Small:
|
||||||
* pppppppp pppppppp pppp---- ----d--a
|
* pppppppp pppppppp pppp---- ----d--A
|
||||||
* pppppppp pppppppp pppp---- -------a
|
* pppppppp pppppppp pppp---- -------A
|
||||||
* pppppppp pppppppp pppp---- ----d--a
|
* pppppppp pppppppp pppp---- ----d--A
|
||||||
*
|
*
|
||||||
* Large:
|
* Large:
|
||||||
* ssssssss ssssssss ssss---- ----D-la
|
* ssssssss ssssssss ssss---- ----D-LA
|
||||||
* xxxxxxxx xxxxxxxx xxxx---- ----xxxx
|
* xxxxxxxx xxxxxxxx xxxx---- ----xxxx
|
||||||
* -------- -------- -------- ----D-la
|
* -------- -------- -------- ----D-LA
|
||||||
*
|
*
|
||||||
* Large (sampled, size <= PAGE_SIZE):
|
* Large (sampled, size <= PAGE_SIZE):
|
||||||
* ssssssss ssssssss sssscccc ccccD-la
|
* ssssssss ssssssss sssscccc ccccD-LA
|
||||||
*
|
*
|
||||||
* Large (not sampled, size == PAGE_SIZE):
|
* Large (not sampled, size == PAGE_SIZE):
|
||||||
* ssssssss ssssssss ssss---- ----D-la
|
* ssssssss ssssssss ssss---- ----D-LA
|
||||||
*/
|
*/
|
||||||
size_t bits;
|
size_t bits;
|
||||||
#ifdef JEMALLOC_PROF
|
#ifdef JEMALLOC_PROF
|
||||||
@@ -347,45 +348,35 @@ struct arena_s {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* bins is used to store trees of free regions of the following sizes,
|
* bins is used to store trees of free regions of the following sizes,
|
||||||
* assuming a 16-byte quantum, 4 KiB page size, and default
|
* assuming a 64-bit system with 16-byte quantum, 4 KiB page size, and
|
||||||
* JEMALLOC_OPTIONS.
|
* default MALLOC_CONF.
|
||||||
*
|
*
|
||||||
* bins[i] | size |
|
* bins[i] | size |
|
||||||
* --------+--------+
|
* --------+--------+
|
||||||
* 0 | 2 |
|
* 0 | 8 |
|
||||||
* 1 | 4 |
|
|
||||||
* 2 | 8 |
|
|
||||||
* --------+--------+
|
* --------+--------+
|
||||||
* 3 | 16 |
|
* 1 | 16 |
|
||||||
* 4 | 32 |
|
* 2 | 32 |
|
||||||
* 5 | 48 |
|
* 3 | 48 |
|
||||||
* : :
|
* : :
|
||||||
* 8 | 96 |
|
* 6 | 96 |
|
||||||
* 9 | 112 |
|
* 7 | 112 |
|
||||||
* 10 | 128 |
|
* 8 | 128 |
|
||||||
* --------+--------+
|
* --------+--------+
|
||||||
* 11 | 192 |
|
* 9 | 192 |
|
||||||
* 12 | 256 |
|
* 10 | 256 |
|
||||||
* 13 | 320 |
|
* 11 | 320 |
|
||||||
* 14 | 384 |
|
* 12 | 384 |
|
||||||
* 15 | 448 |
|
* 13 | 448 |
|
||||||
* 16 | 512 |
|
* 14 | 512 |
|
||||||
* --------+--------+
|
* --------+--------+
|
||||||
* 17 | 768 |
|
* 15 | 768 |
|
||||||
* 18 | 1024 |
|
* 16 | 1024 |
|
||||||
* 19 | 1280 |
|
* 17 | 1280 |
|
||||||
* : :
|
* : :
|
||||||
* 27 | 3328 |
|
* 25 | 3328 |
|
||||||
* 28 | 3584 |
|
* 26 | 3584 |
|
||||||
* 29 | 3840 |
|
* 27 | 3840 |
|
||||||
* --------+--------+
|
|
||||||
* 30 | 4 KiB |
|
|
||||||
* 31 | 6 KiB |
|
|
||||||
* 33 | 8 KiB |
|
|
||||||
* : :
|
|
||||||
* 43 | 28 KiB |
|
|
||||||
* 44 | 30 KiB |
|
|
||||||
* 45 | 32 KiB |
|
|
||||||
* --------+--------+
|
* --------+--------+
|
||||||
*/
|
*/
|
||||||
arena_bin_t bins[1]; /* Dynamically sized. */
|
arena_bin_t bins[1]; /* Dynamically sized. */
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
extern malloc_mutex_t dss_mtx;
|
extern malloc_mutex_t dss_mtx;
|
||||||
|
|
||||||
void *chunk_alloc_dss(size_t size, bool *zero);
|
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_dealloc_dss(void *chunk, size_t size);
|
||||||
bool chunk_dss_boot(void);
|
bool chunk_dss_boot(void);
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ extern size_t swap_avail;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void *chunk_alloc_swap(size_t size, bool *zero);
|
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_dealloc_swap(void *chunk, size_t size);
|
||||||
bool chunk_swap_enable(const int *fds, unsigned nfds, bool prezeroed);
|
bool chunk_swap_enable(const int *fds, unsigned nfds, bool prezeroed);
|
||||||
bool chunk_swap_boot(void);
|
bool chunk_swap_boot(void);
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ struct ckhc_s {
|
|||||||
|
|
||||||
struct ckh_s {
|
struct ckh_s {
|
||||||
#ifdef JEMALLOC_DEBUG
|
#ifdef JEMALLOC_DEBUG
|
||||||
#define CKH_MAGIG 0x3af2489d
|
#define CKH_MAGIC 0x3af2489d
|
||||||
uint32_t magic;
|
uint32_t magic;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ hash(const void *key, size_t len, uint64_t seed)
|
|||||||
h *= m;
|
h *= m;
|
||||||
h ^= h >> r;
|
h ^= h >> r;
|
||||||
|
|
||||||
return h;
|
return (h);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ void *huge_ralloc_no_move(void *ptr, size_t oldsize, size_t size,
|
|||||||
size_t extra);
|
size_t extra);
|
||||||
void *huge_ralloc(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);
|
size_t alignment, bool zero);
|
||||||
void huge_dalloc(void *ptr);
|
void huge_dalloc(void *ptr, bool unmap);
|
||||||
size_t huge_salloc(const void *ptr);
|
size_t huge_salloc(const void *ptr);
|
||||||
#ifdef JEMALLOC_PROF
|
#ifdef JEMALLOC_PROF
|
||||||
prof_ctx_t *huge_prof_ctx_get(const void *ptr);
|
prof_ctx_t *huge_prof_ctx_get(const void *ptr);
|
||||||
|
|||||||
@@ -148,11 +148,6 @@ extern void (*JEMALLOC_P(malloc_message))(void *wcbopaque, const char *s);
|
|||||||
|
|
||||||
#define SIZEOF_PTR (1U << LG_SIZEOF_PTR)
|
#define SIZEOF_PTR (1U << LG_SIZEOF_PTR)
|
||||||
|
|
||||||
/* We can't use TLS in non-PIC programs, since TLS relies on loader magic. */
|
|
||||||
#if (!defined(PIC) && !defined(NO_TLS))
|
|
||||||
# define NO_TLS
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Maximum size of L1 cache line. This is used to avoid cache line aliasing.
|
* Maximum size of L1 cache line. This is used to avoid cache line aliasing.
|
||||||
* In addition, this controls the spacing of cacheline-spaced size classes.
|
* In addition, this controls the spacing of cacheline-spaced size classes.
|
||||||
@@ -240,6 +235,13 @@ extern void (*JEMALLOC_P(malloc_message))(void *wcbopaque, const char *s);
|
|||||||
#endif
|
#endif
|
||||||
#include "jemalloc/internal/prof.h"
|
#include "jemalloc/internal/prof.h"
|
||||||
|
|
||||||
|
#ifdef JEMALLOC_STATS
|
||||||
|
typedef struct {
|
||||||
|
uint64_t allocated;
|
||||||
|
uint64_t deallocated;
|
||||||
|
} thread_allocated_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
#undef JEMALLOC_H_STRUCTS
|
#undef JEMALLOC_H_STRUCTS
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
#define JEMALLOC_H_EXTERNS
|
#define JEMALLOC_H_EXTERNS
|
||||||
@@ -295,45 +297,28 @@ extern arena_t **arenas;
|
|||||||
extern unsigned narenas;
|
extern unsigned narenas;
|
||||||
|
|
||||||
#ifdef JEMALLOC_STATS
|
#ifdef JEMALLOC_STATS
|
||||||
typedef struct {
|
|
||||||
uint64_t allocated;
|
|
||||||
uint64_t deallocated;
|
|
||||||
} thread_allocated_t;
|
|
||||||
# ifndef NO_TLS
|
# ifndef NO_TLS
|
||||||
extern __thread thread_allocated_t thread_allocated_tls;
|
extern __thread thread_allocated_t thread_allocated_tls;
|
||||||
# define ALLOCATED_GET() thread_allocated_tls.allocated
|
# define ALLOCATED_GET() (thread_allocated_tls.allocated)
|
||||||
# define DEALLOCATED_GET() thread_allocated_tls.deallocated
|
# define ALLOCATEDP_GET() (&thread_allocated_tls.allocated)
|
||||||
|
# define DEALLOCATED_GET() (thread_allocated_tls.deallocated)
|
||||||
|
# define DEALLOCATEDP_GET() (&thread_allocated_tls.deallocated)
|
||||||
# define ALLOCATED_ADD(a, d) do { \
|
# define ALLOCATED_ADD(a, d) do { \
|
||||||
thread_allocated_tls.allocated += a; \
|
thread_allocated_tls.allocated += a; \
|
||||||
thread_allocated_tls.deallocated += d; \
|
thread_allocated_tls.deallocated += d; \
|
||||||
} while (0)
|
} while (0)
|
||||||
# else
|
# else
|
||||||
extern pthread_key_t thread_allocated_tsd;
|
extern pthread_key_t thread_allocated_tsd;
|
||||||
# define ALLOCATED_GET() \
|
thread_allocated_t *thread_allocated_get_hard(void);
|
||||||
(uint64_t)((pthread_getspecific(thread_allocated_tsd) != NULL) \
|
|
||||||
? ((thread_allocated_t *) \
|
# define ALLOCATED_GET() (thread_allocated_get()->allocated)
|
||||||
pthread_getspecific(thread_allocated_tsd))->allocated : 0)
|
# define ALLOCATEDP_GET() (&thread_allocated_get()->allocated)
|
||||||
# define DEALLOCATED_GET() \
|
# define DEALLOCATED_GET() (thread_allocated_get()->deallocated)
|
||||||
(uint64_t)((pthread_getspecific(thread_allocated_tsd) != NULL) \
|
# define DEALLOCATEDP_GET() (&thread_allocated_get()->deallocated)
|
||||||
? ((thread_allocated_t \
|
|
||||||
*)pthread_getspecific(thread_allocated_tsd))->deallocated : \
|
|
||||||
0)
|
|
||||||
# define ALLOCATED_ADD(a, d) do { \
|
# define ALLOCATED_ADD(a, d) do { \
|
||||||
thread_allocated_t *thread_allocated = (thread_allocated_t *) \
|
thread_allocated_t *thread_allocated = thread_allocated_get(); \
|
||||||
pthread_getspecific(thread_allocated_tsd); \
|
|
||||||
if (thread_allocated != NULL) { \
|
|
||||||
thread_allocated->allocated += (a); \
|
thread_allocated->allocated += (a); \
|
||||||
thread_allocated->deallocated += (d); \
|
thread_allocated->deallocated += (d); \
|
||||||
} else { \
|
|
||||||
thread_allocated = (thread_allocated_t *) \
|
|
||||||
imalloc(sizeof(thread_allocated_t)); \
|
|
||||||
if (thread_allocated != NULL) { \
|
|
||||||
pthread_setspecific(thread_allocated_tsd, \
|
|
||||||
thread_allocated); \
|
|
||||||
thread_allocated->allocated = (a); \
|
|
||||||
thread_allocated->deallocated = (d); \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
} while (0)
|
} while (0)
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
@@ -384,6 +369,9 @@ size_t s2u(size_t size);
|
|||||||
size_t sa2u(size_t size, size_t alignment, size_t *run_size_p);
|
size_t sa2u(size_t size, size_t alignment, size_t *run_size_p);
|
||||||
void malloc_write(const char *s);
|
void malloc_write(const char *s);
|
||||||
arena_t *choose_arena(void);
|
arena_t *choose_arena(void);
|
||||||
|
# if (defined(JEMALLOC_STATS) && defined(NO_TLS))
|
||||||
|
thread_allocated_t *thread_allocated_get(void);
|
||||||
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_C_))
|
#if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_C_))
|
||||||
@@ -414,10 +402,10 @@ s2u(size_t size)
|
|||||||
{
|
{
|
||||||
|
|
||||||
if (size <= small_maxclass)
|
if (size <= small_maxclass)
|
||||||
return arenas[0]->bins[small_size2bin[size]].reg_size;
|
return (arenas[0]->bins[small_size2bin[size]].reg_size);
|
||||||
if (size <= arena_maxclass)
|
if (size <= arena_maxclass)
|
||||||
return PAGE_CEILING(size);
|
return (PAGE_CEILING(size));
|
||||||
return CHUNK_CEILING(size);
|
return (CHUNK_CEILING(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -544,6 +532,19 @@ choose_arena(void)
|
|||||||
|
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (defined(JEMALLOC_STATS) && defined(NO_TLS))
|
||||||
|
JEMALLOC_INLINE thread_allocated_t *
|
||||||
|
thread_allocated_get(void)
|
||||||
|
{
|
||||||
|
thread_allocated_t *thread_allocated = (thread_allocated_t *)
|
||||||
|
pthread_getspecific(thread_allocated_tsd);
|
||||||
|
|
||||||
|
if (thread_allocated == NULL)
|
||||||
|
return (thread_allocated_get_hard());
|
||||||
|
return (thread_allocated);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "jemalloc/internal/rtree.h"
|
#include "jemalloc/internal/rtree.h"
|
||||||
@@ -666,7 +667,7 @@ idalloc(void *ptr)
|
|||||||
if (chunk != ptr)
|
if (chunk != ptr)
|
||||||
arena_dalloc(chunk->arena, chunk, ptr);
|
arena_dalloc(chunk->arena, chunk, ptr);
|
||||||
else
|
else
|
||||||
huge_dalloc(ptr);
|
huge_dalloc(ptr, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
JEMALLOC_INLINE void *
|
JEMALLOC_INLINE void *
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ struct tcache_bin_s {
|
|||||||
tcache_bin_stats_t tstats;
|
tcache_bin_stats_t tstats;
|
||||||
# endif
|
# endif
|
||||||
unsigned low_water; /* Min # cached since last GC. */
|
unsigned low_water; /* Min # cached since last GC. */
|
||||||
unsigned high_water; /* Max # cached since last GC. */
|
|
||||||
unsigned ncached; /* # of cached objects. */
|
unsigned ncached; /* # of cached objects. */
|
||||||
unsigned ncached_max; /* Upper limit on ncached. */
|
unsigned ncached_max; /* Upper limit on ncached. */
|
||||||
void *avail; /* Chain of available objects. */
|
void *avail; /* Chain of available objects. */
|
||||||
@@ -194,7 +193,6 @@ tcache_event(tcache_t *tcache)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
tbin->low_water = tbin->ncached;
|
tbin->low_water = tbin->ncached;
|
||||||
tbin->high_water = tbin->ncached;
|
|
||||||
|
|
||||||
tcache->next_gc_bin++;
|
tcache->next_gc_bin++;
|
||||||
if (tcache->next_gc_bin == nhbins)
|
if (tcache->next_gc_bin == nhbins)
|
||||||
@@ -348,8 +346,6 @@ tcache_dalloc_small(tcache_t *tcache, void *ptr)
|
|||||||
*(void **)ptr = tbin->avail;
|
*(void **)ptr = tbin->avail;
|
||||||
tbin->avail = ptr;
|
tbin->avail = ptr;
|
||||||
tbin->ncached++;
|
tbin->ncached++;
|
||||||
if (tbin->ncached > tbin->high_water)
|
|
||||||
tbin->high_water = tbin->ncached;
|
|
||||||
|
|
||||||
tcache_event(tcache);
|
tcache_event(tcache);
|
||||||
}
|
}
|
||||||
@@ -388,8 +384,6 @@ tcache_dalloc_large(tcache_t *tcache, void *ptr, size_t size)
|
|||||||
*(void **)ptr = tbin->avail;
|
*(void **)ptr = tbin->avail;
|
||||||
tbin->avail = ptr;
|
tbin->avail = ptr;
|
||||||
tbin->ncached++;
|
tbin->ncached++;
|
||||||
if (tbin->ncached > tbin->high_water)
|
|
||||||
tbin->high_water = tbin->ncached;
|
|
||||||
|
|
||||||
tcache_event(tcache);
|
tcache_event(tcache);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ extern "C" {
|
|||||||
# define JEMALLOC_P(s) s
|
# define JEMALLOC_P(s) s
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ALLOCM_LG_ALIGN ((int)0x3f)
|
#define ALLOCM_LG_ALIGN(la) (la)
|
||||||
#if LG_SIZEOF_PTR == 2
|
#if LG_SIZEOF_PTR == 2
|
||||||
#define ALLOCM_ALIGN(a) (ffs(a)-1)
|
#define ALLOCM_ALIGN(a) (ffs(a)-1)
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -115,6 +115,9 @@
|
|||||||
#undef JEMALLOC_ZONE
|
#undef JEMALLOC_ZONE
|
||||||
#undef JEMALLOC_ZONE_VERSION
|
#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.
|
* Methods for purging unused pages differ between operating systems.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -304,8 +304,10 @@ arena_run_reg_dalloc(arena_run_t *run, void *ptr)
|
|||||||
static inline void
|
static inline void
|
||||||
arena_chunk_validate_zeroed(arena_chunk_t *chunk, size_t run_ind)
|
arena_chunk_validate_zeroed(arena_chunk_t *chunk, size_t run_ind)
|
||||||
{
|
{
|
||||||
|
size_t i;
|
||||||
size_t *p = (size_t *)((uintptr_t)chunk + (run_ind << PAGE_SHIFT));
|
size_t *p = (size_t *)((uintptr_t)chunk + (run_ind << PAGE_SHIFT));
|
||||||
for (size_t i = 0; i < PAGE_SIZE / sizeof(size_t); i++)
|
|
||||||
|
for (i = 0; i < PAGE_SIZE / sizeof(size_t); i++)
|
||||||
assert(p[i] == 0);
|
assert(p[i] == 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -1356,8 +1358,6 @@ arena_tcache_fill_small(arena_t *arena, tcache_bin_t *tbin, size_t binind
|
|||||||
#endif
|
#endif
|
||||||
malloc_mutex_unlock(&bin->lock);
|
malloc_mutex_unlock(&bin->lock);
|
||||||
tbin->ncached = i;
|
tbin->ncached = i;
|
||||||
if (tbin->ncached > tbin->high_water)
|
|
||||||
tbin->high_water = tbin->ncached;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1367,7 +1367,6 @@ arena_tcache_fill_small(arena_t *arena, tcache_bin_t *tbin, size_t binind
|
|||||||
* *) bin->run_size >= min_run_size
|
* *) bin->run_size >= min_run_size
|
||||||
* *) bin->run_size <= arena_maxclass
|
* *) bin->run_size <= arena_maxclass
|
||||||
* *) run header overhead <= RUN_MAX_OVRHD (or header overhead relaxed).
|
* *) run header overhead <= RUN_MAX_OVRHD (or header overhead relaxed).
|
||||||
* *) run header size < PAGE_SIZE
|
|
||||||
*
|
*
|
||||||
* bin->nregs and bin->reg0_offset are also calculated here, since these
|
* bin->nregs and bin->reg0_offset are also calculated here, since these
|
||||||
* settings are all interdependent.
|
* settings are all interdependent.
|
||||||
@@ -1453,8 +1452,7 @@ arena_bin_run_size_calc(arena_bin_t *bin, size_t min_run_size)
|
|||||||
} while (try_run_size <= arena_maxclass
|
} while (try_run_size <= arena_maxclass
|
||||||
&& try_run_size <= arena_maxclass
|
&& try_run_size <= arena_maxclass
|
||||||
&& RUN_MAX_OVRHD * (bin->reg_size << 3) > RUN_MAX_OVRHD_RELAX
|
&& RUN_MAX_OVRHD * (bin->reg_size << 3) > RUN_MAX_OVRHD_RELAX
|
||||||
&& (try_reg0_offset << RUN_BFP) > RUN_MAX_OVRHD * try_run_size
|
&& (try_reg0_offset << RUN_BFP) > RUN_MAX_OVRHD * try_run_size);
|
||||||
&& try_hdr_size < PAGE_SIZE);
|
|
||||||
|
|
||||||
assert(good_hdr_size <= good_reg0_offset);
|
assert(good_hdr_size <= good_reg0_offset);
|
||||||
|
|
||||||
|
|||||||
@@ -146,11 +146,6 @@ chunk_boot(void)
|
|||||||
chunksize_mask = chunksize - 1;
|
chunksize_mask = chunksize - 1;
|
||||||
chunk_npages = (chunksize >> PAGE_SHIFT);
|
chunk_npages = (chunksize >> PAGE_SHIFT);
|
||||||
|
|
||||||
#ifdef JEMALLOC_IVSALLOC
|
|
||||||
chunks_rtree = rtree_new((ZU(1) << (LG_SIZEOF_PTR+3)) - opt_lg_chunk);
|
|
||||||
if (chunks_rtree == NULL)
|
|
||||||
return (true);
|
|
||||||
#endif
|
|
||||||
#if (defined(JEMALLOC_STATS) || defined(JEMALLOC_PROF))
|
#if (defined(JEMALLOC_STATS) || defined(JEMALLOC_PROF))
|
||||||
if (malloc_mutex_init(&chunks_mtx))
|
if (malloc_mutex_init(&chunks_mtx))
|
||||||
return (true);
|
return (true);
|
||||||
@@ -166,6 +161,11 @@ chunk_boot(void)
|
|||||||
if (chunk_dss_boot())
|
if (chunk_dss_boot())
|
||||||
return (true);
|
return (true);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef JEMALLOC_IVSALLOC
|
||||||
|
chunks_rtree = rtree_new((ZU(1) << (LG_SIZEOF_PTR+3)) - opt_lg_chunk);
|
||||||
|
if (chunks_rtree == NULL)
|
||||||
|
return (true);
|
||||||
|
#endif
|
||||||
|
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -199,6 +199,22 @@ chunk_dealloc_dss_record(void *chunk, size_t size)
|
|||||||
return (node);
|
return (node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
chunk_in_dss(void *chunk)
|
||||||
|
{
|
||||||
|
bool ret;
|
||||||
|
|
||||||
|
malloc_mutex_lock(&dss_mtx);
|
||||||
|
if ((uintptr_t)chunk >= (uintptr_t)dss_base
|
||||||
|
&& (uintptr_t)chunk < (uintptr_t)dss_max)
|
||||||
|
ret = true;
|
||||||
|
else
|
||||||
|
ret = false;
|
||||||
|
malloc_mutex_unlock(&dss_mtx);
|
||||||
|
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
chunk_dealloc_dss(void *chunk, size_t size)
|
chunk_dealloc_dss(void *chunk, size_t size)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -206,13 +206,15 @@ chunk_alloc_mmap_internal(size_t size, bool noreserve)
|
|||||||
void *
|
void *
|
||||||
chunk_alloc_mmap(size_t size)
|
chunk_alloc_mmap(size_t size)
|
||||||
{
|
{
|
||||||
return chunk_alloc_mmap_internal(size, false);
|
|
||||||
|
return (chunk_alloc_mmap_internal(size, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
chunk_alloc_mmap_noreserve(size_t size)
|
chunk_alloc_mmap_noreserve(size_t size)
|
||||||
{
|
{
|
||||||
return chunk_alloc_mmap_internal(size, true);
|
|
||||||
|
return (chunk_alloc_mmap_internal(size, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -184,6 +184,24 @@ chunk_dealloc_swap_record(void *chunk, size_t size)
|
|||||||
return (node);
|
return (node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
chunk_in_swap(void *chunk)
|
||||||
|
{
|
||||||
|
bool ret;
|
||||||
|
|
||||||
|
assert(swap_enabled);
|
||||||
|
|
||||||
|
malloc_mutex_lock(&swap_mtx);
|
||||||
|
if ((uintptr_t)chunk >= (uintptr_t)swap_base
|
||||||
|
&& (uintptr_t)chunk < (uintptr_t)swap_max)
|
||||||
|
ret = true;
|
||||||
|
else
|
||||||
|
ret = false;
|
||||||
|
malloc_mutex_unlock(&swap_mtx);
|
||||||
|
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
chunk_dealloc_swap(void *chunk, size_t size)
|
chunk_dealloc_swap(void *chunk, size_t size)
|
||||||
{
|
{
|
||||||
@@ -219,15 +237,15 @@ chunk_dealloc_swap(void *chunk, size_t size)
|
|||||||
} else
|
} else
|
||||||
madvise(chunk, size, MADV_DONTNEED);
|
madvise(chunk, size, MADV_DONTNEED);
|
||||||
|
|
||||||
|
#ifdef JEMALLOC_STATS
|
||||||
|
swap_avail += size;
|
||||||
|
#endif
|
||||||
ret = false;
|
ret = false;
|
||||||
goto RETURN;
|
goto RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = true;
|
ret = true;
|
||||||
RETURN:
|
RETURN:
|
||||||
#ifdef JEMALLOC_STATS
|
|
||||||
swap_avail += size;
|
|
||||||
#endif
|
|
||||||
malloc_mutex_unlock(&swap_mtx);
|
malloc_mutex_unlock(&swap_mtx);
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ ckh_isearch(ckh_t *ckh, const void *key)
|
|||||||
size_t hash1, hash2, bucket, cell;
|
size_t hash1, hash2, bucket, cell;
|
||||||
|
|
||||||
assert(ckh != NULL);
|
assert(ckh != NULL);
|
||||||
assert(ckh->magic = CKH_MAGIG);
|
assert(ckh->magic == CKH_MAGIC);
|
||||||
|
|
||||||
ckh->hash(key, ckh->lg_curbuckets, &hash1, &hash2);
|
ckh->hash(key, ckh->lg_curbuckets, &hash1, &hash2);
|
||||||
|
|
||||||
@@ -383,7 +383,7 @@ ckh_new(ckh_t *ckh, size_t minitems, ckh_hash_t *hash, ckh_keycomp_t *keycomp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef JEMALLOC_DEBUG
|
#ifdef JEMALLOC_DEBUG
|
||||||
ckh->magic = CKH_MAGIG;
|
ckh->magic = CKH_MAGIC;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ret = false;
|
ret = false;
|
||||||
@@ -396,7 +396,7 @@ ckh_delete(ckh_t *ckh)
|
|||||||
{
|
{
|
||||||
|
|
||||||
assert(ckh != NULL);
|
assert(ckh != NULL);
|
||||||
assert(ckh->magic = CKH_MAGIG);
|
assert(ckh->magic == CKH_MAGIC);
|
||||||
|
|
||||||
#ifdef CKH_VERBOSE
|
#ifdef CKH_VERBOSE
|
||||||
malloc_printf(
|
malloc_printf(
|
||||||
@@ -421,7 +421,7 @@ ckh_count(ckh_t *ckh)
|
|||||||
{
|
{
|
||||||
|
|
||||||
assert(ckh != NULL);
|
assert(ckh != NULL);
|
||||||
assert(ckh->magic = CKH_MAGIG);
|
assert(ckh->magic == CKH_MAGIC);
|
||||||
|
|
||||||
return (ckh->count);
|
return (ckh->count);
|
||||||
}
|
}
|
||||||
@@ -452,7 +452,7 @@ ckh_insert(ckh_t *ckh, const void *key, const void *data)
|
|||||||
bool ret;
|
bool ret;
|
||||||
|
|
||||||
assert(ckh != NULL);
|
assert(ckh != NULL);
|
||||||
assert(ckh->magic = CKH_MAGIG);
|
assert(ckh->magic == CKH_MAGIC);
|
||||||
assert(ckh_search(ckh, key, NULL, NULL));
|
assert(ckh_search(ckh, key, NULL, NULL));
|
||||||
|
|
||||||
#ifdef CKH_COUNT
|
#ifdef CKH_COUNT
|
||||||
@@ -477,7 +477,7 @@ ckh_remove(ckh_t *ckh, const void *searchkey, void **key, void **data)
|
|||||||
size_t cell;
|
size_t cell;
|
||||||
|
|
||||||
assert(ckh != NULL);
|
assert(ckh != NULL);
|
||||||
assert(ckh->magic = CKH_MAGIG);
|
assert(ckh->magic == CKH_MAGIC);
|
||||||
|
|
||||||
cell = ckh_isearch(ckh, searchkey);
|
cell = ckh_isearch(ckh, searchkey);
|
||||||
if (cell != SIZE_T_MAX) {
|
if (cell != SIZE_T_MAX) {
|
||||||
@@ -509,7 +509,7 @@ ckh_search(ckh_t *ckh, const void *searchkey, void **key, void **data)
|
|||||||
size_t cell;
|
size_t cell;
|
||||||
|
|
||||||
assert(ckh != NULL);
|
assert(ckh != NULL);
|
||||||
assert(ckh->magic = CKH_MAGIG);
|
assert(ckh->magic == CKH_MAGIC);
|
||||||
|
|
||||||
cell = ckh_isearch(ckh, searchkey);
|
cell = ckh_isearch(ckh, searchkey);
|
||||||
if (cell != SIZE_T_MAX) {
|
if (cell != SIZE_T_MAX) {
|
||||||
|
|||||||
@@ -4,6 +4,13 @@
|
|||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
/* Data. */
|
/* Data. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ctl_mtx protects the following:
|
||||||
|
* - ctl_stats.*
|
||||||
|
* - opt_prof_active
|
||||||
|
* - swap_enabled
|
||||||
|
* - swap_prezeroed
|
||||||
|
*/
|
||||||
static malloc_mutex_t ctl_mtx;
|
static malloc_mutex_t ctl_mtx;
|
||||||
static bool ctl_initialized;
|
static bool ctl_initialized;
|
||||||
static uint64_t ctl_epoch;
|
static uint64_t ctl_epoch;
|
||||||
@@ -44,7 +51,9 @@ CTL_PROTO(tcache_flush)
|
|||||||
CTL_PROTO(thread_arena)
|
CTL_PROTO(thread_arena)
|
||||||
#ifdef JEMALLOC_STATS
|
#ifdef JEMALLOC_STATS
|
||||||
CTL_PROTO(thread_allocated)
|
CTL_PROTO(thread_allocated)
|
||||||
|
CTL_PROTO(thread_allocatedp)
|
||||||
CTL_PROTO(thread_deallocated)
|
CTL_PROTO(thread_deallocated)
|
||||||
|
CTL_PROTO(thread_deallocatedp)
|
||||||
#endif
|
#endif
|
||||||
CTL_PROTO(config_debug)
|
CTL_PROTO(config_debug)
|
||||||
CTL_PROTO(config_dss)
|
CTL_PROTO(config_dss)
|
||||||
@@ -223,7 +232,9 @@ static const ctl_node_t thread_node[] = {
|
|||||||
#ifdef JEMALLOC_STATS
|
#ifdef JEMALLOC_STATS
|
||||||
,
|
,
|
||||||
{NAME("allocated"), CTL(thread_allocated)},
|
{NAME("allocated"), CTL(thread_allocated)},
|
||||||
{NAME("deallocated"), CTL(thread_deallocated)}
|
{NAME("allocatedp"), CTL(thread_allocatedp)},
|
||||||
|
{NAME("deallocated"), CTL(thread_deallocated)},
|
||||||
|
{NAME("deallocatedp"), CTL(thread_deallocatedp)}
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -680,7 +691,9 @@ ctl_refresh(void)
|
|||||||
static bool
|
static bool
|
||||||
ctl_init(void)
|
ctl_init(void)
|
||||||
{
|
{
|
||||||
|
bool ret;
|
||||||
|
|
||||||
|
malloc_mutex_lock(&ctl_mtx);
|
||||||
if (ctl_initialized == false) {
|
if (ctl_initialized == false) {
|
||||||
#ifdef JEMALLOC_STATS
|
#ifdef JEMALLOC_STATS
|
||||||
unsigned i;
|
unsigned i;
|
||||||
@@ -692,8 +705,10 @@ ctl_init(void)
|
|||||||
*/
|
*/
|
||||||
ctl_stats.arenas = (ctl_arena_stats_t *)base_alloc(
|
ctl_stats.arenas = (ctl_arena_stats_t *)base_alloc(
|
||||||
(narenas + 1) * sizeof(ctl_arena_stats_t));
|
(narenas + 1) * sizeof(ctl_arena_stats_t));
|
||||||
if (ctl_stats.arenas == NULL)
|
if (ctl_stats.arenas == NULL) {
|
||||||
return (true);
|
ret = true;
|
||||||
|
goto RETURN;
|
||||||
|
}
|
||||||
memset(ctl_stats.arenas, 0, (narenas + 1) *
|
memset(ctl_stats.arenas, 0, (narenas + 1) *
|
||||||
sizeof(ctl_arena_stats_t));
|
sizeof(ctl_arena_stats_t));
|
||||||
|
|
||||||
@@ -704,8 +719,10 @@ ctl_init(void)
|
|||||||
*/
|
*/
|
||||||
#ifdef JEMALLOC_STATS
|
#ifdef JEMALLOC_STATS
|
||||||
for (i = 0; i <= narenas; i++) {
|
for (i = 0; i <= narenas; i++) {
|
||||||
if (ctl_arena_init(&ctl_stats.arenas[i]))
|
if (ctl_arena_init(&ctl_stats.arenas[i])) {
|
||||||
return (true);
|
ret = true;
|
||||||
|
goto RETURN;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
ctl_stats.arenas[narenas].initialized = true;
|
ctl_stats.arenas[narenas].initialized = true;
|
||||||
@@ -715,7 +732,10 @@ ctl_init(void)
|
|||||||
ctl_initialized = true;
|
ctl_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (false);
|
ret = false;
|
||||||
|
RETURN:
|
||||||
|
malloc_mutex_unlock(&ctl_mtx);
|
||||||
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -825,8 +845,7 @@ ctl_byname(const char *name, void *oldp, size_t *oldlenp, void *newp,
|
|||||||
ctl_node_t const *nodes[CTL_MAX_DEPTH];
|
ctl_node_t const *nodes[CTL_MAX_DEPTH];
|
||||||
size_t mib[CTL_MAX_DEPTH];
|
size_t mib[CTL_MAX_DEPTH];
|
||||||
|
|
||||||
malloc_mutex_lock(&ctl_mtx);
|
if (ctl_initialized == false && ctl_init()) {
|
||||||
if (ctl_init()) {
|
|
||||||
ret = EAGAIN;
|
ret = EAGAIN;
|
||||||
goto RETURN;
|
goto RETURN;
|
||||||
}
|
}
|
||||||
@@ -841,10 +860,9 @@ ctl_byname(const char *name, void *oldp, size_t *oldlenp, void *newp,
|
|||||||
ret = ENOENT;
|
ret = ENOENT;
|
||||||
goto RETURN;
|
goto RETURN;
|
||||||
}
|
}
|
||||||
ret = nodes[depth-1]->ctl(mib, depth, oldp, oldlenp, newp, newlen);
|
|
||||||
|
|
||||||
|
ret = nodes[depth-1]->ctl(mib, depth, oldp, oldlenp, newp, newlen);
|
||||||
RETURN:
|
RETURN:
|
||||||
malloc_mutex_unlock(&ctl_mtx);
|
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -853,16 +871,13 @@ ctl_nametomib(const char *name, size_t *mibp, size_t *miblenp)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
malloc_mutex_lock(&ctl_mtx);
|
if (ctl_initialized == false && ctl_init()) {
|
||||||
if (ctl_init()) {
|
|
||||||
ret = EAGAIN;
|
ret = EAGAIN;
|
||||||
goto RETURN;
|
goto RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ctl_lookup(name, NULL, mibp, miblenp);
|
ret = ctl_lookup(name, NULL, mibp, miblenp);
|
||||||
|
|
||||||
RETURN:
|
RETURN:
|
||||||
malloc_mutex_unlock(&ctl_mtx);
|
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -874,8 +889,7 @@ ctl_bymib(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
|
|||||||
const ctl_node_t *node;
|
const ctl_node_t *node;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
malloc_mutex_lock(&ctl_mtx);
|
if (ctl_initialized == false && ctl_init()) {
|
||||||
if (ctl_init()) {
|
|
||||||
ret = EAGAIN;
|
ret = EAGAIN;
|
||||||
goto RETURN;
|
goto RETURN;
|
||||||
}
|
}
|
||||||
@@ -912,7 +926,6 @@ ctl_bymib(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
|
|||||||
ret = node->ctl(mib, miblen, oldp, oldlenp, newp, newlen);
|
ret = node->ctl(mib, miblen, oldp, oldlenp, newp, newlen);
|
||||||
|
|
||||||
RETURN:
|
RETURN:
|
||||||
malloc_mutex_unlock(&ctl_mtx);
|
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -975,6 +988,29 @@ ctl_boot(void)
|
|||||||
|
|
||||||
#define CTL_RO_GEN(n, v, t) \
|
#define CTL_RO_GEN(n, v, t) \
|
||||||
static int \
|
static int \
|
||||||
|
n##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, \
|
||||||
|
void *newp, size_t newlen) \
|
||||||
|
{ \
|
||||||
|
int ret; \
|
||||||
|
t oldval; \
|
||||||
|
\
|
||||||
|
malloc_mutex_lock(&ctl_mtx); \
|
||||||
|
READONLY(); \
|
||||||
|
oldval = v; \
|
||||||
|
READ(oldval, t); \
|
||||||
|
\
|
||||||
|
ret = 0; \
|
||||||
|
RETURN: \
|
||||||
|
malloc_mutex_unlock(&ctl_mtx); \
|
||||||
|
return (ret); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ctl_mtx is not acquired, under the assumption that no pertinent data will
|
||||||
|
* mutate during the call.
|
||||||
|
*/
|
||||||
|
#define CTL_RO_NL_GEN(n, v, t) \
|
||||||
|
static int \
|
||||||
n##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, \
|
n##_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, \
|
||||||
void *newp, size_t newlen) \
|
void *newp, size_t newlen) \
|
||||||
{ \
|
{ \
|
||||||
@@ -1024,7 +1060,7 @@ RETURN: \
|
|||||||
return (ret); \
|
return (ret); \
|
||||||
}
|
}
|
||||||
|
|
||||||
CTL_RO_GEN(version, JEMALLOC_VERSION, const char *)
|
CTL_RO_NL_GEN(version, JEMALLOC_VERSION, const char *)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
epoch_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
|
epoch_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
|
||||||
@@ -1033,6 +1069,7 @@ epoch_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
|
|||||||
int ret;
|
int ret;
|
||||||
uint64_t newval;
|
uint64_t newval;
|
||||||
|
|
||||||
|
malloc_mutex_lock(&ctl_mtx);
|
||||||
newval = 0;
|
newval = 0;
|
||||||
WRITE(newval, uint64_t);
|
WRITE(newval, uint64_t);
|
||||||
if (newval != 0)
|
if (newval != 0)
|
||||||
@@ -1041,6 +1078,7 @@ epoch_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
|
|||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
RETURN:
|
RETURN:
|
||||||
|
malloc_mutex_unlock(&ctl_mtx);
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1076,8 +1114,8 @@ thread_arena_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
|
|||||||
unsigned newind, oldind;
|
unsigned newind, oldind;
|
||||||
|
|
||||||
newind = oldind = choose_arena()->ind;
|
newind = oldind = choose_arena()->ind;
|
||||||
WRITE(oldind, unsigned);
|
WRITE(newind, unsigned);
|
||||||
READ(newind, unsigned);
|
READ(oldind, unsigned);
|
||||||
if (newind != oldind) {
|
if (newind != oldind) {
|
||||||
arena_t *arena;
|
arena_t *arena;
|
||||||
|
|
||||||
@@ -1099,6 +1137,11 @@ thread_arena_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
|
|||||||
|
|
||||||
/* Set new arena association. */
|
/* Set new arena association. */
|
||||||
ARENA_SET(arena);
|
ARENA_SET(arena);
|
||||||
|
{
|
||||||
|
tcache_t *tcache = TCACHE_GET();
|
||||||
|
if (tcache != NULL)
|
||||||
|
tcache->arena = arena;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
@@ -1107,8 +1150,10 @@ RETURN:
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef JEMALLOC_STATS
|
#ifdef JEMALLOC_STATS
|
||||||
CTL_RO_GEN(thread_allocated, ALLOCATED_GET(), uint64_t);
|
CTL_RO_NL_GEN(thread_allocated, ALLOCATED_GET(), uint64_t);
|
||||||
CTL_RO_GEN(thread_deallocated, DEALLOCATED_GET(), uint64_t);
|
CTL_RO_NL_GEN(thread_allocatedp, ALLOCATEDP_GET(), uint64_t *);
|
||||||
|
CTL_RO_NL_GEN(thread_deallocated, DEALLOCATED_GET(), uint64_t);
|
||||||
|
CTL_RO_NL_GEN(thread_deallocatedp, DEALLOCATEDP_GET(), uint64_t *);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@@ -1205,48 +1250,48 @@ CTL_RO_FALSE_GEN(config_xmalloc)
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
CTL_RO_GEN(opt_abort, opt_abort, bool)
|
CTL_RO_NL_GEN(opt_abort, opt_abort, bool)
|
||||||
CTL_RO_GEN(opt_lg_qspace_max, opt_lg_qspace_max, size_t)
|
CTL_RO_NL_GEN(opt_lg_qspace_max, opt_lg_qspace_max, size_t)
|
||||||
CTL_RO_GEN(opt_lg_cspace_max, opt_lg_cspace_max, size_t)
|
CTL_RO_NL_GEN(opt_lg_cspace_max, opt_lg_cspace_max, size_t)
|
||||||
CTL_RO_GEN(opt_lg_chunk, opt_lg_chunk, size_t)
|
CTL_RO_NL_GEN(opt_lg_chunk, opt_lg_chunk, size_t)
|
||||||
CTL_RO_GEN(opt_narenas, opt_narenas, size_t)
|
CTL_RO_NL_GEN(opt_narenas, opt_narenas, size_t)
|
||||||
CTL_RO_GEN(opt_lg_dirty_mult, opt_lg_dirty_mult, ssize_t)
|
CTL_RO_NL_GEN(opt_lg_dirty_mult, opt_lg_dirty_mult, ssize_t)
|
||||||
CTL_RO_GEN(opt_stats_print, opt_stats_print, bool)
|
CTL_RO_NL_GEN(opt_stats_print, opt_stats_print, bool)
|
||||||
#ifdef JEMALLOC_FILL
|
#ifdef JEMALLOC_FILL
|
||||||
CTL_RO_GEN(opt_junk, opt_junk, bool)
|
CTL_RO_NL_GEN(opt_junk, opt_junk, bool)
|
||||||
CTL_RO_GEN(opt_zero, opt_zero, bool)
|
CTL_RO_NL_GEN(opt_zero, opt_zero, bool)
|
||||||
#endif
|
#endif
|
||||||
#ifdef JEMALLOC_SYSV
|
#ifdef JEMALLOC_SYSV
|
||||||
CTL_RO_GEN(opt_sysv, opt_sysv, bool)
|
CTL_RO_NL_GEN(opt_sysv, opt_sysv, bool)
|
||||||
#endif
|
#endif
|
||||||
#ifdef JEMALLOC_XMALLOC
|
#ifdef JEMALLOC_XMALLOC
|
||||||
CTL_RO_GEN(opt_xmalloc, opt_xmalloc, bool)
|
CTL_RO_NL_GEN(opt_xmalloc, opt_xmalloc, bool)
|
||||||
#endif
|
#endif
|
||||||
#ifdef JEMALLOC_TCACHE
|
#ifdef JEMALLOC_TCACHE
|
||||||
CTL_RO_GEN(opt_tcache, opt_tcache, bool)
|
CTL_RO_NL_GEN(opt_tcache, opt_tcache, bool)
|
||||||
CTL_RO_GEN(opt_lg_tcache_gc_sweep, opt_lg_tcache_gc_sweep, ssize_t)
|
CTL_RO_NL_GEN(opt_lg_tcache_gc_sweep, opt_lg_tcache_gc_sweep, ssize_t)
|
||||||
#endif
|
#endif
|
||||||
#ifdef JEMALLOC_PROF
|
#ifdef JEMALLOC_PROF
|
||||||
CTL_RO_GEN(opt_prof, opt_prof, bool)
|
CTL_RO_NL_GEN(opt_prof, opt_prof, bool)
|
||||||
CTL_RO_GEN(opt_prof_prefix, opt_prof_prefix, const char *)
|
CTL_RO_NL_GEN(opt_prof_prefix, opt_prof_prefix, const char *)
|
||||||
CTL_RO_GEN(opt_prof_active, opt_prof_active, bool)
|
CTL_RO_GEN(opt_prof_active, opt_prof_active, bool) /* Mutable. */
|
||||||
CTL_RO_GEN(opt_lg_prof_bt_max, opt_lg_prof_bt_max, size_t)
|
CTL_RO_NL_GEN(opt_lg_prof_bt_max, opt_lg_prof_bt_max, size_t)
|
||||||
CTL_RO_GEN(opt_lg_prof_sample, opt_lg_prof_sample, size_t)
|
CTL_RO_NL_GEN(opt_lg_prof_sample, opt_lg_prof_sample, size_t)
|
||||||
CTL_RO_GEN(opt_lg_prof_interval, opt_lg_prof_interval, ssize_t)
|
CTL_RO_NL_GEN(opt_lg_prof_interval, opt_lg_prof_interval, ssize_t)
|
||||||
CTL_RO_GEN(opt_prof_gdump, opt_prof_gdump, bool)
|
CTL_RO_NL_GEN(opt_prof_gdump, opt_prof_gdump, bool)
|
||||||
CTL_RO_GEN(opt_prof_leak, opt_prof_leak, bool)
|
CTL_RO_NL_GEN(opt_prof_leak, opt_prof_leak, bool)
|
||||||
CTL_RO_GEN(opt_prof_accum, opt_prof_accum, bool)
|
CTL_RO_NL_GEN(opt_prof_accum, opt_prof_accum, bool)
|
||||||
CTL_RO_GEN(opt_lg_prof_tcmax, opt_lg_prof_tcmax, ssize_t)
|
CTL_RO_NL_GEN(opt_lg_prof_tcmax, opt_lg_prof_tcmax, ssize_t)
|
||||||
#endif
|
#endif
|
||||||
#ifdef JEMALLOC_SWAP
|
#ifdef JEMALLOC_SWAP
|
||||||
CTL_RO_GEN(opt_overcommit, opt_overcommit, bool)
|
CTL_RO_NL_GEN(opt_overcommit, opt_overcommit, bool)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
CTL_RO_GEN(arenas_bin_i_size, arenas[0]->bins[mib[2]].reg_size, size_t)
|
CTL_RO_NL_GEN(arenas_bin_i_size, arenas[0]->bins[mib[2]].reg_size, size_t)
|
||||||
CTL_RO_GEN(arenas_bin_i_nregs, arenas[0]->bins[mib[2]].nregs, uint32_t)
|
CTL_RO_NL_GEN(arenas_bin_i_nregs, arenas[0]->bins[mib[2]].nregs, uint32_t)
|
||||||
CTL_RO_GEN(arenas_bin_i_run_size, arenas[0]->bins[mib[2]].run_size, size_t)
|
CTL_RO_NL_GEN(arenas_bin_i_run_size, arenas[0]->bins[mib[2]].run_size, size_t)
|
||||||
const ctl_node_t *
|
const ctl_node_t *
|
||||||
arenas_bin_i_index(const size_t *mib, size_t miblen, size_t i)
|
arenas_bin_i_index(const size_t *mib, size_t miblen, size_t i)
|
||||||
{
|
{
|
||||||
@@ -1256,7 +1301,7 @@ arenas_bin_i_index(const size_t *mib, size_t miblen, size_t i)
|
|||||||
return (super_arenas_bin_i_node);
|
return (super_arenas_bin_i_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
CTL_RO_GEN(arenas_lrun_i_size, ((mib[2]+1) << PAGE_SHIFT), size_t)
|
CTL_RO_NL_GEN(arenas_lrun_i_size, ((mib[2]+1) << PAGE_SHIFT), size_t)
|
||||||
const ctl_node_t *
|
const ctl_node_t *
|
||||||
arenas_lrun_i_index(const size_t *mib, size_t miblen, size_t i)
|
arenas_lrun_i_index(const size_t *mib, size_t miblen, size_t i)
|
||||||
{
|
{
|
||||||
@@ -1266,7 +1311,7 @@ arenas_lrun_i_index(const size_t *mib, size_t miblen, size_t i)
|
|||||||
return (super_arenas_lrun_i_node);
|
return (super_arenas_lrun_i_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
CTL_RO_GEN(arenas_narenas, narenas, unsigned)
|
CTL_RO_NL_GEN(arenas_narenas, narenas, unsigned)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
arenas_initialized_ctl(const size_t *mib, size_t miblen, void *oldp,
|
arenas_initialized_ctl(const size_t *mib, size_t miblen, void *oldp,
|
||||||
@@ -1275,6 +1320,7 @@ arenas_initialized_ctl(const size_t *mib, size_t miblen, void *oldp,
|
|||||||
int ret;
|
int ret;
|
||||||
unsigned nread, i;
|
unsigned nread, i;
|
||||||
|
|
||||||
|
malloc_mutex_lock(&ctl_mtx);
|
||||||
READONLY();
|
READONLY();
|
||||||
if (*oldlenp != narenas * sizeof(bool)) {
|
if (*oldlenp != narenas * sizeof(bool)) {
|
||||||
ret = EINVAL;
|
ret = EINVAL;
|
||||||
@@ -1289,36 +1335,37 @@ arenas_initialized_ctl(const size_t *mib, size_t miblen, void *oldp,
|
|||||||
((bool *)oldp)[i] = ctl_stats.arenas[i].initialized;
|
((bool *)oldp)[i] = ctl_stats.arenas[i].initialized;
|
||||||
|
|
||||||
RETURN:
|
RETURN:
|
||||||
|
malloc_mutex_unlock(&ctl_mtx);
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
CTL_RO_GEN(arenas_quantum, QUANTUM, size_t)
|
CTL_RO_NL_GEN(arenas_quantum, QUANTUM, size_t)
|
||||||
CTL_RO_GEN(arenas_cacheline, CACHELINE, size_t)
|
CTL_RO_NL_GEN(arenas_cacheline, CACHELINE, size_t)
|
||||||
CTL_RO_GEN(arenas_subpage, SUBPAGE, size_t)
|
CTL_RO_NL_GEN(arenas_subpage, SUBPAGE, size_t)
|
||||||
CTL_RO_GEN(arenas_pagesize, PAGE_SIZE, size_t)
|
CTL_RO_NL_GEN(arenas_pagesize, PAGE_SIZE, size_t)
|
||||||
CTL_RO_GEN(arenas_chunksize, chunksize, size_t)
|
CTL_RO_NL_GEN(arenas_chunksize, chunksize, size_t)
|
||||||
#ifdef JEMALLOC_TINY
|
#ifdef JEMALLOC_TINY
|
||||||
CTL_RO_GEN(arenas_tspace_min, (1U << LG_TINY_MIN), size_t)
|
CTL_RO_NL_GEN(arenas_tspace_min, (1U << LG_TINY_MIN), size_t)
|
||||||
CTL_RO_GEN(arenas_tspace_max, (qspace_min >> 1), size_t)
|
CTL_RO_NL_GEN(arenas_tspace_max, (qspace_min >> 1), size_t)
|
||||||
#endif
|
#endif
|
||||||
CTL_RO_GEN(arenas_qspace_min, qspace_min, size_t)
|
CTL_RO_NL_GEN(arenas_qspace_min, qspace_min, size_t)
|
||||||
CTL_RO_GEN(arenas_qspace_max, qspace_max, size_t)
|
CTL_RO_NL_GEN(arenas_qspace_max, qspace_max, size_t)
|
||||||
CTL_RO_GEN(arenas_cspace_min, cspace_min, size_t)
|
CTL_RO_NL_GEN(arenas_cspace_min, cspace_min, size_t)
|
||||||
CTL_RO_GEN(arenas_cspace_max, cspace_max, size_t)
|
CTL_RO_NL_GEN(arenas_cspace_max, cspace_max, size_t)
|
||||||
CTL_RO_GEN(arenas_sspace_min, sspace_min, size_t)
|
CTL_RO_NL_GEN(arenas_sspace_min, sspace_min, size_t)
|
||||||
CTL_RO_GEN(arenas_sspace_max, sspace_max, size_t)
|
CTL_RO_NL_GEN(arenas_sspace_max, sspace_max, size_t)
|
||||||
#ifdef JEMALLOC_TCACHE
|
#ifdef JEMALLOC_TCACHE
|
||||||
CTL_RO_GEN(arenas_tcache_max, tcache_maxclass, size_t)
|
CTL_RO_NL_GEN(arenas_tcache_max, tcache_maxclass, size_t)
|
||||||
#endif
|
#endif
|
||||||
CTL_RO_GEN(arenas_ntbins, ntbins, unsigned)
|
CTL_RO_NL_GEN(arenas_ntbins, ntbins, unsigned)
|
||||||
CTL_RO_GEN(arenas_nqbins, nqbins, unsigned)
|
CTL_RO_NL_GEN(arenas_nqbins, nqbins, unsigned)
|
||||||
CTL_RO_GEN(arenas_ncbins, ncbins, unsigned)
|
CTL_RO_NL_GEN(arenas_ncbins, ncbins, unsigned)
|
||||||
CTL_RO_GEN(arenas_nsbins, nsbins, unsigned)
|
CTL_RO_NL_GEN(arenas_nsbins, nsbins, unsigned)
|
||||||
CTL_RO_GEN(arenas_nbins, nbins, unsigned)
|
CTL_RO_NL_GEN(arenas_nbins, nbins, unsigned)
|
||||||
#ifdef JEMALLOC_TCACHE
|
#ifdef JEMALLOC_TCACHE
|
||||||
CTL_RO_GEN(arenas_nhbins, nhbins, unsigned)
|
CTL_RO_NL_GEN(arenas_nhbins, nhbins, unsigned)
|
||||||
#endif
|
#endif
|
||||||
CTL_RO_GEN(arenas_nlruns, nlclasses, size_t)
|
CTL_RO_NL_GEN(arenas_nlruns, nlclasses, size_t)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
arenas_purge_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
|
arenas_purge_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
|
||||||
@@ -1368,6 +1415,7 @@ prof_active_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
|
|||||||
int ret;
|
int ret;
|
||||||
bool oldval;
|
bool oldval;
|
||||||
|
|
||||||
|
malloc_mutex_lock(&ctl_mtx); /* Protect opt_prof_active. */
|
||||||
oldval = opt_prof_active;
|
oldval = opt_prof_active;
|
||||||
if (newp != NULL) {
|
if (newp != NULL) {
|
||||||
/*
|
/*
|
||||||
@@ -1382,6 +1430,7 @@ prof_active_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
|
|||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
RETURN:
|
RETURN:
|
||||||
|
malloc_mutex_unlock(&ctl_mtx);
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1405,7 +1454,7 @@ RETURN:
|
|||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
CTL_RO_GEN(prof_interval, prof_interval, uint64_t)
|
CTL_RO_NL_GEN(prof_interval, prof_interval, uint64_t)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@@ -1503,10 +1552,18 @@ CTL_RO_GEN(stats_arenas_i_purged, ctl_stats.arenas[mib[2]].astats.purged,
|
|||||||
const ctl_node_t *
|
const ctl_node_t *
|
||||||
stats_arenas_i_index(const size_t *mib, size_t miblen, size_t i)
|
stats_arenas_i_index(const size_t *mib, size_t miblen, size_t i)
|
||||||
{
|
{
|
||||||
|
const ctl_node_t * ret;
|
||||||
|
|
||||||
if (ctl_stats.arenas[i].initialized == false)
|
malloc_mutex_lock(&ctl_mtx);
|
||||||
return (NULL);
|
if (ctl_stats.arenas[i].initialized == false) {
|
||||||
return (super_stats_arenas_i_node);
|
ret = NULL;
|
||||||
|
goto RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = super_stats_arenas_i_node;
|
||||||
|
RETURN:
|
||||||
|
malloc_mutex_unlock(&ctl_mtx);
|
||||||
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef JEMALLOC_STATS
|
#ifdef JEMALLOC_STATS
|
||||||
@@ -1528,6 +1585,7 @@ swap_prezeroed_ctl(const size_t *mib, size_t miblen, void *oldp,
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
malloc_mutex_lock(&ctl_mtx);
|
||||||
if (swap_enabled) {
|
if (swap_enabled) {
|
||||||
READONLY();
|
READONLY();
|
||||||
} else {
|
} else {
|
||||||
@@ -1545,6 +1603,7 @@ swap_prezeroed_ctl(const size_t *mib, size_t miblen, void *oldp,
|
|||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
RETURN:
|
RETURN:
|
||||||
|
malloc_mutex_unlock(&ctl_mtx);
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1556,6 +1615,7 @@ swap_fds_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
malloc_mutex_lock(&ctl_mtx);
|
||||||
if (swap_enabled) {
|
if (swap_enabled) {
|
||||||
READONLY();
|
READONLY();
|
||||||
} else if (newp != NULL) {
|
} else if (newp != NULL) {
|
||||||
@@ -1586,6 +1646,7 @@ swap_fds_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
|
|||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
RETURN:
|
RETURN:
|
||||||
|
malloc_mutex_unlock(&ctl_mtx);
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ huge_palloc(size_t size, size_t alignment, bool zero)
|
|||||||
* alignment, in order to assure the alignment can be achieved, then
|
* alignment, in order to assure the alignment can be achieved, then
|
||||||
* unmap leading and trailing chunks.
|
* unmap leading and trailing chunks.
|
||||||
*/
|
*/
|
||||||
assert(alignment >= chunksize);
|
assert(alignment > chunksize);
|
||||||
|
|
||||||
chunk_size = CHUNK_CEILING(size);
|
chunk_size = CHUNK_CEILING(size);
|
||||||
|
|
||||||
@@ -192,7 +192,7 @@ huge_ralloc(void *ptr, size_t oldsize, size_t size, size_t extra,
|
|||||||
* different size class. In that case, fall back to allocating new
|
* different size class. In that case, fall back to allocating new
|
||||||
* space and copying.
|
* space and copying.
|
||||||
*/
|
*/
|
||||||
if (alignment != 0)
|
if (alignment > chunksize)
|
||||||
ret = huge_palloc(size + extra, alignment, zero);
|
ret = huge_palloc(size + extra, alignment, zero);
|
||||||
else
|
else
|
||||||
ret = huge_malloc(size + extra, zero);
|
ret = huge_malloc(size + extra, zero);
|
||||||
@@ -201,7 +201,7 @@ huge_ralloc(void *ptr, size_t oldsize, size_t size, size_t extra,
|
|||||||
if (extra == 0)
|
if (extra == 0)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
/* Try again, this time without extra. */
|
/* Try again, this time without extra. */
|
||||||
if (alignment != 0)
|
if (alignment > chunksize)
|
||||||
ret = huge_palloc(size, alignment, zero);
|
ret = huge_palloc(size, alignment, zero);
|
||||||
else
|
else
|
||||||
ret = huge_malloc(size, zero);
|
ret = huge_malloc(size, zero);
|
||||||
@@ -215,13 +215,56 @@ huge_ralloc(void *ptr, size_t oldsize, size_t size, size_t extra,
|
|||||||
* expectation that the extra bytes will be reliably preserved.
|
* expectation that the extra bytes will be reliably preserved.
|
||||||
*/
|
*/
|
||||||
copysize = (size < oldsize) ? size : oldsize;
|
copysize = (size < oldsize) ? size : oldsize;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use mremap(2) if this is a huge-->huge reallocation, and neither the
|
||||||
|
* source nor the destination are in swap or dss.
|
||||||
|
*/
|
||||||
|
#ifdef JEMALLOC_MREMAP_FIXED
|
||||||
|
if (oldsize >= chunksize
|
||||||
|
# ifdef JEMALLOC_SWAP
|
||||||
|
&& (swap_enabled == false || (chunk_in_swap(ptr) == false &&
|
||||||
|
chunk_in_swap(ret) == false))
|
||||||
|
# endif
|
||||||
|
# ifdef JEMALLOC_DSS
|
||||||
|
&& chunk_in_dss(ptr) == false && chunk_in_dss(ret) == false
|
||||||
|
# endif
|
||||||
|
) {
|
||||||
|
size_t newsize = huge_salloc(ret);
|
||||||
|
|
||||||
|
if (mremap(ptr, oldsize, newsize, MREMAP_MAYMOVE|MREMAP_FIXED,
|
||||||
|
ret) == MAP_FAILED) {
|
||||||
|
/*
|
||||||
|
* Assuming no chunk management bugs in the allocator,
|
||||||
|
* the only documented way an error can occur here is
|
||||||
|
* if the application changed the map type for a
|
||||||
|
* portion of the old allocation. This is firmly in
|
||||||
|
* undefined behavior territory, so write a diagnostic
|
||||||
|
* message, and optionally abort.
|
||||||
|
*/
|
||||||
|
char buf[BUFERROR_BUF];
|
||||||
|
|
||||||
|
buferror(errno, buf, sizeof(buf));
|
||||||
|
malloc_write("<jemalloc>: Error in mremap(): ");
|
||||||
|
malloc_write(buf);
|
||||||
|
malloc_write("\n");
|
||||||
|
if (opt_abort)
|
||||||
|
abort();
|
||||||
memcpy(ret, ptr, copysize);
|
memcpy(ret, ptr, copysize);
|
||||||
idalloc(ptr);
|
idalloc(ptr);
|
||||||
|
} else
|
||||||
|
huge_dalloc(ptr, false);
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
memcpy(ret, ptr, copysize);
|
||||||
|
idalloc(ptr);
|
||||||
|
}
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
huge_dalloc(void *ptr)
|
huge_dalloc(void *ptr, bool unmap)
|
||||||
{
|
{
|
||||||
extent_node_t *node, key;
|
extent_node_t *node, key;
|
||||||
|
|
||||||
@@ -241,6 +284,7 @@ huge_dalloc(void *ptr)
|
|||||||
|
|
||||||
malloc_mutex_unlock(&huge_mtx);
|
malloc_mutex_unlock(&huge_mtx);
|
||||||
|
|
||||||
|
if (unmap) {
|
||||||
/* Unmap chunk. */
|
/* Unmap chunk. */
|
||||||
#ifdef JEMALLOC_FILL
|
#ifdef JEMALLOC_FILL
|
||||||
#if (defined(JEMALLOC_SWAP) || defined(JEMALLOC_DSS))
|
#if (defined(JEMALLOC_SWAP) || defined(JEMALLOC_DSS))
|
||||||
@@ -249,6 +293,7 @@ huge_dalloc(void *ptr)
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
chunk_dealloc(node->addr, node->size);
|
chunk_dealloc(node->addr, node->size);
|
||||||
|
}
|
||||||
|
|
||||||
base_node_dealloc(node);
|
base_node_dealloc(node);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -213,6 +213,28 @@ stats_print_atexit(void)
|
|||||||
JEMALLOC_P(malloc_stats_print)(NULL, NULL, NULL);
|
JEMALLOC_P(malloc_stats_print)(NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (defined(JEMALLOC_STATS) && defined(NO_TLS))
|
||||||
|
thread_allocated_t *
|
||||||
|
thread_allocated_get_hard(void)
|
||||||
|
{
|
||||||
|
thread_allocated_t *thread_allocated = (thread_allocated_t *)
|
||||||
|
imalloc(sizeof(thread_allocated_t));
|
||||||
|
if (thread_allocated == NULL) {
|
||||||
|
static thread_allocated_t static_thread_allocated = {0, 0};
|
||||||
|
malloc_write("<jemalloc>: Error allocating TSD;"
|
||||||
|
" mallctl(\"thread.{de,}allocated[p]\", ...)"
|
||||||
|
" will be inaccurate\n");
|
||||||
|
if (opt_abort)
|
||||||
|
abort();
|
||||||
|
return (&static_thread_allocated);
|
||||||
|
}
|
||||||
|
pthread_setspecific(thread_allocated_tsd, thread_allocated);
|
||||||
|
thread_allocated->allocated = 0;
|
||||||
|
thread_allocated->deallocated = 0;
|
||||||
|
return (thread_allocated);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* End miscellaneous support functions.
|
* End miscellaneous support functions.
|
||||||
*/
|
*/
|
||||||
@@ -421,8 +443,8 @@ malloc_conf_init(void)
|
|||||||
if ((opts = getenv(envname)) != NULL) {
|
if ((opts = getenv(envname)) != NULL) {
|
||||||
/*
|
/*
|
||||||
* Do nothing; opts is already initialized to
|
* Do nothing; opts is already initialized to
|
||||||
* the value of the JEMALLOC_OPTIONS
|
* the value of the MALLOC_CONF environment
|
||||||
* environment variable.
|
* variable.
|
||||||
*/
|
*/
|
||||||
} else {
|
} else {
|
||||||
/* No configuration specified. */
|
/* No configuration specified. */
|
||||||
|
|||||||
@@ -255,6 +255,7 @@ prof_backtrace(prof_bt_t *bt, unsigned nignore, unsigned max)
|
|||||||
} else \
|
} else \
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
assert(nignore <= 3);
|
||||||
assert(max <= (1U << opt_lg_prof_bt_max));
|
assert(max <= (1U << opt_lg_prof_bt_max));
|
||||||
|
|
||||||
BT_FRAME(0)
|
BT_FRAME(0)
|
||||||
@@ -398,7 +399,7 @@ prof_backtrace(prof_bt_t *bt, unsigned nignore, unsigned max)
|
|||||||
BT_FRAME(126)
|
BT_FRAME(126)
|
||||||
BT_FRAME(127)
|
BT_FRAME(127)
|
||||||
|
|
||||||
/* Extras to compensate for NIGNORE. */
|
/* Extras to compensate for nignore. */
|
||||||
BT_FRAME(128)
|
BT_FRAME(128)
|
||||||
BT_FRAME(129)
|
BT_FRAME(129)
|
||||||
BT_FRAME(130)
|
BT_FRAME(130)
|
||||||
@@ -431,6 +432,7 @@ prof_lookup(prof_bt_t *bt)
|
|||||||
prof_ctx_t *p;
|
prof_ctx_t *p;
|
||||||
void *v;
|
void *v;
|
||||||
} ctx;
|
} ctx;
|
||||||
|
bool new_ctx;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This thread's cache lacks bt. Look for it in the global
|
* This thread's cache lacks bt. Look for it in the global
|
||||||
@@ -467,12 +469,14 @@ prof_lookup(prof_bt_t *bt)
|
|||||||
idalloc(ctx.v);
|
idalloc(ctx.v);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
* Acquire ctx's lock before releasing bt2ctx_mtx, in order to
|
* Artificially raise curobjs, in order to avoid a race
|
||||||
* avoid a race condition with prof_ctx_destroy().
|
* condition with prof_ctx_merge()/prof_ctx_destroy().
|
||||||
*/
|
*/
|
||||||
malloc_mutex_lock(&ctx.p->lock);
|
ctx.p->cnt_merged.curobjs++;
|
||||||
|
new_ctx = true;
|
||||||
|
} else
|
||||||
|
new_ctx = false;
|
||||||
prof_leave();
|
prof_leave();
|
||||||
|
|
||||||
/* Link a prof_thd_cnt_t into ctx for this thread. */
|
/* Link a prof_thd_cnt_t into ctx for this thread. */
|
||||||
@@ -496,8 +500,14 @@ prof_lookup(prof_bt_t *bt)
|
|||||||
opt_lg_prof_tcmax));
|
opt_lg_prof_tcmax));
|
||||||
/* Allocate and partially initialize a new cnt. */
|
/* Allocate and partially initialize a new cnt. */
|
||||||
ret.v = imalloc(sizeof(prof_thr_cnt_t));
|
ret.v = imalloc(sizeof(prof_thr_cnt_t));
|
||||||
if (ret.p == NULL)
|
if (ret.p == NULL) {
|
||||||
|
if (new_ctx) {
|
||||||
|
malloc_mutex_lock(&ctx.p->lock);
|
||||||
|
ctx.p->cnt_merged.curobjs--;
|
||||||
|
malloc_mutex_unlock(&ctx.p->lock);
|
||||||
|
}
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
}
|
||||||
ql_elm_new(ret.p, cnts_link);
|
ql_elm_new(ret.p, cnts_link);
|
||||||
ql_elm_new(ret.p, lru_link);
|
ql_elm_new(ret.p, lru_link);
|
||||||
}
|
}
|
||||||
@@ -506,11 +516,19 @@ prof_lookup(prof_bt_t *bt)
|
|||||||
ret.p->epoch = 0;
|
ret.p->epoch = 0;
|
||||||
memset(&ret.p->cnts, 0, sizeof(prof_cnt_t));
|
memset(&ret.p->cnts, 0, sizeof(prof_cnt_t));
|
||||||
if (ckh_insert(&prof_tdata->bt2cnt, btkey.v, ret.v)) {
|
if (ckh_insert(&prof_tdata->bt2cnt, btkey.v, ret.v)) {
|
||||||
|
if (new_ctx) {
|
||||||
|
malloc_mutex_lock(&ctx.p->lock);
|
||||||
|
ctx.p->cnt_merged.curobjs--;
|
||||||
|
malloc_mutex_unlock(&ctx.p->lock);
|
||||||
|
}
|
||||||
idalloc(ret.v);
|
idalloc(ret.v);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
ql_head_insert(&prof_tdata->lru_ql, ret.p, lru_link);
|
ql_head_insert(&prof_tdata->lru_ql, ret.p, lru_link);
|
||||||
|
malloc_mutex_lock(&ctx.p->lock);
|
||||||
ql_tail_insert(&ctx.p->cnts_ql, ret.p, cnts_link);
|
ql_tail_insert(&ctx.p->cnts_ql, ret.p, cnts_link);
|
||||||
|
if (new_ctx)
|
||||||
|
ctx.p->cnt_merged.curobjs--;
|
||||||
malloc_mutex_unlock(&ctx.p->lock);
|
malloc_mutex_unlock(&ctx.p->lock);
|
||||||
} else {
|
} else {
|
||||||
/* Move ret to the front of the LRU. */
|
/* Move ret to the front of the LRU. */
|
||||||
@@ -625,11 +643,14 @@ prof_ctx_destroy(prof_ctx_t *ctx)
|
|||||||
/*
|
/*
|
||||||
* Check that ctx is still unused by any thread cache before destroying
|
* Check that ctx is still unused by any thread cache before destroying
|
||||||
* it. prof_lookup() interlocks bt2ctx_mtx and ctx->lock in order to
|
* it. prof_lookup() interlocks bt2ctx_mtx and ctx->lock in order to
|
||||||
* avoid a race condition with this function.
|
* avoid a race condition with this function, and prof_ctx_merge()
|
||||||
|
* artificially raises ctx->cnt_merged.curobjs in order to avoid a race
|
||||||
|
* between the main body of prof_ctx_merge() and entry into this
|
||||||
|
* function.
|
||||||
*/
|
*/
|
||||||
prof_enter();
|
prof_enter();
|
||||||
malloc_mutex_lock(&ctx->lock);
|
malloc_mutex_lock(&ctx->lock);
|
||||||
if (ql_first(&ctx->cnts_ql) == NULL && ctx->cnt_merged.curobjs == 0) {
|
if (ql_first(&ctx->cnts_ql) == NULL && ctx->cnt_merged.curobjs == 1) {
|
||||||
assert(ctx->cnt_merged.curbytes == 0);
|
assert(ctx->cnt_merged.curbytes == 0);
|
||||||
assert(ctx->cnt_merged.accumobjs == 0);
|
assert(ctx->cnt_merged.accumobjs == 0);
|
||||||
assert(ctx->cnt_merged.accumbytes == 0);
|
assert(ctx->cnt_merged.accumbytes == 0);
|
||||||
@@ -642,6 +663,8 @@ prof_ctx_destroy(prof_ctx_t *ctx)
|
|||||||
malloc_mutex_destroy(&ctx->lock);
|
malloc_mutex_destroy(&ctx->lock);
|
||||||
idalloc(ctx);
|
idalloc(ctx);
|
||||||
} else {
|
} else {
|
||||||
|
/* Compensate for increment in prof_ctx_merge(). */
|
||||||
|
ctx->cnt_merged.curobjs--;
|
||||||
malloc_mutex_unlock(&ctx->lock);
|
malloc_mutex_unlock(&ctx->lock);
|
||||||
prof_leave();
|
prof_leave();
|
||||||
}
|
}
|
||||||
@@ -660,9 +683,23 @@ prof_ctx_merge(prof_ctx_t *ctx, prof_thr_cnt_t *cnt)
|
|||||||
ctx->cnt_merged.accumbytes += cnt->cnts.accumbytes;
|
ctx->cnt_merged.accumbytes += cnt->cnts.accumbytes;
|
||||||
ql_remove(&ctx->cnts_ql, cnt, cnts_link);
|
ql_remove(&ctx->cnts_ql, cnt, cnts_link);
|
||||||
if (opt_prof_accum == false && ql_first(&ctx->cnts_ql) == NULL &&
|
if (opt_prof_accum == false && ql_first(&ctx->cnts_ql) == NULL &&
|
||||||
ctx->cnt_merged.curobjs == 0)
|
ctx->cnt_merged.curobjs == 0) {
|
||||||
|
/*
|
||||||
|
* Artificially raise ctx->cnt_merged.curobjs in order to keep
|
||||||
|
* another thread from winning the race to destroy ctx while
|
||||||
|
* this one has ctx->lock dropped. Without this, it would be
|
||||||
|
* possible for another thread to:
|
||||||
|
*
|
||||||
|
* 1) Sample an allocation associated with ctx.
|
||||||
|
* 2) Deallocate the sampled object.
|
||||||
|
* 3) Successfully prof_ctx_destroy(ctx).
|
||||||
|
*
|
||||||
|
* The result would be that ctx no longer exists by the time
|
||||||
|
* this thread accesses it in prof_ctx_destroy().
|
||||||
|
*/
|
||||||
|
ctx->cnt_merged.curobjs++;
|
||||||
destroy = true;
|
destroy = true;
|
||||||
else
|
} else
|
||||||
destroy = false;
|
destroy = false;
|
||||||
malloc_mutex_unlock(&ctx->lock);
|
malloc_mutex_unlock(&ctx->lock);
|
||||||
if (destroy)
|
if (destroy)
|
||||||
|
|||||||
@@ -58,6 +58,9 @@ tcache_bin_flush_small(tcache_bin_t *tbin, size_t binind, unsigned rem
|
|||||||
void *flush, *deferred, *ptr;
|
void *flush, *deferred, *ptr;
|
||||||
unsigned i, nflush, ndeferred;
|
unsigned i, nflush, ndeferred;
|
||||||
bool first_pass;
|
bool first_pass;
|
||||||
|
#ifdef JEMALLOC_STATS
|
||||||
|
bool merged_stats = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
assert(binind < nbins);
|
assert(binind < nbins);
|
||||||
assert(rem <= tbin->ncached);
|
assert(rem <= tbin->ncached);
|
||||||
@@ -82,6 +85,8 @@ tcache_bin_flush_small(tcache_bin_t *tbin, size_t binind, unsigned rem
|
|||||||
malloc_mutex_lock(&bin->lock);
|
malloc_mutex_lock(&bin->lock);
|
||||||
#ifdef JEMALLOC_STATS
|
#ifdef JEMALLOC_STATS
|
||||||
if (arena == tcache->arena) {
|
if (arena == tcache->arena) {
|
||||||
|
assert(merged_stats == false);
|
||||||
|
merged_stats = true;
|
||||||
bin->stats.nflushes++;
|
bin->stats.nflushes++;
|
||||||
bin->stats.nrequests += tbin->tstats.nrequests;
|
bin->stats.nrequests += tbin->tstats.nrequests;
|
||||||
tbin->tstats.nrequests = 0;
|
tbin->tstats.nrequests = 0;
|
||||||
@@ -119,6 +124,20 @@ tcache_bin_flush_small(tcache_bin_t *tbin, size_t binind, unsigned rem
|
|||||||
first_pass = false;
|
first_pass = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef JEMALLOC_STATS
|
||||||
|
if (merged_stats == false) {
|
||||||
|
/*
|
||||||
|
* The flush loop didn't happen to flush to this thread's
|
||||||
|
* arena, so the stats didn't get merged. Manually do so now.
|
||||||
|
*/
|
||||||
|
arena_bin_t *bin = &tcache->arena->bins[binind];
|
||||||
|
malloc_mutex_lock(&bin->lock);
|
||||||
|
bin->stats.nflushes++;
|
||||||
|
bin->stats.nrequests += tbin->tstats.nrequests;
|
||||||
|
tbin->tstats.nrequests = 0;
|
||||||
|
malloc_mutex_unlock(&bin->lock);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
tbin->ncached = rem;
|
tbin->ncached = rem;
|
||||||
if (tbin->ncached < tbin->low_water)
|
if (tbin->ncached < tbin->low_water)
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ thread_start(void *arg)
|
|||||||
int err;
|
int err;
|
||||||
void *p;
|
void *p;
|
||||||
uint64_t a0, a1, d0, d1;
|
uint64_t a0, a1, d0, d1;
|
||||||
|
uint64_t *ap0, *ap1, *dp0, *dp1;
|
||||||
size_t sz, usize;
|
size_t sz, usize;
|
||||||
|
|
||||||
sz = sizeof(a0);
|
sz = sizeof(a0);
|
||||||
@@ -31,6 +32,20 @@ thread_start(void *arg)
|
|||||||
strerror(err));
|
strerror(err));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
sz = sizeof(ap0);
|
||||||
|
if ((err = JEMALLOC_P(mallctl)("thread.allocatedp", &ap0, &sz, NULL,
|
||||||
|
0))) {
|
||||||
|
if (err == ENOENT) {
|
||||||
|
#ifdef JEMALLOC_STATS
|
||||||
|
assert(false);
|
||||||
|
#endif
|
||||||
|
goto RETURN;
|
||||||
|
}
|
||||||
|
fprintf(stderr, "%s(): Error in mallctl(): %s\n", __func__,
|
||||||
|
strerror(err));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
assert(*ap0 == a0);
|
||||||
|
|
||||||
sz = sizeof(d0);
|
sz = sizeof(d0);
|
||||||
if ((err = JEMALLOC_P(mallctl)("thread.deallocated", &d0, &sz, NULL,
|
if ((err = JEMALLOC_P(mallctl)("thread.deallocated", &d0, &sz, NULL,
|
||||||
@@ -45,6 +60,20 @@ thread_start(void *arg)
|
|||||||
strerror(err));
|
strerror(err));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
sz = sizeof(dp0);
|
||||||
|
if ((err = JEMALLOC_P(mallctl)("thread.deallocatedp", &dp0, &sz, NULL,
|
||||||
|
0))) {
|
||||||
|
if (err == ENOENT) {
|
||||||
|
#ifdef JEMALLOC_STATS
|
||||||
|
assert(false);
|
||||||
|
#endif
|
||||||
|
goto RETURN;
|
||||||
|
}
|
||||||
|
fprintf(stderr, "%s(): Error in mallctl(): %s\n", __func__,
|
||||||
|
strerror(err));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
assert(*dp0 == d0);
|
||||||
|
|
||||||
p = JEMALLOC_P(malloc)(1);
|
p = JEMALLOC_P(malloc)(1);
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
@@ -54,6 +83,10 @@ thread_start(void *arg)
|
|||||||
|
|
||||||
sz = sizeof(a1);
|
sz = sizeof(a1);
|
||||||
JEMALLOC_P(mallctl)("thread.allocated", &a1, &sz, NULL, 0);
|
JEMALLOC_P(mallctl)("thread.allocated", &a1, &sz, NULL, 0);
|
||||||
|
sz = sizeof(ap1);
|
||||||
|
JEMALLOC_P(mallctl)("thread.allocatedp", &ap1, &sz, NULL, 0);
|
||||||
|
assert(*ap1 == a1);
|
||||||
|
assert(ap0 == ap1);
|
||||||
|
|
||||||
usize = JEMALLOC_P(malloc_usable_size)(p);
|
usize = JEMALLOC_P(malloc_usable_size)(p);
|
||||||
assert(a0 + usize <= a1);
|
assert(a0 + usize <= a1);
|
||||||
@@ -62,6 +95,10 @@ thread_start(void *arg)
|
|||||||
|
|
||||||
sz = sizeof(d1);
|
sz = sizeof(d1);
|
||||||
JEMALLOC_P(mallctl)("thread.deallocated", &d1, &sz, NULL, 0);
|
JEMALLOC_P(mallctl)("thread.deallocated", &d1, &sz, NULL, 0);
|
||||||
|
sz = sizeof(dp1);
|
||||||
|
JEMALLOC_P(mallctl)("thread.deallocatedp", &dp1, &sz, NULL, 0);
|
||||||
|
assert(*dp1 == d1);
|
||||||
|
assert(dp0 == dp1);
|
||||||
|
|
||||||
assert(d0 + usize <= d1);
|
assert(d0 + usize <= d1);
|
||||||
|
|
||||||
|
|||||||
67
jemalloc/test/mremap.c
Normal file
67
jemalloc/test/mremap.c
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define JEMALLOC_MANGLE
|
||||||
|
#include "jemalloc_test.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
main(void)
|
||||||
|
{
|
||||||
|
int ret, err;
|
||||||
|
size_t sz, lg_chunk, chunksize, i;
|
||||||
|
char *p, *q;
|
||||||
|
|
||||||
|
fprintf(stderr, "Test begin\n");
|
||||||
|
|
||||||
|
sz = sizeof(lg_chunk);
|
||||||
|
if ((err = JEMALLOC_P(mallctl)("opt.lg_chunk", &lg_chunk, &sz, NULL,
|
||||||
|
0))) {
|
||||||
|
assert(err != ENOENT);
|
||||||
|
fprintf(stderr, "%s(): Error in mallctl(): %s\n", __func__,
|
||||||
|
strerror(err));
|
||||||
|
ret = 1;
|
||||||
|
goto RETURN;
|
||||||
|
}
|
||||||
|
chunksize = ((size_t)1U) << lg_chunk;
|
||||||
|
|
||||||
|
p = (char *)malloc(chunksize);
|
||||||
|
if (p == NULL) {
|
||||||
|
fprintf(stderr, "malloc(%zu) --> %p\n", chunksize, p);
|
||||||
|
ret = 1;
|
||||||
|
goto RETURN;
|
||||||
|
}
|
||||||
|
memset(p, 'a', chunksize);
|
||||||
|
|
||||||
|
q = (char *)realloc(p, chunksize * 2);
|
||||||
|
if (q == NULL) {
|
||||||
|
fprintf(stderr, "realloc(%p, %zu) --> %p\n", p, chunksize * 2,
|
||||||
|
q);
|
||||||
|
ret = 1;
|
||||||
|
goto RETURN;
|
||||||
|
}
|
||||||
|
for (i = 0; i < chunksize; i++) {
|
||||||
|
assert(q[i] == 'a');
|
||||||
|
}
|
||||||
|
|
||||||
|
p = q;
|
||||||
|
|
||||||
|
q = (char *)realloc(p, chunksize);
|
||||||
|
if (q == NULL) {
|
||||||
|
fprintf(stderr, "realloc(%p, %zu) --> %p\n", p, chunksize, q);
|
||||||
|
ret = 1;
|
||||||
|
goto RETURN;
|
||||||
|
}
|
||||||
|
for (i = 0; i < chunksize; i++) {
|
||||||
|
assert(q[i] == 'a');
|
||||||
|
}
|
||||||
|
|
||||||
|
free(q);
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
RETURN:
|
||||||
|
fprintf(stderr, "Test end\n");
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
2
jemalloc/test/mremap.exp
Normal file
2
jemalloc/test/mremap.exp
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
Test begin
|
||||||
|
Test end
|
||||||
@@ -2,10 +2,13 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#define JEMALLOC_MANGLE
|
#define JEMALLOC_MANGLE
|
||||||
#include "jemalloc_test.h"
|
#include "jemalloc_test.h"
|
||||||
|
|
||||||
|
#define NTHREADS 10
|
||||||
|
|
||||||
void *
|
void *
|
||||||
thread_start(void *arg)
|
thread_start(void *arg)
|
||||||
{
|
{
|
||||||
@@ -29,6 +32,15 @@ thread_start(void *arg)
|
|||||||
return (void *)1;
|
return (void *)1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size = sizeof(arena_ind);
|
||||||
|
if ((err = JEMALLOC_P(mallctl)("thread.arena", &arena_ind, &size, NULL,
|
||||||
|
0))) {
|
||||||
|
fprintf(stderr, "%s(): Error in mallctl(): %s\n", __func__,
|
||||||
|
strerror(err));
|
||||||
|
return (void *)1;
|
||||||
|
}
|
||||||
|
assert(arena_ind == main_arena_ind);
|
||||||
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,7 +52,8 @@ main(void)
|
|||||||
unsigned arena_ind;
|
unsigned arena_ind;
|
||||||
size_t size;
|
size_t size;
|
||||||
int err;
|
int err;
|
||||||
pthread_t thread;
|
pthread_t threads[NTHREADS];
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
fprintf(stderr, "Test begin\n");
|
fprintf(stderr, "Test begin\n");
|
||||||
|
|
||||||
@@ -60,21 +73,18 @@ main(void)
|
|||||||
goto RETURN;
|
goto RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pthread_create(&thread, NULL, thread_start, (void *)&arena_ind)
|
for (i = 0; i < NTHREADS; i++) {
|
||||||
!= 0) {
|
if (pthread_create(&threads[i], NULL, thread_start,
|
||||||
fprintf(stderr, "%s(): Error in pthread_create()\n", __func__);
|
(void *)&arena_ind) != 0) {
|
||||||
|
fprintf(stderr, "%s(): Error in pthread_create()\n",
|
||||||
|
__func__);
|
||||||
ret = 1;
|
ret = 1;
|
||||||
goto RETURN;
|
goto RETURN;
|
||||||
}
|
}
|
||||||
pthread_join(thread, (void *)&ret);
|
}
|
||||||
|
|
||||||
if (pthread_create(&thread, NULL, thread_start, (void *)&arena_ind)
|
for (i = 0; i < NTHREADS; i++)
|
||||||
!= 0) {
|
pthread_join(threads[i], (void *)&ret);
|
||||||
fprintf(stderr, "%s(): Error in pthread_create()\n", __func__);
|
|
||||||
ret = 1;
|
|
||||||
goto RETURN;
|
|
||||||
}
|
|
||||||
pthread_join(thread, (void *)&ret);
|
|
||||||
|
|
||||||
RETURN:
|
RETURN:
|
||||||
fprintf(stderr, "Test end\n");
|
fprintf(stderr, "Test end\n");
|
||||||
|
|||||||
Reference in New Issue
Block a user