summaryrefslogtreecommitdiffstats
path: root/jemalloc/src/prof.c
diff options
context:
space:
mode:
authorJason Evans <jasone@canonware.com>2010-04-14 22:07:37 (GMT)
committerJason Evans <jasone@canonware.com>2010-04-14 22:07:37 (GMT)
commit1af6ac42e303f229d5e8bb38252b1fb7371081b2 (patch)
tree0199eb3067af365c1c5268a49cf4b76d7efd2e15 /jemalloc/src/prof.c
parent552339916925c5432e51ab78864fe63edba9298d (diff)
parent5055f4516c8852e67668b0e746863a7d6a1c148e (diff)
downloadjemalloc-1.0.1.zip
jemalloc-1.0.1.tar.gz
jemalloc-1.0.1.tar.bz2
Merge branch 'dev'1.0.1
Diffstat (limited to 'jemalloc/src/prof.c')
-rw-r--r--jemalloc/src/prof.c114
1 files changed, 74 insertions, 40 deletions
diff --git a/jemalloc/src/prof.c b/jemalloc/src/prof.c
index 6326188..93904b8 100644
--- a/jemalloc/src/prof.c
+++ b/jemalloc/src/prof.c
@@ -48,7 +48,7 @@ static malloc_mutex_t bt2ctx_mtx;
static __thread ckh_t *bt2cnt_tls JEMALLOC_ATTR(tls_model("initial-exec"));
/*
- * Same contents as b2cnt, but initialized such that the TSD destructor is
+ * Same contents as b2cnt_tls, but initialized such that the TSD destructor is
* called when a thread exits, so that bt2cnt_tls contents can be merged,
* unlinked, and deallocated.
*/
@@ -100,7 +100,7 @@ static _Unwind_Reason_Code prof_unwind_callback(
#endif
static void prof_backtrace(prof_bt_t *bt, unsigned nignore, unsigned max);
static prof_thr_cnt_t *prof_lookup(prof_bt_t *bt);
-static void prof_cnt_set(const void *ptr, prof_thr_cnt_t *cnt);
+static void prof_ctx_set(const void *ptr, prof_ctx_t *ctx);
static bool prof_flush(bool propagate_err);
static bool prof_write(const char *s, bool propagate_err);
static void prof_ctx_merge(prof_ctx_t *ctx, prof_cnt_t *cnt_all,
@@ -450,6 +450,7 @@ prof_lookup(prof_bt_t *bt)
return (NULL);
}
bt2cnt_tls = bt2cnt;
+ pthread_setspecific(bt2cnt_tsd, bt2cnt);
}
if (ckh_search(bt2cnt, bt, NULL, (void **)&ret)) {
@@ -475,6 +476,7 @@ prof_lookup(prof_bt_t *bt)
idalloc(ctx);
return (NULL);
}
+ ctx->bt = btkey;
if (malloc_mutex_init(&ctx->lock)) {
prof_leave();
idalloc(btkey);
@@ -580,10 +582,10 @@ prof_alloc_prep(size_t size)
return (ret);
}
-prof_thr_cnt_t *
-prof_cnt_get(const void *ptr)
+prof_ctx_t *
+prof_ctx_get(const void *ptr)
{
- prof_thr_cnt_t *ret;
+ prof_ctx_t *ret;
arena_chunk_t *chunk;
assert(ptr != NULL);
@@ -593,15 +595,15 @@ prof_cnt_get(const void *ptr)
/* Region. */
assert(chunk->arena->magic == ARENA_MAGIC);
- ret = arena_prof_cnt_get(ptr);
+ ret = arena_prof_ctx_get(ptr);
} else
- ret = huge_prof_cnt_get(ptr);
+ ret = huge_prof_ctx_get(ptr);
return (ret);
}
static void
-prof_cnt_set(const void *ptr, prof_thr_cnt_t *cnt)
+prof_ctx_set(const void *ptr, prof_ctx_t *ctx)
{
arena_chunk_t *chunk;
@@ -612,9 +614,9 @@ prof_cnt_set(const void *ptr, prof_thr_cnt_t *cnt)
/* Region. */
assert(chunk->arena->magic == ARENA_MAGIC);
- arena_prof_cnt_set(ptr, cnt);
+ arena_prof_ctx_set(ptr, ctx);
} else
- huge_prof_cnt_set(ptr, cnt);
+ huge_prof_ctx_set(ptr, ctx);
}
static inline void
@@ -649,10 +651,11 @@ prof_malloc(const void *ptr, prof_thr_cnt_t *cnt)
assert(ptr != NULL);
- prof_cnt_set(ptr, cnt);
prof_sample_accum_update(size);
if ((uintptr_t)cnt > (uintptr_t)1U) {
+ prof_ctx_set(ptr, cnt->ctx);
+
cnt->epoch++;
/*********/
mb_write();
@@ -668,30 +671,49 @@ prof_malloc(const void *ptr, prof_thr_cnt_t *cnt)
/*********/
mb_write();
/*********/
- }
+ } else
+ prof_ctx_set(ptr, (prof_ctx_t *)(uintptr_t)1U);
}
void
prof_realloc(const void *ptr, prof_thr_cnt_t *cnt, const void *old_ptr,
- size_t old_size, prof_thr_cnt_t *old_cnt)
+ size_t old_size, prof_ctx_t *old_ctx)
{
size_t size = isalloc(ptr);
+ prof_thr_cnt_t *told_cnt;
- if (ptr != NULL) {
- prof_cnt_set(ptr, cnt);
+ if (ptr != NULL)
prof_sample_accum_update(size);
- }
- if ((uintptr_t)old_cnt > (uintptr_t)1U)
- old_cnt->epoch++;
- if ((uintptr_t)cnt > (uintptr_t)1U)
+ if ((uintptr_t)old_ctx > (uintptr_t)1U) {
+ told_cnt = prof_lookup(old_ctx->bt);
+ if (told_cnt == NULL) {
+ /*
+ * It's too late to propagate OOM for this realloc(),
+ * so operate directly on old_cnt->ctx->cnt_merged.
+ */
+ malloc_mutex_lock(&old_ctx->lock);
+ old_ctx->cnt_merged.curobjs--;
+ old_ctx->cnt_merged.curbytes -= old_size;
+ malloc_mutex_unlock(&old_ctx->lock);
+ told_cnt = (prof_thr_cnt_t *)(uintptr_t)1U;
+ }
+ } else
+ told_cnt = (prof_thr_cnt_t *)(uintptr_t)1U;
+
+ if ((uintptr_t)told_cnt > (uintptr_t)1U)
+ told_cnt->epoch++;
+ if ((uintptr_t)cnt > (uintptr_t)1U) {
+ prof_ctx_set(ptr, cnt->ctx);
cnt->epoch++;
+ } else
+ prof_ctx_set(ptr, (prof_ctx_t *)(uintptr_t)1U);
/*********/
mb_write();
/*********/
- if ((uintptr_t)old_cnt > (uintptr_t)1U) {
- old_cnt->cnts.curobjs--;
- old_cnt->cnts.curbytes -= old_size;
+ if ((uintptr_t)told_cnt > (uintptr_t)1U) {
+ told_cnt->cnts.curobjs--;
+ told_cnt->cnts.curbytes -= old_size;
}
if ((uintptr_t)cnt > (uintptr_t)1U) {
cnt->cnts.curobjs++;
@@ -702,8 +724,8 @@ prof_realloc(const void *ptr, prof_thr_cnt_t *cnt, const void *old_ptr,
/*********/
mb_write();
/*********/
- if ((uintptr_t)old_cnt > (uintptr_t)1U)
- old_cnt->epoch++;
+ if ((uintptr_t)told_cnt > (uintptr_t)1U)
+ told_cnt->epoch++;
if ((uintptr_t)cnt > (uintptr_t)1U)
cnt->epoch++;
/*********/
@@ -713,24 +735,36 @@ prof_realloc(const void *ptr, prof_thr_cnt_t *cnt, const void *old_ptr,
void
prof_free(const void *ptr)
{
- prof_thr_cnt_t *cnt = prof_cnt_get(ptr);
+ prof_ctx_t *ctx = prof_ctx_get(ptr);
- if ((uintptr_t)cnt > (uintptr_t)1) {
+ if ((uintptr_t)ctx > (uintptr_t)1) {
size_t size = isalloc(ptr);
-
- cnt->epoch++;
- /*********/
- mb_write();
- /*********/
- cnt->cnts.curobjs--;
- cnt->cnts.curbytes -= size;
- /*********/
- mb_write();
- /*********/
- cnt->epoch++;
- /*********/
- mb_write();
- /*********/
+ prof_thr_cnt_t *tcnt = prof_lookup(ctx->bt);
+
+ if (tcnt != NULL) {
+ tcnt->epoch++;
+ /*********/
+ mb_write();
+ /*********/
+ tcnt->cnts.curobjs--;
+ tcnt->cnts.curbytes -= size;
+ /*********/
+ mb_write();
+ /*********/
+ tcnt->epoch++;
+ /*********/
+ mb_write();
+ /*********/
+ } else {
+ /*
+ * OOM during free() cannot be propagated, so operate
+ * directly on cnt->ctx->cnt_merged.
+ */
+ malloc_mutex_lock(&ctx->lock);
+ ctx->cnt_merged.curobjs--;
+ ctx->cnt_merged.curbytes -= size;
+ malloc_mutex_unlock(&ctx->lock);
+ }
}
}