--- libc/malloc/arena.c.jj 2009-05-13 08:48:01.000000000 -0400 +++ libc/malloc/arena.c 2009-05-13 09:36:04.000000000 -0400 @@ -119,10 +119,17 @@ int __malloc_initialized = -1; #ifdef PER_THREAD #define arena_lock(ptr, size) do { \ - if(ptr) \ - (void)mutex_lock(&ptr->mutex); \ - else \ - ptr = arena_get2(ptr, (size)); \ + if (__builtin_expect (use_per_thread, 0)) { \ + if(ptr) \ + (void)mutex_lock(&ptr->mutex); \ + else \ + ptr = arena_get2(ptr, size); \ + } else { \ + if(ptr && !mutex_trylock(&ptr->mutex)) { \ + THREAD_STAT(++(ptr->stat_lock_direct)); \ + } else \ + ptr = arena_get2(ptr, (size)); \ + } \ } while(0) #else #define arena_lock(ptr, size) do { \ @@ -581,6 +588,8 @@ ptmalloc_init (void) { if (memcmp (envline, "ARENA_TEST", 10) == 0) mALLOPt(M_ARENA_TEST, atoi(&envline[11])); + else if (memcmp (envline, "PER_THREAD", 10) == 0) + use_per_thread = true; } break; #endif @@ -918,7 +927,8 @@ _int_new_arena(size_t size) (void)mutex_lock(&a->mutex); #ifdef PER_THREAD - (void)mutex_lock(&list_lock); + if (__builtin_expect (use_per_thread, 0)) + (void)mutex_lock(&list_lock); #endif /* Add the new arena to the global list. */ @@ -927,9 +937,11 @@ _int_new_arena(size_t size) main_arena.next = a; #ifdef PER_THREAD - ++narenas; + if (__builtin_expect (use_per_thread, 0)) { + ++narenas; - (void)mutex_unlock(&list_lock); + (void)mutex_unlock(&list_lock); + } #endif THREAD_STAT(++(a->stat_lock_loop)); @@ -1026,13 +1038,15 @@ arena_get2(a_tsd, size) mstate a_tsd; si #endif { mstate a; - #ifdef PER_THREAD - if ((a = get_free_list ()) == NULL - && (a = reused_arena ()) == NULL) - /* Nothing immediately available, so generate a new arena. */ - a = _int_new_arena(size); -#else + if (__builtin_expect (use_per_thread, 0)) { + if ((a = get_free_list ()) == NULL + && (a = reused_arena ()) == NULL) + /* Nothing immediately available, so generate a new arena. */ + a = _int_new_arena(size); + return a; + } +#endif if(!a_tsd) a = a_tsd = &main_arena; else { @@ -1076,7 +1090,6 @@ arena_get2(a_tsd, size) mstate a_tsd; si /* Nothing immediately available, so generate a new arena. */ a = _int_new_arena(size); (void)mutex_unlock(&list_lock); -#endif return a; } --- libc/malloc/hooks.c.jj 2009-05-13 08:48:01.000000000 -0400 +++ libc/malloc/hooks.c 2009-05-13 08:59:25.000000000 -0400 @@ -523,6 +523,10 @@ struct malloc_save_state { unsigned long mmapped_mem; unsigned long max_mmapped_mem; int using_malloc_checking; + unsigned long max_fast; + unsigned long arena_test; + unsigned long arena_max; + unsigned long narenas; }; Void_t* @@ -570,6 +574,16 @@ public_gET_STATe(void) ms->mmapped_mem = mp_.mmapped_mem; ms->max_mmapped_mem = mp_.max_mmapped_mem; ms->using_malloc_checking = using_malloc_checking; +#ifdef PER_THREAD + if (__builtin_expect (use_per_thread, 0)) + { + ms->version += 2; + ms->max_fast = get_max_fast(); + ms->arena_test = mp_.arena_test; + ms->arena_max = mp_.arena_max; + ms->narenas = narenas; + } +#endif (void)mutex_unlock(&main_arena.mutex); return (Void_t*)ms; } @@ -589,6 +603,10 @@ public_sET_STATe(Void_t* msptr) (void)mutex_lock(&main_arena.mutex); /* There are no fastchunks. */ clear_fastchunks(&main_arena); + if (ms->version >= 4) + set_max_fast(ms->max_fast); + else + set_max_fast(64); /* 64 used to be the value we always used. */ set_max_fast(DEFAULT_MXFAST); for (i=0; i<NFASTBINS; ++i) fastbin (&main_arena, i) = 0; @@ -635,6 +653,7 @@ public_sET_STATe(Void_t* msptr) b = b->fd; } } + use_per_thread = false; mp_.sbrk_base = ms->sbrk_base; main_arena.system_mem = ms->sbrked_mem_bytes; mp_.trim_threshold = ms->trim_threshold; @@ -665,6 +684,14 @@ public_sET_STATe(Void_t* msptr) using_malloc_checking = 0; } } +#ifdef PER_THREAD + if (ms->version >= 4) { + use_per_thread = true; + mp_.arena_test = ms->arena_test; + mp_.arena_max = ms->arena_max; + narenas = ms->narenas; + } +#endif check_malloc_state(&main_arena); (void)mutex_unlock(&main_arena.mutex); --- libc/malloc/malloc.c.jj 2009-05-13 08:48:01.000000000 -0400 +++ libc/malloc/malloc.c 2009-05-13 09:36:39.000000000 -0400 @@ -1311,7 +1311,11 @@ int __posix_memalign(void **, size_ #endif #ifndef DEFAULT_MXFAST -#define DEFAULT_MXFAST (64 * SIZE_SZ / 4) +# ifdef PER_THREAD +# define DEFAULT_MXFAST (__builtin_expect (use_per_thread, 0) ? 64 * SIZE_SZ / 4 : 64) +# else +# define DEFAULT_MXFAST 64 +# endif #endif @@ -2404,6 +2408,7 @@ static struct malloc_par mp_; /* Non public mallopt parameters. */ #define M_ARENA_TEST -7 #define M_ARENA_MAX -8 +static bool use_per_thread; #endif @@ -3739,9 +3744,12 @@ public_rEALLOc(Void_t* oldmem, size_t by (void)mutex_lock(&ar_ptr->mutex); #endif -#if !defined NO_THREADS && !defined PER_THREAD - /* As in malloc(), remember this arena for the next allocation. */ - tsd_setspecific(arena_key, (Void_t *)ar_ptr); +#if !defined NO_THREADS +# ifdef PER_THREAD + if (! __builtin_expect (use_per_thread, 0)) +# endif + /* As in malloc(), remember this arena for the next allocation. */ + tsd_setspecific(arena_key, (Void_t *)ar_ptr); #endif newp = _int_realloc(ar_ptr, oldp, nb);