summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQi Wang <interwq@gwu.edu>2017-04-20 22:19:02 (GMT)
committerQi Wang <interwq@gmail.com>2017-04-21 07:29:18 (GMT)
commit5aa46f027df42636d4aa1fb70d1078a6c5f96420 (patch)
treea6c7dd4f8e2eeac7949b0d39b0f4329b79735ab7 /src
parentfed9a880c811fc56f7563efcb0a70c6ffe401c5f (diff)
downloadjemalloc-5aa46f027df42636d4aa1fb70d1078a6c5f96420.zip
jemalloc-5aa46f027df42636d4aa1fb70d1078a6c5f96420.tar.gz
jemalloc-5aa46f027df42636d4aa1fb70d1078a6c5f96420.tar.bz2
Bypass extent tracking for auto arenas.
Tracking extents is required by arena_reset. To support this, the extent linkage was used for tracking 1) large allocations, and 2) full slabs. However modifying the extent linkage could be an expensive operation as it likely incurs cache misses. Since we forbid arena_reset on auto arenas, let's bypass the linkage operations for auto arenas.
Diffstat (limited to 'src')
-rw-r--r--src/arena.c33
-rw-r--r--src/ctl.c7
-rw-r--r--src/large.c25
3 files changed, 39 insertions, 26 deletions
diff --git a/src/arena.c b/src/arena.c
index bb45a90..94a4b5e 100644
--- a/src/arena.c
+++ b/src/arena.c
@@ -1032,13 +1032,24 @@ arena_bin_slabs_nonfull_tryget(arena_bin_t *bin) {
}
static void
-arena_bin_slabs_full_insert(arena_bin_t *bin, extent_t *slab) {
+arena_bin_slabs_full_insert(arena_t *arena, arena_bin_t *bin, extent_t *slab) {
assert(extent_nfree_get(slab) == 0);
+ /*
+ * Tracking extents is required by arena_reset, which is not allowed
+ * for auto arenas. Bypass this step to avoid touching the extent
+ * linkage (often results in cache misses) for auto arenas.
+ */
+ if (arena_is_auto(arena)) {
+ return;
+ }
extent_list_append(&bin->slabs_full, slab);
}
static void
-arena_bin_slabs_full_remove(arena_bin_t *bin, extent_t *slab) {
+arena_bin_slabs_full_remove(arena_t *arena, arena_bin_t *bin, extent_t *slab) {
+ if (arena_is_auto(arena)) {
+ return;
+ }
extent_list_remove(&bin->slabs_full, slab);
}
@@ -1106,7 +1117,7 @@ arena_reset(tsd_t *tsd, arena_t *arena) {
}
for (slab = extent_list_first(&bin->slabs_full); slab != NULL;
slab = extent_list_first(&bin->slabs_full)) {
- arena_bin_slabs_full_remove(bin, slab);
+ arena_bin_slabs_full_remove(arena, bin, slab);
malloc_mutex_unlock(tsd_tsdn(tsd), &bin->lock);
arena_slab_dalloc(tsd_tsdn(tsd), arena, slab);
malloc_mutex_lock(tsd_tsdn(tsd), &bin->lock);
@@ -1285,8 +1296,8 @@ arena_bin_malloc_hard(tsdn_t *tsdn, arena_t *arena, arena_bin_t *bin,
extent_t *slab;
bin_info = &arena_bin_info[binind];
- if (bin->slabcur != NULL) {
- arena_bin_slabs_full_insert(bin, bin->slabcur);
+ if (!arena_is_auto(arena) && bin->slabcur != NULL) {
+ arena_bin_slabs_full_insert(arena, bin, bin->slabcur);
bin->slabcur = NULL;
}
slab = arena_bin_nonfull_slab_get(tsdn, arena, bin, binind);
@@ -1319,7 +1330,7 @@ arena_bin_malloc_hard(tsdn_t *tsdn, arena_t *arena, arena_bin_t *bin,
return ret;
}
- arena_bin_slabs_full_insert(bin, bin->slabcur);
+ arena_bin_slabs_full_insert(arena, bin, bin->slabcur);
bin->slabcur = NULL;
}
@@ -1559,7 +1570,7 @@ arena_dalloc_promoted(tsdn_t *tsdn, void *ptr, tcache_t *tcache,
}
static void
-arena_dissociate_bin_slab(extent_t *slab, arena_bin_t *bin) {
+arena_dissociate_bin_slab(arena_t *arena, extent_t *slab, arena_bin_t *bin) {
/* Dissociate slab from bin. */
if (slab == bin->slabcur) {
bin->slabcur = NULL;
@@ -1573,7 +1584,7 @@ arena_dissociate_bin_slab(extent_t *slab, arena_bin_t *bin) {
* into the non-full slabs heap.
*/
if (bin_info->nregs == 1) {
- arena_bin_slabs_full_remove(bin, slab);
+ arena_bin_slabs_full_remove(arena, bin, slab);
} else {
arena_bin_slabs_nonfull_remove(bin, slab);
}
@@ -1611,7 +1622,7 @@ arena_bin_lower_slab(tsdn_t *tsdn, arena_t *arena, extent_t *slab,
if (extent_nfree_get(bin->slabcur) > 0) {
arena_bin_slabs_nonfull_insert(bin, bin->slabcur);
} else {
- arena_bin_slabs_full_insert(bin, bin->slabcur);
+ arena_bin_slabs_full_insert(arena, bin, bin->slabcur);
}
bin->slabcur = slab;
if (config_stats) {
@@ -1637,10 +1648,10 @@ arena_dalloc_bin_locked_impl(tsdn_t *tsdn, arena_t *arena, extent_t *slab,
arena_slab_reg_dalloc(tsdn, slab, slab_data, ptr);
unsigned nfree = extent_nfree_get(slab);
if (nfree == bin_info->nregs) {
- arena_dissociate_bin_slab(slab, bin);
+ arena_dissociate_bin_slab(arena, slab, bin);
arena_dalloc_bin_slab(tsdn, arena, slab, bin);
} else if (nfree == 1 && slab != bin->slabcur) {
- arena_bin_slabs_full_remove(bin, slab);
+ arena_bin_slabs_full_remove(arena, bin, slab);
arena_bin_lower_slab(tsdn, arena, slab, bin);
}
diff --git a/src/ctl.c b/src/ctl.c
index 069e535..1b0ee05 100644
--- a/src/ctl.c
+++ b/src/ctl.c
@@ -1846,13 +1846,8 @@ arena_i_reset_destroy_helper(tsd_t *tsd, const size_t *mib, size_t miblen,
WRITEONLY();
MIB_UNSIGNED(*arena_ind, 1);
- if (*arena_ind < narenas_auto) {
- ret = EFAULT;
- goto label_return;
- }
-
*arena = arena_get(tsd_tsdn(tsd), *arena_ind, false);
- if (*arena == NULL) {
+ if (*arena == NULL || arena_is_auto(*arena)) {
ret = EFAULT;
goto label_return;
}
diff --git a/src/large.c b/src/large.c
index 629656d..36e8be9 100644
--- a/src/large.c
+++ b/src/large.c
@@ -46,10 +46,13 @@ large_palloc(tsdn_t *tsdn, arena_t *arena, size_t usize, size_t alignment,
return NULL;
}
- /* Insert extent into large. */
- malloc_mutex_lock(tsdn, &arena->large_mtx);
- extent_list_append(&arena->large, extent);
- malloc_mutex_unlock(tsdn, &arena->large_mtx);
+ /* See comments in arena_bin_slabs_full_insert(). */
+ if (!arena_is_auto(arena)) {
+ /* Insert extent into large. */
+ malloc_mutex_lock(tsdn, &arena->large_mtx);
+ extent_list_append(&arena->large, extent);
+ malloc_mutex_unlock(tsdn, &arena->large_mtx);
+ }
if (config_prof && arena_prof_accum(tsdn, arena, usize)) {
prof_idump(tsdn);
}
@@ -318,16 +321,20 @@ large_ralloc(tsdn_t *tsdn, arena_t *arena, extent_t *extent, size_t usize,
static void
large_dalloc_prep_impl(tsdn_t *tsdn, arena_t *arena, extent_t *extent,
bool junked_locked) {
-
if (!junked_locked) {
- malloc_mutex_lock(tsdn, &arena->large_mtx);
- extent_list_remove(&arena->large, extent);
- malloc_mutex_unlock(tsdn, &arena->large_mtx);
+ /* See comments in arena_bin_slabs_full_insert(). */
+ if (!arena_is_auto(arena)) {
+ malloc_mutex_lock(tsdn, &arena->large_mtx);
+ extent_list_remove(&arena->large, extent);
+ malloc_mutex_unlock(tsdn, &arena->large_mtx);
+ }
large_dalloc_maybe_junk(extent_addr_get(extent),
extent_usize_get(extent));
} else {
malloc_mutex_assert_owner(tsdn, &arena->large_mtx);
- extent_list_remove(&arena->large, extent);
+ if (!arena_is_auto(arena)) {
+ extent_list_remove(&arena->large, extent);
+ }
}
arena_extent_dalloc_large_prep(tsdn, arena, extent);
}