]> git.saurik.com Git - redis.git/blobdiff - deps/jemalloc/src/prof.c
Merge pull request #496 from pietern/2.6-makeinstall
[redis.git] / deps / jemalloc / src / prof.c
index 8370042b482b4e129a37b3ee86e12d50c9163e67..8a144b4e46c9e7e01e4b8df45021f4dedf2071b1 100644 (file)
@@ -474,11 +474,23 @@ prof_lookup(prof_bt_t *bt)
                        /*
                         * Artificially raise curobjs, in order to avoid a race
                         * condition with prof_ctx_merge()/prof_ctx_destroy().
                        /*
                         * Artificially raise curobjs, in order to avoid a race
                         * condition with prof_ctx_merge()/prof_ctx_destroy().
+                        *
+                        * No locking is necessary for ctx here because no other
+                        * threads have had the opportunity to fetch it from
+                        * bt2ctx yet.
                         */
                        ctx.p->cnt_merged.curobjs++;
                        new_ctx = true;
                         */
                        ctx.p->cnt_merged.curobjs++;
                        new_ctx = true;
-               } else
+               } else {
+                       /*
+                        * Artificially raise curobjs, in order to avoid a race
+                        * condition with prof_ctx_merge()/prof_ctx_destroy().
+                        */
+                       malloc_mutex_lock(&ctx.p->lock);
+                       ctx.p->cnt_merged.curobjs++;
+                       malloc_mutex_unlock(&ctx.p->lock);
                        new_ctx = false;
                        new_ctx = false;
+               }
                prof_leave();
 
                /* Link a prof_thd_cnt_t into ctx for this thread. */
                prof_leave();
 
                /* Link a prof_thd_cnt_t into ctx for this thread. */
@@ -491,8 +503,9 @@ prof_lookup(prof_bt_t *bt)
                         */
                        ret.p = ql_last(&prof_tdata->lru_ql, lru_link);
                        assert(ret.v != NULL);
                         */
                        ret.p = ql_last(&prof_tdata->lru_ql, lru_link);
                        assert(ret.v != NULL);
-                       ckh_remove(&prof_tdata->bt2cnt, ret.p->ctx->bt, NULL,
-                           NULL);
+                       if (ckh_remove(&prof_tdata->bt2cnt, ret.p->ctx->bt,
+                           NULL, NULL))
+                               assert(false);
                        ql_remove(&prof_tdata->lru_ql, ret.p, lru_link);
                        prof_ctx_merge(ret.p->ctx, ret.p);
                        /* ret can now be re-used. */
                        ql_remove(&prof_tdata->lru_ql, ret.p, lru_link);
                        prof_ctx_merge(ret.p->ctx, ret.p);
                        /* ret can now be re-used. */
@@ -503,11 +516,8 @@ prof_lookup(prof_bt_t *bt)
                        /* Allocate and partially initialize a new cnt. */
                        ret.v = imalloc(sizeof(prof_thr_cnt_t));
                        if (ret.p == NULL) {
                        /* Allocate and partially initialize a new cnt. */
                        ret.v = imalloc(sizeof(prof_thr_cnt_t));
                        if (ret.p == NULL) {
-                               if (new_ctx) {
-                                       malloc_mutex_lock(&ctx.p->lock);
-                                       ctx.p->cnt_merged.curobjs--;
-                                       malloc_mutex_unlock(&ctx.p->lock);
-                               }
+                               if (new_ctx)
+                                       prof_ctx_destroy(ctx.p);
                                return (NULL);
                        }
                        ql_elm_new(ret.p, cnts_link);
                                return (NULL);
                        }
                        ql_elm_new(ret.p, cnts_link);
@@ -518,19 +528,15 @@ prof_lookup(prof_bt_t *bt)
                ret.p->epoch = 0;
                memset(&ret.p->cnts, 0, sizeof(prof_cnt_t));
                if (ckh_insert(&prof_tdata->bt2cnt, btkey.v, ret.v)) {
                ret.p->epoch = 0;
                memset(&ret.p->cnts, 0, sizeof(prof_cnt_t));
                if (ckh_insert(&prof_tdata->bt2cnt, btkey.v, ret.v)) {
-                       if (new_ctx) {
-                               malloc_mutex_lock(&ctx.p->lock);
-                               ctx.p->cnt_merged.curobjs--;
-                               malloc_mutex_unlock(&ctx.p->lock);
-                       }
+                       if (new_ctx)
+                               prof_ctx_destroy(ctx.p);
                        idalloc(ret.v);
                        return (NULL);
                }
                ql_head_insert(&prof_tdata->lru_ql, ret.p, lru_link);
                malloc_mutex_lock(&ctx.p->lock);
                ql_tail_insert(&ctx.p->cnts_ql, ret.p, cnts_link);
                        idalloc(ret.v);
                        return (NULL);
                }
                ql_head_insert(&prof_tdata->lru_ql, ret.p, lru_link);
                malloc_mutex_lock(&ctx.p->lock);
                ql_tail_insert(&ctx.p->cnts_ql, ret.p, cnts_link);
-               if (new_ctx)
-                       ctx.p->cnt_merged.curobjs--;
+               ctx.p->cnt_merged.curobjs--;
                malloc_mutex_unlock(&ctx.p->lock);
        } else {
                /* Move ret to the front of the LRU. */
                malloc_mutex_unlock(&ctx.p->lock);
        } else {
                /* Move ret to the front of the LRU. */
@@ -644,11 +650,10 @@ prof_ctx_destroy(prof_ctx_t *ctx)
 
        /*
         * Check that ctx is still unused by any thread cache before destroying
 
        /*
         * Check that ctx is still unused by any thread cache before destroying
-        * it.  prof_lookup() interlocks bt2ctx_mtx and ctx->lock in order to
-        * avoid a race condition with this function, and prof_ctx_merge()
-        * artificially raises ctx->cnt_merged.curobjs in order to avoid a race
-        * between the main body of prof_ctx_merge() and entry into this
-        * function.
+        * it.  prof_lookup() artificially raises ctx->cnt_merge.curobjs in
+        * order to avoid a race condition with this function, as does
+        * prof_ctx_merge() in order to avoid a race between the main body of
+        * prof_ctx_merge() and entry into this function.
         */
        prof_enter();
        malloc_mutex_lock(&ctx->lock);
         */
        prof_enter();
        malloc_mutex_lock(&ctx->lock);
@@ -657,7 +662,8 @@ prof_ctx_destroy(prof_ctx_t *ctx)
                assert(ctx->cnt_merged.accumobjs == 0);
                assert(ctx->cnt_merged.accumbytes == 0);
                /* Remove ctx from bt2ctx. */
                assert(ctx->cnt_merged.accumobjs == 0);
                assert(ctx->cnt_merged.accumbytes == 0);
                /* Remove ctx from bt2ctx. */
-               ckh_remove(&bt2ctx, ctx->bt, NULL, NULL);
+               if (ckh_remove(&bt2ctx, ctx->bt, NULL, NULL))
+                       assert(false);
                prof_leave();
                /* Destroy ctx. */
                malloc_mutex_unlock(&ctx->lock);
                prof_leave();
                /* Destroy ctx. */
                malloc_mutex_unlock(&ctx->lock);
@@ -665,7 +671,10 @@ prof_ctx_destroy(prof_ctx_t *ctx)
                malloc_mutex_destroy(&ctx->lock);
                idalloc(ctx);
        } else {
                malloc_mutex_destroy(&ctx->lock);
                idalloc(ctx);
        } else {
-               /* Compensate for increment in prof_ctx_merge(). */
+               /*
+                * Compensate for increment in prof_ctx_merge() or
+                * prof_lookup().
+                */
                ctx->cnt_merged.curobjs--;
                malloc_mutex_unlock(&ctx->lock);
                prof_leave();
                ctx->cnt_merged.curobjs--;
                malloc_mutex_unlock(&ctx->lock);
                prof_leave();
@@ -1072,7 +1081,7 @@ prof_bt_hash(const void *key, unsigned minbits, size_t *hash1, size_t *hash2)
        } else {
                ret1 = h;
                ret2 = hash(bt->vec, bt->len * sizeof(void *),
        } else {
                ret1 = h;
                ret2 = hash(bt->vec, bt->len * sizeof(void *),
-                   0x8432a476666bbc13U);
+                   0x8432a476666bbc13LLU);
        }
 
        *hash1 = ret1;
        }
 
        *hash1 = ret1;
@@ -1109,7 +1118,6 @@ prof_tdata_init(void)
 
        prof_tdata->vec = imalloc(sizeof(void *) * prof_bt_max);
        if (prof_tdata->vec == NULL) {
 
        prof_tdata->vec = imalloc(sizeof(void *) * prof_bt_max);
        if (prof_tdata->vec == NULL) {
-
                ckh_delete(&prof_tdata->bt2cnt);
                idalloc(prof_tdata);
                return (NULL);
                ckh_delete(&prof_tdata->bt2cnt);
                idalloc(prof_tdata);
                return (NULL);
@@ -1127,33 +1135,26 @@ prof_tdata_init(void)
 static void
 prof_tdata_cleanup(void *arg)
 {
 static void
 prof_tdata_cleanup(void *arg)
 {
-       prof_tdata_t *prof_tdata;
+       prof_thr_cnt_t *cnt;
+       prof_tdata_t *prof_tdata = (prof_tdata_t *)arg;
 
 
-       prof_tdata = PROF_TCACHE_GET();
-       if (prof_tdata != NULL) {
-               prof_thr_cnt_t *cnt;
-
-               /*
-                * Delete the hash table.  All of its contents can still be
-                * iterated over via the LRU.
-                */
-               ckh_delete(&prof_tdata->bt2cnt);
+       /*
+        * Delete the hash table.  All of its contents can still be iterated
+        * over via the LRU.
+        */
+       ckh_delete(&prof_tdata->bt2cnt);
 
 
-               /*
-                * Iteratively merge cnt's into the global stats and delete
-                * them.
-                */
-               while ((cnt = ql_last(&prof_tdata->lru_ql, lru_link)) != NULL) {
-                       prof_ctx_merge(cnt->ctx, cnt);
-                       ql_remove(&prof_tdata->lru_ql, cnt, lru_link);
-                       idalloc(cnt);
-               }
+       /* Iteratively merge cnt's into the global stats and delete them. */
+       while ((cnt = ql_last(&prof_tdata->lru_ql, lru_link)) != NULL) {
+               ql_remove(&prof_tdata->lru_ql, cnt, lru_link);
+               prof_ctx_merge(cnt->ctx, cnt);
+               idalloc(cnt);
+       }
 
 
-               idalloc(prof_tdata->vec);
+       idalloc(prof_tdata->vec);
 
 
-               idalloc(prof_tdata);
-               PROF_TCACHE_SET(NULL);
-       }
+       idalloc(prof_tdata);
+       PROF_TCACHE_SET(NULL);
 }
 
 void
 }
 
 void