| 381 | } |
| 382 | |
| 383 | static bool |
| 384 | check_background_thread_creation(tsd_t *tsd, unsigned *n_created, |
| 385 | bool *created_threads) { |
| 386 | bool ret = false; |
| 387 | if (likely(*n_created == n_background_threads)) { |
| 388 | return ret; |
| 389 | } |
| 390 | |
| 391 | tsdn_t *tsdn = tsd_tsdn(tsd); |
| 392 | malloc_mutex_unlock(tsdn, &background_thread_info[0].mtx); |
| 393 | for (unsigned i = 1; i < max_background_threads; i++) { |
| 394 | if (created_threads[i]) { |
| 395 | continue; |
| 396 | } |
| 397 | background_thread_info_t *info = &background_thread_info[i]; |
| 398 | malloc_mutex_lock(tsdn, &info->mtx); |
| 399 | /* |
| 400 | * In case of the background_thread_paused state because of |
| 401 | * arena reset, delay the creation. |
| 402 | */ |
| 403 | bool create = (info->state == background_thread_started); |
| 404 | malloc_mutex_unlock(tsdn, &info->mtx); |
| 405 | if (!create) { |
| 406 | continue; |
| 407 | } |
| 408 | |
| 409 | pre_reentrancy(tsd, NULL); |
| 410 | int err = background_thread_create_signals_masked(&info->thread, |
| 411 | NULL, background_thread_entry, (void *)(uintptr_t)i); |
| 412 | post_reentrancy(tsd); |
| 413 | |
| 414 | if (err == 0) { |
| 415 | (*n_created)++; |
| 416 | created_threads[i] = true; |
| 417 | } else { |
| 418 | malloc_printf("<jemalloc>: background thread " |
| 419 | "creation failed (%d)\n", err); |
| 420 | if (opt_abort) { |
| 421 | abort(); |
| 422 | } |
| 423 | } |
| 424 | /* Return to restart the loop since we unlocked. */ |
| 425 | ret = true; |
| 426 | break; |
| 427 | } |
| 428 | malloc_mutex_lock(tsdn, &background_thread_info[0].mtx); |
| 429 | |
| 430 | return ret; |
| 431 | } |
| 432 | |
| 433 | static void |
| 434 | background_thread0_work(tsd_t *tsd) { |
no test coverage detected