mirror of
https://github.com/jemalloc/jemalloc.git
synced 2026-06-22 11:55:47 +03:00
Do not (recursively) allocate within tsd_fetch().
Refactor tsd so that tsdn_fetch() does not trigger allocation, since allocation could cause infinite recursion. This resolves #458.
This commit is contained in:
parent
e2bcf037d4
commit
962a2979e3
14 changed files with 176 additions and 130 deletions
85
src/prof.c
85
src/prof.c
|
|
@ -125,7 +125,7 @@ static bool prof_tctx_should_destroy(tsdn_t *tsdn, prof_tctx_t *tctx);
|
|||
static void prof_tctx_destroy(tsd_t *tsd, prof_tctx_t *tctx);
|
||||
static bool prof_tdata_should_destroy(tsdn_t *tsdn, prof_tdata_t *tdata,
|
||||
bool even_if_attached);
|
||||
static void prof_tdata_destroy(tsdn_t *tsdn, prof_tdata_t *tdata,
|
||||
static void prof_tdata_destroy(tsd_t *tsd, prof_tdata_t *tdata,
|
||||
bool even_if_attached);
|
||||
static char *prof_thread_name_alloc(tsdn_t *tsdn, const char *thread_name);
|
||||
|
||||
|
|
@ -591,7 +591,7 @@ prof_gctx_try_destroy(tsd_t *tsd, prof_tdata_t *tdata_self, prof_gctx_t *gctx,
|
|||
assert(gctx->nlimbo != 0);
|
||||
if (tctx_tree_empty(&gctx->tctxs) && gctx->nlimbo == 1) {
|
||||
/* Remove gctx from bt2gctx. */
|
||||
if (ckh_remove(tsd_tsdn(tsd), &bt2gctx, &gctx->bt, NULL, NULL))
|
||||
if (ckh_remove(tsd, &bt2gctx, &gctx->bt, NULL, NULL))
|
||||
not_reached();
|
||||
prof_leave(tsd, tdata_self);
|
||||
/* Destroy gctx. */
|
||||
|
|
@ -651,7 +651,7 @@ prof_tctx_destroy(tsd_t *tsd, prof_tctx_t *tctx)
|
|||
assert(tctx->cnts.accumobjs == 0);
|
||||
assert(tctx->cnts.accumbytes == 0);
|
||||
|
||||
ckh_remove(tsd_tsdn(tsd), &tdata->bt2tctx, &gctx->bt, NULL, NULL);
|
||||
ckh_remove(tsd, &tdata->bt2tctx, &gctx->bt, NULL, NULL);
|
||||
destroy_tdata = prof_tdata_should_destroy(tsd_tsdn(tsd), tdata, false);
|
||||
malloc_mutex_unlock(tsd_tsdn(tsd), tdata->lock);
|
||||
|
||||
|
|
@ -704,7 +704,7 @@ prof_tctx_destroy(tsd_t *tsd, prof_tctx_t *tctx)
|
|||
malloc_mutex_assert_not_owner(tsd_tsdn(tsd), tctx->tdata->lock);
|
||||
|
||||
if (destroy_tdata)
|
||||
prof_tdata_destroy(tsd_tsdn(tsd), tdata, false);
|
||||
prof_tdata_destroy(tsd, tdata, false);
|
||||
|
||||
if (destroy_tctx)
|
||||
idalloctm(tsd_tsdn(tsd), tctx, NULL, true, true);
|
||||
|
|
@ -733,7 +733,7 @@ prof_lookup_global(tsd_t *tsd, prof_bt_t *bt, prof_tdata_t *tdata,
|
|||
return (true);
|
||||
}
|
||||
btkey.p = &gctx.p->bt;
|
||||
if (ckh_insert(tsd_tsdn(tsd), &bt2gctx, btkey.v, gctx.v)) {
|
||||
if (ckh_insert(tsd, &bt2gctx, btkey.v, gctx.v)) {
|
||||
/* OOM. */
|
||||
prof_leave(tsd, tdata);
|
||||
idalloctm(tsd_tsdn(tsd), gctx.v, NULL, true, true);
|
||||
|
|
@ -795,7 +795,7 @@ prof_lookup(tsd_t *tsd, prof_bt_t *bt)
|
|||
/* Link a prof_tctx_t into gctx for this thread. */
|
||||
ret.v = iallocztm(tsd_tsdn(tsd), sizeof(prof_tctx_t),
|
||||
size2index(sizeof(prof_tctx_t)), false, NULL, true,
|
||||
arena_ichoose(tsd_tsdn(tsd), NULL), true);
|
||||
arena_ichoose(tsd, NULL), true);
|
||||
if (ret.p == NULL) {
|
||||
if (new_gctx)
|
||||
prof_gctx_try_destroy(tsd, tdata, gctx, tdata);
|
||||
|
|
@ -810,8 +810,7 @@ prof_lookup(tsd_t *tsd, prof_bt_t *bt)
|
|||
ret.p->prepared = true;
|
||||
ret.p->state = prof_tctx_state_initializing;
|
||||
malloc_mutex_lock(tsd_tsdn(tsd), tdata->lock);
|
||||
error = ckh_insert(tsd_tsdn(tsd), &tdata->bt2tctx, btkey,
|
||||
ret.v);
|
||||
error = ckh_insert(tsd, &tdata->bt2tctx, btkey, ret.v);
|
||||
malloc_mutex_unlock(tsd_tsdn(tsd), tdata->lock);
|
||||
if (error) {
|
||||
if (new_gctx)
|
||||
|
|
@ -1791,7 +1790,7 @@ prof_thr_uid_alloc(tsdn_t *tsdn)
|
|||
}
|
||||
|
||||
static prof_tdata_t *
|
||||
prof_tdata_init_impl(tsdn_t *tsdn, uint64_t thr_uid, uint64_t thr_discrim,
|
||||
prof_tdata_init_impl(tsd_t *tsd, uint64_t thr_uid, uint64_t thr_discrim,
|
||||
char *thread_name, bool active)
|
||||
{
|
||||
prof_tdata_t *tdata;
|
||||
|
|
@ -1799,7 +1798,7 @@ prof_tdata_init_impl(tsdn_t *tsdn, uint64_t thr_uid, uint64_t thr_discrim,
|
|||
cassert(config_prof);
|
||||
|
||||
/* Initialize an empty cache for this thread. */
|
||||
tdata = (prof_tdata_t *)iallocztm(tsdn, sizeof(prof_tdata_t),
|
||||
tdata = (prof_tdata_t *)iallocztm(tsd_tsdn(tsd), sizeof(prof_tdata_t),
|
||||
size2index(sizeof(prof_tdata_t)), false, NULL, true,
|
||||
arena_get(TSDN_NULL, 0, true), true);
|
||||
if (tdata == NULL)
|
||||
|
|
@ -1813,9 +1812,9 @@ prof_tdata_init_impl(tsdn_t *tsdn, uint64_t thr_uid, uint64_t thr_discrim,
|
|||
tdata->expired = false;
|
||||
tdata->tctx_uid_next = 0;
|
||||
|
||||
if (ckh_new(tsdn, &tdata->bt2tctx, PROF_CKH_MINITEMS,
|
||||
prof_bt_hash, prof_bt_keycomp)) {
|
||||
idalloctm(tsdn, tdata, NULL, true, true);
|
||||
if (ckh_new(tsd, &tdata->bt2tctx, PROF_CKH_MINITEMS, prof_bt_hash,
|
||||
prof_bt_keycomp)) {
|
||||
idalloctm(tsd_tsdn(tsd), tdata, NULL, true, true);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
|
@ -1829,19 +1828,19 @@ prof_tdata_init_impl(tsdn_t *tsdn, uint64_t thr_uid, uint64_t thr_discrim,
|
|||
tdata->dumping = false;
|
||||
tdata->active = active;
|
||||
|
||||
malloc_mutex_lock(tsdn, &tdatas_mtx);
|
||||
malloc_mutex_lock(tsd_tsdn(tsd), &tdatas_mtx);
|
||||
tdata_tree_insert(&tdatas, tdata);
|
||||
malloc_mutex_unlock(tsdn, &tdatas_mtx);
|
||||
malloc_mutex_unlock(tsd_tsdn(tsd), &tdatas_mtx);
|
||||
|
||||
return (tdata);
|
||||
}
|
||||
|
||||
prof_tdata_t *
|
||||
prof_tdata_init(tsdn_t *tsdn)
|
||||
prof_tdata_init(tsd_t *tsd)
|
||||
{
|
||||
|
||||
return (prof_tdata_init_impl(tsdn, prof_thr_uid_alloc(tsdn), 0, NULL,
|
||||
prof_thread_active_init_get(tsdn)));
|
||||
return (prof_tdata_init_impl(tsd, prof_thr_uid_alloc(tsd_tsdn(tsd)), 0,
|
||||
NULL, prof_thread_active_init_get(tsd_tsdn(tsd))));
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -1866,31 +1865,29 @@ prof_tdata_should_destroy(tsdn_t *tsdn, prof_tdata_t *tdata,
|
|||
}
|
||||
|
||||
static void
|
||||
prof_tdata_destroy_locked(tsdn_t *tsdn, prof_tdata_t *tdata,
|
||||
prof_tdata_destroy_locked(tsd_t *tsd, prof_tdata_t *tdata,
|
||||
bool even_if_attached)
|
||||
{
|
||||
|
||||
malloc_mutex_assert_owner(tsdn, &tdatas_mtx);
|
||||
|
||||
assert(tsdn_null(tsdn) || tsd_prof_tdata_get(tsdn_tsd(tsdn)) != tdata);
|
||||
malloc_mutex_assert_owner(tsd_tsdn(tsd), &tdatas_mtx);
|
||||
|
||||
tdata_tree_remove(&tdatas, tdata);
|
||||
|
||||
assert(prof_tdata_should_destroy_unlocked(tdata, even_if_attached));
|
||||
|
||||
if (tdata->thread_name != NULL)
|
||||
idalloctm(tsdn, tdata->thread_name, NULL, true, true);
|
||||
ckh_delete(tsdn, &tdata->bt2tctx);
|
||||
idalloctm(tsdn, tdata, NULL, true, true);
|
||||
idalloctm(tsd_tsdn(tsd), tdata->thread_name, NULL, true, true);
|
||||
ckh_delete(tsd, &tdata->bt2tctx);
|
||||
idalloctm(tsd_tsdn(tsd), tdata, NULL, true, true);
|
||||
}
|
||||
|
||||
static void
|
||||
prof_tdata_destroy(tsdn_t *tsdn, prof_tdata_t *tdata, bool even_if_attached)
|
||||
prof_tdata_destroy(tsd_t *tsd, prof_tdata_t *tdata, bool even_if_attached)
|
||||
{
|
||||
|
||||
malloc_mutex_lock(tsdn, &tdatas_mtx);
|
||||
prof_tdata_destroy_locked(tsdn, tdata, even_if_attached);
|
||||
malloc_mutex_unlock(tsdn, &tdatas_mtx);
|
||||
malloc_mutex_lock(tsd_tsdn(tsd), &tdatas_mtx);
|
||||
prof_tdata_destroy_locked(tsd, tdata, even_if_attached);
|
||||
malloc_mutex_unlock(tsd_tsdn(tsd), &tdatas_mtx);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1913,7 +1910,7 @@ prof_tdata_detach(tsd_t *tsd, prof_tdata_t *tdata)
|
|||
destroy_tdata = false;
|
||||
malloc_mutex_unlock(tsd_tsdn(tsd), tdata->lock);
|
||||
if (destroy_tdata)
|
||||
prof_tdata_destroy(tsd_tsdn(tsd), tdata, true);
|
||||
prof_tdata_destroy(tsd, tdata, true);
|
||||
}
|
||||
|
||||
prof_tdata_t *
|
||||
|
|
@ -1926,8 +1923,8 @@ prof_tdata_reinit(tsd_t *tsd, prof_tdata_t *tdata)
|
|||
bool active = tdata->active;
|
||||
|
||||
prof_tdata_detach(tsd, tdata);
|
||||
return (prof_tdata_init_impl(tsd_tsdn(tsd), thr_uid, thr_discrim,
|
||||
thread_name, active));
|
||||
return (prof_tdata_init_impl(tsd, thr_uid, thr_discrim, thread_name,
|
||||
active));
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
@ -1956,30 +1953,30 @@ prof_tdata_reset_iter(prof_tdata_tree_t *tdatas, prof_tdata_t *tdata, void *arg)
|
|||
}
|
||||
|
||||
void
|
||||
prof_reset(tsdn_t *tsdn, size_t lg_sample)
|
||||
prof_reset(tsd_t *tsd, size_t lg_sample)
|
||||
{
|
||||
prof_tdata_t *next;
|
||||
|
||||
assert(lg_sample < (sizeof(uint64_t) << 3));
|
||||
|
||||
malloc_mutex_lock(tsdn, &prof_dump_mtx);
|
||||
malloc_mutex_lock(tsdn, &tdatas_mtx);
|
||||
malloc_mutex_lock(tsd_tsdn(tsd), &prof_dump_mtx);
|
||||
malloc_mutex_lock(tsd_tsdn(tsd), &tdatas_mtx);
|
||||
|
||||
lg_prof_sample = lg_sample;
|
||||
|
||||
next = NULL;
|
||||
do {
|
||||
prof_tdata_t *to_destroy = tdata_tree_iter(&tdatas, next,
|
||||
prof_tdata_reset_iter, (void *)tsdn);
|
||||
prof_tdata_reset_iter, (void *)tsd);
|
||||
if (to_destroy != NULL) {
|
||||
next = tdata_tree_next(&tdatas, to_destroy);
|
||||
prof_tdata_destroy_locked(tsdn, to_destroy, false);
|
||||
prof_tdata_destroy_locked(tsd, to_destroy, false);
|
||||
} else
|
||||
next = NULL;
|
||||
} while (next != NULL);
|
||||
|
||||
malloc_mutex_unlock(tsdn, &tdatas_mtx);
|
||||
malloc_mutex_unlock(tsdn, &prof_dump_mtx);
|
||||
malloc_mutex_unlock(tsd_tsdn(tsd), &tdatas_mtx);
|
||||
malloc_mutex_unlock(tsd_tsdn(tsd), &prof_dump_mtx);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -2189,7 +2186,7 @@ prof_boot1(void)
|
|||
}
|
||||
|
||||
bool
|
||||
prof_boot2(tsdn_t *tsdn)
|
||||
prof_boot2(tsd_t *tsd)
|
||||
{
|
||||
|
||||
cassert(config_prof);
|
||||
|
|
@ -2215,7 +2212,7 @@ prof_boot2(tsdn_t *tsdn)
|
|||
WITNESS_RANK_PROF_THREAD_ACTIVE_INIT))
|
||||
return (true);
|
||||
|
||||
if (ckh_new(tsdn, &bt2gctx, PROF_CKH_MINITEMS, prof_bt_hash,
|
||||
if (ckh_new(tsd, &bt2gctx, PROF_CKH_MINITEMS, prof_bt_hash,
|
||||
prof_bt_keycomp))
|
||||
return (true);
|
||||
if (malloc_mutex_init(&bt2gctx_mtx, "prof_bt2gctx",
|
||||
|
|
@ -2246,8 +2243,8 @@ prof_boot2(tsdn_t *tsdn)
|
|||
abort();
|
||||
}
|
||||
|
||||
gctx_locks = (malloc_mutex_t *)base_alloc(tsdn, PROF_NCTX_LOCKS
|
||||
* sizeof(malloc_mutex_t));
|
||||
gctx_locks = (malloc_mutex_t *)base_alloc(tsd_tsdn(tsd),
|
||||
PROF_NCTX_LOCKS * sizeof(malloc_mutex_t));
|
||||
if (gctx_locks == NULL)
|
||||
return (true);
|
||||
for (i = 0; i < PROF_NCTX_LOCKS; i++) {
|
||||
|
|
@ -2256,7 +2253,7 @@ prof_boot2(tsdn_t *tsdn)
|
|||
return (true);
|
||||
}
|
||||
|
||||
tdata_locks = (malloc_mutex_t *)base_alloc(tsdn,
|
||||
tdata_locks = (malloc_mutex_t *)base_alloc(tsd_tsdn(tsd),
|
||||
PROF_NTDATA_LOCKS * sizeof(malloc_mutex_t));
|
||||
if (tdata_locks == NULL)
|
||||
return (true);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue