Call prof_gctx_create() without owing bt2gctx_mtx.

This reduces the probability of allocating (and thereby indirectly
making a system call) while owning bt2gctx_mtx.  Unfortunately it is an
incomplete solution, because ckh insertion/deletion can also
allocate/deallocate, which requires more extensive changes to address.
This commit is contained in:
Jason Evans 2017-01-29 21:51:30 -08:00
parent 397f54aa46
commit 5033a9176a

View File

@ -708,7 +708,7 @@ prof_lookup_global(tsd_t *tsd, prof_bt_t *bt, prof_tdata_t *tdata,
union { union {
prof_gctx_t *p; prof_gctx_t *p;
void *v; void *v;
} gctx; } gctx, tgctx;
union { union {
prof_bt_t *p; prof_bt_t *p;
void *v; void *v;
@ -718,21 +718,32 @@ prof_lookup_global(tsd_t *tsd, prof_bt_t *bt, prof_tdata_t *tdata,
prof_enter(tsd, tdata); prof_enter(tsd, tdata);
if (ckh_search(&bt2gctx, bt, &btkey.v, &gctx.v)) { if (ckh_search(&bt2gctx, bt, &btkey.v, &gctx.v)) {
/* bt has never been seen before. Insert it. */ /* bt has never been seen before. Insert it. */
gctx.p = prof_gctx_create(tsd_tsdn(tsd), bt);
if (gctx.v == NULL) {
prof_leave(tsd, tdata); prof_leave(tsd, tdata);
tgctx.p = prof_gctx_create(tsd_tsdn(tsd), bt);
if (tgctx.v == NULL) {
return true; return true;
} }
prof_enter(tsd, tdata);
if (ckh_search(&bt2gctx, bt, &btkey.v, &gctx.v)) {
gctx.p = tgctx.p;
btkey.p = &gctx.p->bt; btkey.p = &gctx.p->bt;
if (ckh_insert(tsd, &bt2gctx, btkey.v, gctx.v)) { if (ckh_insert(tsd, &bt2gctx, btkey.v, gctx.v)) {
/* OOM. */ /* OOM. */
prof_leave(tsd, tdata); prof_leave(tsd, tdata);
idalloctm(tsd_tsdn(tsd), iealloc(tsd_tsdn(tsd), gctx.v), idalloctm(tsd_tsdn(tsd), iealloc(tsd_tsdn(tsd),
gctx.v, NULL, true, true); gctx.v), gctx.v, NULL, true, true);
return true; return true;
} }
new_gctx = true; new_gctx = true;
} else { } else {
new_gctx = false;
}
} else {
tgctx.v = NULL;
new_gctx = false;
}
if (!new_gctx) {
/* /*
* Increment nlimbo, in order to avoid a race condition with * Increment nlimbo, in order to avoid a race condition with
* prof_tctx_destroy()/prof_gctx_try_destroy(). * prof_tctx_destroy()/prof_gctx_try_destroy().
@ -741,6 +752,12 @@ prof_lookup_global(tsd_t *tsd, prof_bt_t *bt, prof_tdata_t *tdata,
gctx.p->nlimbo++; gctx.p->nlimbo++;
malloc_mutex_unlock(tsd_tsdn(tsd), gctx.p->lock); malloc_mutex_unlock(tsd_tsdn(tsd), gctx.p->lock);
new_gctx = false; new_gctx = false;
if (tgctx.v != NULL) {
/* Lost race to insert. */
idalloctm(tsd_tsdn(tsd), iealloc(tsd_tsdn(tsd),
tgctx.v), tgctx.v, NULL, true, true);
}
} }
prof_leave(tsd, tdata); prof_leave(tsd, tdata);