Fix background thread creation.

The state initialization should be done before pthread_create.
This commit is contained in:
Qi Wang 2017-06-01 00:04:56 -07:00 committed by Jason Evans
parent fd0fa003e1
commit c84ec3e9da

View File

@ -317,34 +317,38 @@ background_thread_create(tsd_t *tsd, unsigned arena_ind) {
bool need_new_thread; bool need_new_thread;
malloc_mutex_lock(tsd_tsdn(tsd), &info->mtx); malloc_mutex_lock(tsd_tsdn(tsd), &info->mtx);
need_new_thread = background_thread_enabled() && !info->started; need_new_thread = background_thread_enabled() && !info->started;
if (need_new_thread) {
info->started = true;
background_thread_info_reinit(tsd_tsdn(tsd), info);
n_background_threads++;
}
malloc_mutex_unlock(tsd_tsdn(tsd), &info->mtx); malloc_mutex_unlock(tsd_tsdn(tsd), &info->mtx);
if (!need_new_thread) { if (!need_new_thread) {
return false; return false;
} }
pre_reentrancy(tsd); pre_reentrancy(tsd);
int err;
/* /*
* To avoid complications (besides reentrancy), create internal * To avoid complications (besides reentrancy), create internal
* background threads with the underlying pthread_create. * background threads with the underlying pthread_create.
*/ */
if ((err = pthread_create_wrapper(&info->thread, NULL, int err = pthread_create_wrapper(&info->thread, NULL,
background_thread_entry, (void *)thread_ind)) != 0) { background_thread_entry, (void *)thread_ind);
malloc_printf("<jemalloc>: arena %u background thread creation "
"failed (%d).\n", arena_ind, err);
}
post_reentrancy(tsd); post_reentrancy(tsd);
malloc_mutex_lock(tsd_tsdn(tsd), &info->mtx); if (err != 0) {
assert(info->started == false); malloc_printf("<jemalloc>: arena %u background thread creation "
if (err == 0) { "failed (%d).\n", arena_ind, err);
info->started = true; malloc_mutex_lock(tsd_tsdn(tsd), &info->mtx);
background_thread_info_reinit(tsd_tsdn(tsd), info); info->started = false;
n_background_threads++; n_background_threads--;
} malloc_mutex_unlock(tsd_tsdn(tsd), &info->mtx);
malloc_mutex_unlock(tsd_tsdn(tsd), &info->mtx);
return (err != 0); return true;
}
assert(info->started);
return false;
} }
bool bool