2010-01-17 01:53:50 +08:00
|
|
|
#define JEMALLOC_BASE_C_
|
2010-02-12 06:45:59 +08:00
|
|
|
#include "jemalloc/internal/jemalloc_internal.h"
|
2010-01-17 01:53:50 +08:00
|
|
|
|
2010-01-24 18:53:40 +08:00
|
|
|
/******************************************************************************/
|
|
|
|
/* Data. */
|
2010-01-17 01:53:50 +08:00
|
|
|
|
2012-03-14 07:31:41 +08:00
|
|
|
static malloc_mutex_t base_mtx;
|
2015-01-31 13:49:19 +08:00
|
|
|
static extent_tree_t base_avail_szad;
|
2010-01-17 01:53:50 +08:00
|
|
|
static extent_node_t *base_nodes;
|
2014-11-28 03:22:36 +08:00
|
|
|
static size_t base_allocated;
|
2015-03-24 08:25:57 +08:00
|
|
|
static size_t base_resident;
|
|
|
|
static size_t base_mapped;
|
2014-11-28 03:22:36 +08:00
|
|
|
|
2010-01-24 18:53:40 +08:00
|
|
|
/******************************************************************************/
|
2010-01-17 01:53:50 +08:00
|
|
|
|
Move centralized chunk management into arenas.
Migrate all centralized data structures related to huge allocations and
recyclable chunks into arena_t, so that each arena can manage huge
allocations and recyclable virtual memory completely independently of
other arenas.
Add chunk node caching to arenas, in order to avoid contention on the
base allocator.
Use chunks_rtree to look up huge allocations rather than a red-black
tree. Maintain a per arena unsorted list of huge allocations (which
will be needed to enumerate huge allocations during arena reset).
Remove the --enable-ivsalloc option, make ivsalloc() always available,
and use it for size queries if --enable-debug is enabled. The only
practical implications to this removal are that 1) ivsalloc() is now
always available during live debugging (and the underlying radix tree is
available during core-based debugging), and 2) size query validation can
no longer be enabled independent of --enable-debug.
Remove the stats.chunks.{current,total,high} mallctls, and replace their
underlying statistics with simpler atomically updated counters used
exclusively for gdump triggering. These statistics are no longer very
useful because each arena manages chunks independently, and per arena
statistics provide similar information.
Simplify chunk synchronization code, now that base chunk allocation
cannot cause recursive lock acquisition.
2015-02-12 04:24:27 +08:00
|
|
|
/* base_mtx must be held. */
|
2015-01-31 13:49:19 +08:00
|
|
|
static extent_node_t *
|
Move centralized chunk management into arenas.
Migrate all centralized data structures related to huge allocations and
recyclable chunks into arena_t, so that each arena can manage huge
allocations and recyclable virtual memory completely independently of
other arenas.
Add chunk node caching to arenas, in order to avoid contention on the
base allocator.
Use chunks_rtree to look up huge allocations rather than a red-black
tree. Maintain a per arena unsorted list of huge allocations (which
will be needed to enumerate huge allocations during arena reset).
Remove the --enable-ivsalloc option, make ivsalloc() always available,
and use it for size queries if --enable-debug is enabled. The only
practical implications to this removal are that 1) ivsalloc() is now
always available during live debugging (and the underlying radix tree is
available during core-based debugging), and 2) size query validation can
no longer be enabled independent of --enable-debug.
Remove the stats.chunks.{current,total,high} mallctls, and replace their
underlying statistics with simpler atomically updated counters used
exclusively for gdump triggering. These statistics are no longer very
useful because each arena manages chunks independently, and per arena
statistics provide similar information.
Simplify chunk synchronization code, now that base chunk allocation
cannot cause recursive lock acquisition.
2015-02-12 04:24:27 +08:00
|
|
|
base_node_try_alloc(void)
|
2010-01-17 01:53:50 +08:00
|
|
|
{
|
2015-01-31 13:49:19 +08:00
|
|
|
extent_node_t *node;
|
2010-01-17 01:53:50 +08:00
|
|
|
|
2015-01-31 13:49:19 +08:00
|
|
|
if (base_nodes == NULL)
|
|
|
|
return (NULL);
|
|
|
|
node = base_nodes;
|
|
|
|
base_nodes = *(extent_node_t **)node;
|
|
|
|
JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(node, sizeof(extent_node_t));
|
|
|
|
return (node);
|
|
|
|
}
|
2010-01-17 01:53:50 +08:00
|
|
|
|
Move centralized chunk management into arenas.
Migrate all centralized data structures related to huge allocations and
recyclable chunks into arena_t, so that each arena can manage huge
allocations and recyclable virtual memory completely independently of
other arenas.
Add chunk node caching to arenas, in order to avoid contention on the
base allocator.
Use chunks_rtree to look up huge allocations rather than a red-black
tree. Maintain a per arena unsorted list of huge allocations (which
will be needed to enumerate huge allocations during arena reset).
Remove the --enable-ivsalloc option, make ivsalloc() always available,
and use it for size queries if --enable-debug is enabled. The only
practical implications to this removal are that 1) ivsalloc() is now
always available during live debugging (and the underlying radix tree is
available during core-based debugging), and 2) size query validation can
no longer be enabled independent of --enable-debug.
Remove the stats.chunks.{current,total,high} mallctls, and replace their
underlying statistics with simpler atomically updated counters used
exclusively for gdump triggering. These statistics are no longer very
useful because each arena manages chunks independently, and per arena
statistics provide similar information.
Simplify chunk synchronization code, now that base chunk allocation
cannot cause recursive lock acquisition.
2015-02-12 04:24:27 +08:00
|
|
|
/* base_mtx must be held. */
|
2015-01-31 13:49:19 +08:00
|
|
|
static void
|
Move centralized chunk management into arenas.
Migrate all centralized data structures related to huge allocations and
recyclable chunks into arena_t, so that each arena can manage huge
allocations and recyclable virtual memory completely independently of
other arenas.
Add chunk node caching to arenas, in order to avoid contention on the
base allocator.
Use chunks_rtree to look up huge allocations rather than a red-black
tree. Maintain a per arena unsorted list of huge allocations (which
will be needed to enumerate huge allocations during arena reset).
Remove the --enable-ivsalloc option, make ivsalloc() always available,
and use it for size queries if --enable-debug is enabled. The only
practical implications to this removal are that 1) ivsalloc() is now
always available during live debugging (and the underlying radix tree is
available during core-based debugging), and 2) size query validation can
no longer be enabled independent of --enable-debug.
Remove the stats.chunks.{current,total,high} mallctls, and replace their
underlying statistics with simpler atomically updated counters used
exclusively for gdump triggering. These statistics are no longer very
useful because each arena manages chunks independently, and per arena
statistics provide similar information.
Simplify chunk synchronization code, now that base chunk allocation
cannot cause recursive lock acquisition.
2015-02-12 04:24:27 +08:00
|
|
|
base_node_dalloc(extent_node_t *node)
|
2015-01-31 13:49:19 +08:00
|
|
|
{
|
|
|
|
|
|
|
|
JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(node, sizeof(extent_node_t));
|
|
|
|
*(extent_node_t **)node = base_nodes;
|
|
|
|
base_nodes = node;
|
2010-01-17 01:53:50 +08:00
|
|
|
}
|
|
|
|
|
2015-01-31 13:49:19 +08:00
|
|
|
/* base_mtx must be held. */
|
|
|
|
static extent_node_t *
|
|
|
|
base_chunk_alloc(size_t minsize)
|
|
|
|
{
|
|
|
|
extent_node_t *node;
|
|
|
|
size_t csize, nsize;
|
|
|
|
void *addr;
|
|
|
|
|
|
|
|
assert(minsize != 0);
|
Move centralized chunk management into arenas.
Migrate all centralized data structures related to huge allocations and
recyclable chunks into arena_t, so that each arena can manage huge
allocations and recyclable virtual memory completely independently of
other arenas.
Add chunk node caching to arenas, in order to avoid contention on the
base allocator.
Use chunks_rtree to look up huge allocations rather than a red-black
tree. Maintain a per arena unsorted list of huge allocations (which
will be needed to enumerate huge allocations during arena reset).
Remove the --enable-ivsalloc option, make ivsalloc() always available,
and use it for size queries if --enable-debug is enabled. The only
practical implications to this removal are that 1) ivsalloc() is now
always available during live debugging (and the underlying radix tree is
available during core-based debugging), and 2) size query validation can
no longer be enabled independent of --enable-debug.
Remove the stats.chunks.{current,total,high} mallctls, and replace their
underlying statistics with simpler atomically updated counters used
exclusively for gdump triggering. These statistics are no longer very
useful because each arena manages chunks independently, and per arena
statistics provide similar information.
Simplify chunk synchronization code, now that base chunk allocation
cannot cause recursive lock acquisition.
2015-02-12 04:24:27 +08:00
|
|
|
node = base_node_try_alloc();
|
2015-01-31 13:49:19 +08:00
|
|
|
/* Allocate enough space to also carve a node out if necessary. */
|
|
|
|
nsize = (node == NULL) ? CACHELINE_CEILING(sizeof(extent_node_t)) : 0;
|
|
|
|
csize = CHUNK_CEILING(minsize + nsize);
|
|
|
|
addr = chunk_alloc_base(csize);
|
|
|
|
if (addr == NULL) {
|
|
|
|
if (node != NULL)
|
Move centralized chunk management into arenas.
Migrate all centralized data structures related to huge allocations and
recyclable chunks into arena_t, so that each arena can manage huge
allocations and recyclable virtual memory completely independently of
other arenas.
Add chunk node caching to arenas, in order to avoid contention on the
base allocator.
Use chunks_rtree to look up huge allocations rather than a red-black
tree. Maintain a per arena unsorted list of huge allocations (which
will be needed to enumerate huge allocations during arena reset).
Remove the --enable-ivsalloc option, make ivsalloc() always available,
and use it for size queries if --enable-debug is enabled. The only
practical implications to this removal are that 1) ivsalloc() is now
always available during live debugging (and the underlying radix tree is
available during core-based debugging), and 2) size query validation can
no longer be enabled independent of --enable-debug.
Remove the stats.chunks.{current,total,high} mallctls, and replace their
underlying statistics with simpler atomically updated counters used
exclusively for gdump triggering. These statistics are no longer very
useful because each arena manages chunks independently, and per arena
statistics provide similar information.
Simplify chunk synchronization code, now that base chunk allocation
cannot cause recursive lock acquisition.
2015-02-12 04:24:27 +08:00
|
|
|
base_node_dalloc(node);
|
2015-01-31 13:49:19 +08:00
|
|
|
return (NULL);
|
|
|
|
}
|
2015-03-24 08:25:57 +08:00
|
|
|
base_mapped += csize;
|
2015-01-31 13:49:19 +08:00
|
|
|
if (node == NULL) {
|
2015-03-24 08:25:57 +08:00
|
|
|
node = (extent_node_t *)addr;
|
|
|
|
addr = (void *)((uintptr_t)addr + nsize);
|
2015-01-31 13:49:19 +08:00
|
|
|
csize -= nsize;
|
2015-03-24 08:25:57 +08:00
|
|
|
if (config_stats) {
|
2015-01-31 13:49:19 +08:00
|
|
|
base_allocated += nsize;
|
2015-03-24 08:25:57 +08:00
|
|
|
base_resident += PAGE_CEILING(nsize);
|
|
|
|
}
|
2015-01-31 13:49:19 +08:00
|
|
|
}
|
2015-02-18 07:13:52 +08:00
|
|
|
extent_node_init(node, NULL, addr, csize, true);
|
2015-01-31 13:49:19 +08:00
|
|
|
return (node);
|
|
|
|
}
|
|
|
|
|
Move centralized chunk management into arenas.
Migrate all centralized data structures related to huge allocations and
recyclable chunks into arena_t, so that each arena can manage huge
allocations and recyclable virtual memory completely independently of
other arenas.
Add chunk node caching to arenas, in order to avoid contention on the
base allocator.
Use chunks_rtree to look up huge allocations rather than a red-black
tree. Maintain a per arena unsorted list of huge allocations (which
will be needed to enumerate huge allocations during arena reset).
Remove the --enable-ivsalloc option, make ivsalloc() always available,
and use it for size queries if --enable-debug is enabled. The only
practical implications to this removal are that 1) ivsalloc() is now
always available during live debugging (and the underlying radix tree is
available during core-based debugging), and 2) size query validation can
no longer be enabled independent of --enable-debug.
Remove the stats.chunks.{current,total,high} mallctls, and replace their
underlying statistics with simpler atomically updated counters used
exclusively for gdump triggering. These statistics are no longer very
useful because each arena manages chunks independently, and per arena
statistics provide similar information.
Simplify chunk synchronization code, now that base chunk allocation
cannot cause recursive lock acquisition.
2015-02-12 04:24:27 +08:00
|
|
|
/*
|
|
|
|
* base_alloc() guarantees demand-zeroed memory, in order to make multi-page
|
|
|
|
* sparse data structures such as radix tree nodes efficient with respect to
|
|
|
|
* physical memory usage.
|
|
|
|
*/
|
|
|
|
void *
|
|
|
|
base_alloc(size_t size)
|
2010-01-17 01:53:50 +08:00
|
|
|
{
|
|
|
|
void *ret;
|
2015-03-07 09:14:05 +08:00
|
|
|
size_t csize, usize;
|
2015-01-31 13:49:19 +08:00
|
|
|
extent_node_t *node;
|
|
|
|
extent_node_t key;
|
2010-01-17 01:53:50 +08:00
|
|
|
|
2015-01-31 13:49:19 +08:00
|
|
|
/*
|
|
|
|
* Round size up to nearest multiple of the cacheline size, so that
|
|
|
|
* there is no chance of false cache line sharing.
|
|
|
|
*/
|
2010-01-17 01:53:50 +08:00
|
|
|
csize = CACHELINE_CEILING(size);
|
|
|
|
|
2015-03-07 09:14:05 +08:00
|
|
|
usize = s2u(csize);
|
|
|
|
extent_node_init(&key, NULL, NULL, usize, false);
|
Move centralized chunk management into arenas.
Migrate all centralized data structures related to huge allocations and
recyclable chunks into arena_t, so that each arena can manage huge
allocations and recyclable virtual memory completely independently of
other arenas.
Add chunk node caching to arenas, in order to avoid contention on the
base allocator.
Use chunks_rtree to look up huge allocations rather than a red-black
tree. Maintain a per arena unsorted list of huge allocations (which
will be needed to enumerate huge allocations during arena reset).
Remove the --enable-ivsalloc option, make ivsalloc() always available,
and use it for size queries if --enable-debug is enabled. The only
practical implications to this removal are that 1) ivsalloc() is now
always available during live debugging (and the underlying radix tree is
available during core-based debugging), and 2) size query validation can
no longer be enabled independent of --enable-debug.
Remove the stats.chunks.{current,total,high} mallctls, and replace their
underlying statistics with simpler atomically updated counters used
exclusively for gdump triggering. These statistics are no longer very
useful because each arena manages chunks independently, and per arena
statistics provide similar information.
Simplify chunk synchronization code, now that base chunk allocation
cannot cause recursive lock acquisition.
2015-02-12 04:24:27 +08:00
|
|
|
malloc_mutex_lock(&base_mtx);
|
2015-01-31 13:49:19 +08:00
|
|
|
node = extent_tree_szad_nsearch(&base_avail_szad, &key);
|
|
|
|
if (node != NULL) {
|
|
|
|
/* Use existing space. */
|
|
|
|
extent_tree_szad_remove(&base_avail_szad, node);
|
|
|
|
} else {
|
|
|
|
/* Try to allocate more space. */
|
|
|
|
node = base_chunk_alloc(csize);
|
2010-01-17 01:53:50 +08:00
|
|
|
}
|
Move centralized chunk management into arenas.
Migrate all centralized data structures related to huge allocations and
recyclable chunks into arena_t, so that each arena can manage huge
allocations and recyclable virtual memory completely independently of
other arenas.
Add chunk node caching to arenas, in order to avoid contention on the
base allocator.
Use chunks_rtree to look up huge allocations rather than a red-black
tree. Maintain a per arena unsorted list of huge allocations (which
will be needed to enumerate huge allocations during arena reset).
Remove the --enable-ivsalloc option, make ivsalloc() always available,
and use it for size queries if --enable-debug is enabled. The only
practical implications to this removal are that 1) ivsalloc() is now
always available during live debugging (and the underlying radix tree is
available during core-based debugging), and 2) size query validation can
no longer be enabled independent of --enable-debug.
Remove the stats.chunks.{current,total,high} mallctls, and replace their
underlying statistics with simpler atomically updated counters used
exclusively for gdump triggering. These statistics are no longer very
useful because each arena manages chunks independently, and per arena
statistics provide similar information.
Simplify chunk synchronization code, now that base chunk allocation
cannot cause recursive lock acquisition.
2015-02-12 04:24:27 +08:00
|
|
|
if (node == NULL) {
|
|
|
|
ret = NULL;
|
|
|
|
goto label_return;
|
|
|
|
}
|
2015-01-31 13:49:19 +08:00
|
|
|
|
2015-02-16 10:04:46 +08:00
|
|
|
ret = extent_node_addr_get(node);
|
|
|
|
if (extent_node_size_get(node) > csize) {
|
|
|
|
extent_node_addr_set(node, (void *)((uintptr_t)ret + csize));
|
|
|
|
extent_node_size_set(node, extent_node_size_get(node) - csize);
|
2015-01-31 13:49:19 +08:00
|
|
|
extent_tree_szad_insert(&base_avail_szad, node);
|
|
|
|
} else
|
Move centralized chunk management into arenas.
Migrate all centralized data structures related to huge allocations and
recyclable chunks into arena_t, so that each arena can manage huge
allocations and recyclable virtual memory completely independently of
other arenas.
Add chunk node caching to arenas, in order to avoid contention on the
base allocator.
Use chunks_rtree to look up huge allocations rather than a red-black
tree. Maintain a per arena unsorted list of huge allocations (which
will be needed to enumerate huge allocations during arena reset).
Remove the --enable-ivsalloc option, make ivsalloc() always available,
and use it for size queries if --enable-debug is enabled. The only
practical implications to this removal are that 1) ivsalloc() is now
always available during live debugging (and the underlying radix tree is
available during core-based debugging), and 2) size query validation can
no longer be enabled independent of --enable-debug.
Remove the stats.chunks.{current,total,high} mallctls, and replace their
underlying statistics with simpler atomically updated counters used
exclusively for gdump triggering. These statistics are no longer very
useful because each arena manages chunks independently, and per arena
statistics provide similar information.
Simplify chunk synchronization code, now that base chunk allocation
cannot cause recursive lock acquisition.
2015-02-12 04:24:27 +08:00
|
|
|
base_node_dalloc(node);
|
2015-03-24 08:25:57 +08:00
|
|
|
if (config_stats) {
|
2014-11-28 03:22:36 +08:00
|
|
|
base_allocated += csize;
|
2015-03-24 08:25:57 +08:00
|
|
|
/*
|
|
|
|
* Add one PAGE to base_resident for every page boundary that is
|
|
|
|
* crossed by the new allocation.
|
|
|
|
*/
|
|
|
|
base_resident += PAGE_CEILING((uintptr_t)ret + csize) -
|
|
|
|
PAGE_CEILING((uintptr_t)ret);
|
|
|
|
}
|
2014-04-16 07:35:08 +08:00
|
|
|
JEMALLOC_VALGRIND_MAKE_MEM_UNDEFINED(ret, csize);
|
Move centralized chunk management into arenas.
Migrate all centralized data structures related to huge allocations and
recyclable chunks into arena_t, so that each arena can manage huge
allocations and recyclable virtual memory completely independently of
other arenas.
Add chunk node caching to arenas, in order to avoid contention on the
base allocator.
Use chunks_rtree to look up huge allocations rather than a red-black
tree. Maintain a per arena unsorted list of huge allocations (which
will be needed to enumerate huge allocations during arena reset).
Remove the --enable-ivsalloc option, make ivsalloc() always available,
and use it for size queries if --enable-debug is enabled. The only
practical implications to this removal are that 1) ivsalloc() is now
always available during live debugging (and the underlying radix tree is
available during core-based debugging), and 2) size query validation can
no longer be enabled independent of --enable-debug.
Remove the stats.chunks.{current,total,high} mallctls, and replace their
underlying statistics with simpler atomically updated counters used
exclusively for gdump triggering. These statistics are no longer very
useful because each arena manages chunks independently, and per arena
statistics provide similar information.
Simplify chunk synchronization code, now that base chunk allocation
cannot cause recursive lock acquisition.
2015-02-12 04:24:27 +08:00
|
|
|
label_return:
|
2015-01-31 13:49:19 +08:00
|
|
|
malloc_mutex_unlock(&base_mtx);
|
2012-02-03 14:04:57 +08:00
|
|
|
return (ret);
|
|
|
|
}
|
|
|
|
|
2015-03-24 08:25:57 +08:00
|
|
|
void
|
|
|
|
base_stats_get(size_t *allocated, size_t *resident, size_t *mapped)
|
2014-11-28 03:22:36 +08:00
|
|
|
{
|
|
|
|
|
|
|
|
malloc_mutex_lock(&base_mtx);
|
2015-03-24 08:25:57 +08:00
|
|
|
*allocated = base_allocated;
|
|
|
|
*resident = base_resident;
|
|
|
|
*mapped = base_mapped;
|
2014-11-28 03:22:36 +08:00
|
|
|
malloc_mutex_unlock(&base_mtx);
|
|
|
|
}
|
|
|
|
|
2010-01-17 01:53:50 +08:00
|
|
|
bool
|
|
|
|
base_boot(void)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (malloc_mutex_init(&base_mtx))
|
|
|
|
return (true);
|
2015-01-31 13:49:19 +08:00
|
|
|
extent_tree_szad_new(&base_avail_szad);
|
|
|
|
base_nodes = NULL;
|
2010-01-17 01:53:50 +08:00
|
|
|
|
|
|
|
return (false);
|
|
|
|
}
|
2012-03-14 07:31:41 +08:00
|
|
|
|
|
|
|
void
|
|
|
|
base_prefork(void)
|
|
|
|
{
|
|
|
|
|
|
|
|
malloc_mutex_prefork(&base_mtx);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
base_postfork_parent(void)
|
|
|
|
{
|
|
|
|
|
|
|
|
malloc_mutex_postfork_parent(&base_mtx);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
base_postfork_child(void)
|
|
|
|
{
|
|
|
|
|
|
|
|
malloc_mutex_postfork_child(&base_mtx);
|
|
|
|
}
|