diff --git a/jemalloc/ChangeLog b/jemalloc/ChangeLog index d042982d..08526c80 100644 --- a/jemalloc/ChangeLog +++ b/jemalloc/ChangeLog @@ -6,6 +6,14 @@ found in the git revision history: http://www.canonware.com/cgi-bin/gitweb.cgi?p=jemalloc.git git://canonware.com/jemalloc.git +* 2.1.3 (March 14, 2011) + + Bug fixes: + - Fix a cpp logic regression (due to the "thread.{de,}allocatedp" mallctl fix + for OS X in 2.1.2). + - Fix a "thread.arena" mallctl bug. + - Fix a thread cache stats merging bug. + * 2.1.2 (March 2, 2011) Bug fixes: diff --git a/jemalloc/include/jemalloc/internal/jemalloc_internal.h.in b/jemalloc/include/jemalloc/internal/jemalloc_internal.h.in index a27416ce..aab2bfb2 100644 --- a/jemalloc/include/jemalloc/internal/jemalloc_internal.h.in +++ b/jemalloc/include/jemalloc/internal/jemalloc_internal.h.in @@ -369,7 +369,7 @@ size_t s2u(size_t size); size_t sa2u(size_t size, size_t alignment, size_t *run_size_p); void malloc_write(const char *s); arena_t *choose_arena(void); -# ifdef NO_TLS +# if (defined(JEMALLOC_STATS) && defined(NO_TLS)) thread_allocated_t *thread_allocated_get(void); # endif #endif @@ -533,7 +533,7 @@ choose_arena(void) return (ret); } -#ifdef NO_TLS +#if (defined(JEMALLOC_STATS) && defined(NO_TLS)) JEMALLOC_INLINE thread_allocated_t * thread_allocated_get(void) { diff --git a/jemalloc/src/ctl.c b/jemalloc/src/ctl.c index c37b4e75..1b28da47 100644 --- a/jemalloc/src/ctl.c +++ b/jemalloc/src/ctl.c @@ -1114,8 +1114,8 @@ thread_arena_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp, unsigned newind, oldind; newind = oldind = choose_arena()->ind; - WRITE(oldind, unsigned); - READ(newind, unsigned); + WRITE(newind, unsigned); + READ(oldind, unsigned); if (newind != oldind) { arena_t *arena; diff --git a/jemalloc/src/tcache.c b/jemalloc/src/tcache.c index cbbe7a11..e9b067d4 100644 --- a/jemalloc/src/tcache.c +++ b/jemalloc/src/tcache.c @@ -58,6 +58,9 @@ tcache_bin_flush_small(tcache_bin_t *tbin, size_t binind, unsigned rem void *flush, *deferred, *ptr; unsigned i, nflush, ndeferred; bool first_pass; +#ifdef JEMALLOC_STATS + bool merged_stats = false; +#endif assert(binind < nbins); assert(rem <= tbin->ncached); @@ -82,6 +85,8 @@ tcache_bin_flush_small(tcache_bin_t *tbin, size_t binind, unsigned rem malloc_mutex_lock(&bin->lock); #ifdef JEMALLOC_STATS if (arena == tcache->arena) { + assert(merged_stats == false); + merged_stats = true; bin->stats.nflushes++; bin->stats.nrequests += tbin->tstats.nrequests; tbin->tstats.nrequests = 0; @@ -119,6 +124,20 @@ tcache_bin_flush_small(tcache_bin_t *tbin, size_t binind, unsigned rem first_pass = false; } } +#ifdef JEMALLOC_STATS + if (merged_stats == false) { + /* + * The flush loop didn't happen to flush to this thread's + * arena, so the stats didn't get merged. Manually do so now. + */ + arena_bin_t *bin = &tcache->arena->bins[binind]; + malloc_mutex_lock(&bin->lock); + bin->stats.nflushes++; + bin->stats.nrequests += tbin->tstats.nrequests; + tbin->tstats.nrequests = 0; + malloc_mutex_unlock(&bin->lock); + } +#endif tbin->ncached = rem; if (tbin->ncached < tbin->low_water) diff --git a/jemalloc/test/thread_arena.c b/jemalloc/test/thread_arena.c index bd884e1f..ef8d6817 100644 --- a/jemalloc/test/thread_arena.c +++ b/jemalloc/test/thread_arena.c @@ -2,10 +2,13 @@ #include #include #include +#include #define JEMALLOC_MANGLE #include "jemalloc_test.h" +#define NTHREADS 10 + void * thread_start(void *arg) { @@ -29,6 +32,15 @@ thread_start(void *arg) return (void *)1; } + size = sizeof(arena_ind); + if ((err = JEMALLOC_P(mallctl)("thread.arena", &arena_ind, &size, NULL, + 0))) { + fprintf(stderr, "%s(): Error in mallctl(): %s\n", __func__, + strerror(err)); + return (void *)1; + } + assert(arena_ind == main_arena_ind); + return (NULL); } @@ -40,7 +52,8 @@ main(void) unsigned arena_ind; size_t size; int err; - pthread_t thread; + pthread_t threads[NTHREADS]; + unsigned i; fprintf(stderr, "Test begin\n"); @@ -60,21 +73,18 @@ main(void) goto RETURN; } - if (pthread_create(&thread, NULL, thread_start, (void *)&arena_ind) - != 0) { - fprintf(stderr, "%s(): Error in pthread_create()\n", __func__); - ret = 1; - goto RETURN; + for (i = 0; i < NTHREADS; i++) { + if (pthread_create(&threads[i], NULL, thread_start, + (void *)&arena_ind) != 0) { + fprintf(stderr, "%s(): Error in pthread_create()\n", + __func__); + ret = 1; + goto RETURN; + } } - pthread_join(thread, (void *)&ret); - if (pthread_create(&thread, NULL, thread_start, (void *)&arena_ind) - != 0) { - fprintf(stderr, "%s(): Error in pthread_create()\n", __func__); - ret = 1; - goto RETURN; - } - pthread_join(thread, (void *)&ret); + for (i = 0; i < NTHREADS; i++) + pthread_join(threads[i], (void *)&ret); RETURN: fprintf(stderr, "Test end\n");