5 Commits
2.1.2 ... 2.1.3

Author SHA1 Message Date
Jason Evans
ad11ee6a34 Merge branch 'dev' 2011-03-14 16:42:26 -07:00
Jason Evans
0e4d0d13f9 Update ChangeLog for 2.1.3. 2011-03-14 16:41:03 -07:00
Jason Evans
a8118233ec Fix a thread cache stats merging bug.
When a thread cache flushes objects to their arenas due to an abundance
of cached objects, it merges the allocation request count for the
associated size class, and increments a flush counter.  If none of the
flushed objects came from the thread's assigned arena, then the merging
wouldn't happen (though the counter would typically eventually be
merged), nor would the flush counter be incremented (a hard bug).  Fix
this via extra conditional code just after the flush loop.
2011-03-14 12:56:51 -07:00
Jason Evans
a7153a0d7d Fix a "thread.arena" mallctl bug.
Fix a variable reversal bug in mallctl("thread.arena", ...).
2011-03-14 11:43:54 -07:00
Jason Evans
814b9bda7f Fix a cpp logic regression.
Fix a cpp logic error that was introduced by the recent commit:
	Fix "thread.{de,}allocatedp" mallctl.
2011-03-06 23:03:33 -08:00
5 changed files with 55 additions and 18 deletions

View File

@@ -6,6 +6,14 @@ found in the git revision history:
http://www.canonware.com/cgi-bin/gitweb.cgi?p=jemalloc.git http://www.canonware.com/cgi-bin/gitweb.cgi?p=jemalloc.git
git://canonware.com/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) * 2.1.2 (March 2, 2011)
Bug fixes: Bug fixes:

View File

@@ -369,7 +369,7 @@ size_t s2u(size_t size);
size_t sa2u(size_t size, size_t alignment, size_t *run_size_p); size_t sa2u(size_t size, size_t alignment, size_t *run_size_p);
void malloc_write(const char *s); void malloc_write(const char *s);
arena_t *choose_arena(void); arena_t *choose_arena(void);
# ifdef NO_TLS # if (defined(JEMALLOC_STATS) && defined(NO_TLS))
thread_allocated_t *thread_allocated_get(void); thread_allocated_t *thread_allocated_get(void);
# endif # endif
#endif #endif
@@ -533,7 +533,7 @@ choose_arena(void)
return (ret); return (ret);
} }
#ifdef NO_TLS #if (defined(JEMALLOC_STATS) && defined(NO_TLS))
JEMALLOC_INLINE thread_allocated_t * JEMALLOC_INLINE thread_allocated_t *
thread_allocated_get(void) thread_allocated_get(void)
{ {

View File

@@ -1114,8 +1114,8 @@ thread_arena_ctl(const size_t *mib, size_t miblen, void *oldp, size_t *oldlenp,
unsigned newind, oldind; unsigned newind, oldind;
newind = oldind = choose_arena()->ind; newind = oldind = choose_arena()->ind;
WRITE(oldind, unsigned); WRITE(newind, unsigned);
READ(newind, unsigned); READ(oldind, unsigned);
if (newind != oldind) { if (newind != oldind) {
arena_t *arena; arena_t *arena;

View File

@@ -58,6 +58,9 @@ tcache_bin_flush_small(tcache_bin_t *tbin, size_t binind, unsigned rem
void *flush, *deferred, *ptr; void *flush, *deferred, *ptr;
unsigned i, nflush, ndeferred; unsigned i, nflush, ndeferred;
bool first_pass; bool first_pass;
#ifdef JEMALLOC_STATS
bool merged_stats = false;
#endif
assert(binind < nbins); assert(binind < nbins);
assert(rem <= tbin->ncached); 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); malloc_mutex_lock(&bin->lock);
#ifdef JEMALLOC_STATS #ifdef JEMALLOC_STATS
if (arena == tcache->arena) { if (arena == tcache->arena) {
assert(merged_stats == false);
merged_stats = true;
bin->stats.nflushes++; bin->stats.nflushes++;
bin->stats.nrequests += tbin->tstats.nrequests; bin->stats.nrequests += tbin->tstats.nrequests;
tbin->tstats.nrequests = 0; tbin->tstats.nrequests = 0;
@@ -119,6 +124,20 @@ tcache_bin_flush_small(tcache_bin_t *tbin, size_t binind, unsigned rem
first_pass = false; 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; tbin->ncached = rem;
if (tbin->ncached < tbin->low_water) if (tbin->ncached < tbin->low_water)

View File

@@ -2,10 +2,13 @@
#include <stdlib.h> #include <stdlib.h>
#include <pthread.h> #include <pthread.h>
#include <string.h> #include <string.h>
#include <assert.h>
#define JEMALLOC_MANGLE #define JEMALLOC_MANGLE
#include "jemalloc_test.h" #include "jemalloc_test.h"
#define NTHREADS 10
void * void *
thread_start(void *arg) thread_start(void *arg)
{ {
@@ -29,6 +32,15 @@ thread_start(void *arg)
return (void *)1; 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); return (NULL);
} }
@@ -40,7 +52,8 @@ main(void)
unsigned arena_ind; unsigned arena_ind;
size_t size; size_t size;
int err; int err;
pthread_t thread; pthread_t threads[NTHREADS];
unsigned i;
fprintf(stderr, "Test begin\n"); fprintf(stderr, "Test begin\n");
@@ -60,21 +73,18 @@ main(void)
goto RETURN; goto RETURN;
} }
if (pthread_create(&thread, NULL, thread_start, (void *)&arena_ind) for (i = 0; i < NTHREADS; i++) {
!= 0) { if (pthread_create(&threads[i], NULL, thread_start,
fprintf(stderr, "%s(): Error in pthread_create()\n", __func__); (void *)&arena_ind) != 0) {
ret = 1; fprintf(stderr, "%s(): Error in pthread_create()\n",
goto RETURN; __func__);
ret = 1;
goto RETURN;
}
} }
pthread_join(thread, (void *)&ret);
if (pthread_create(&thread, NULL, thread_start, (void *)&arena_ind) for (i = 0; i < NTHREADS; i++)
!= 0) { pthread_join(threads[i], (void *)&ret);
fprintf(stderr, "%s(): Error in pthread_create()\n", __func__);
ret = 1;
goto RETURN;
}
pthread_join(thread, (void *)&ret);
RETURN: RETURN:
fprintf(stderr, "Test end\n"); fprintf(stderr, "Test end\n");