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:
parent
397f54aa46
commit
5033a9176a
41
src/prof.c
41
src/prof.c
@ -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);
|
prof_leave(tsd, tdata);
|
||||||
if (gctx.v == NULL) {
|
tgctx.p = prof_gctx_create(tsd_tsdn(tsd), bt);
|
||||||
prof_leave(tsd, tdata);
|
if (tgctx.v == NULL) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
btkey.p = &gctx.p->bt;
|
prof_enter(tsd, tdata);
|
||||||
if (ckh_insert(tsd, &bt2gctx, btkey.v, gctx.v)) {
|
if (ckh_search(&bt2gctx, bt, &btkey.v, &gctx.v)) {
|
||||||
/* OOM. */
|
gctx.p = tgctx.p;
|
||||||
prof_leave(tsd, tdata);
|
btkey.p = &gctx.p->bt;
|
||||||
idalloctm(tsd_tsdn(tsd), iealloc(tsd_tsdn(tsd), gctx.v),
|
if (ckh_insert(tsd, &bt2gctx, btkey.v, gctx.v)) {
|
||||||
gctx.v, NULL, true, true);
|
/* OOM. */
|
||||||
return true;
|
prof_leave(tsd, tdata);
|
||||||
|
idalloctm(tsd_tsdn(tsd), iealloc(tsd_tsdn(tsd),
|
||||||
|
gctx.v), gctx.v, NULL, true, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
new_gctx = true;
|
||||||
|
} else {
|
||||||
|
new_gctx = false;
|
||||||
}
|
}
|
||||||
new_gctx = true;
|
|
||||||
} else {
|
} 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);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user