Slow path, called only by arena_choose(). */
| 496 | |
| 497 | /* Slow path, called only by arena_choose(). */ |
| 498 | arena_t * |
| 499 | arena_choose_hard(tsd_t *tsd, bool internal) { |
| 500 | arena_t *ret JEMALLOC_CC_SILENCE_INIT(NULL); |
| 501 | |
| 502 | if (have_percpu_arena && PERCPU_ARENA_ENABLED(opt_percpu_arena)) { |
| 503 | unsigned choose = percpu_arena_choose(); |
| 504 | ret = arena_get(tsd_tsdn(tsd), choose, true); |
| 505 | assert(ret != NULL); |
| 506 | arena_bind(tsd, arena_ind_get(ret), false); |
| 507 | arena_bind(tsd, arena_ind_get(ret), true); |
| 508 | |
| 509 | return ret; |
| 510 | } |
| 511 | |
| 512 | if (narenas_auto > 1) { |
| 513 | unsigned i, j, choose[2], first_null; |
| 514 | bool is_new_arena[2]; |
| 515 | |
| 516 | /* |
| 517 | * Determine binding for both non-internal and internal |
| 518 | * allocation. |
| 519 | * |
| 520 | * choose[0]: For application allocation. |
| 521 | * choose[1]: For internal metadata allocation. |
| 522 | */ |
| 523 | |
| 524 | for (j = 0; j < 2; j++) { |
| 525 | choose[j] = 0; |
| 526 | is_new_arena[j] = false; |
| 527 | } |
| 528 | |
| 529 | first_null = narenas_auto; |
| 530 | malloc_mutex_lock(tsd_tsdn(tsd), &arenas_lock); |
| 531 | assert(arena_get(tsd_tsdn(tsd), 0, false) != NULL); |
| 532 | for (i = 1; i < narenas_auto; i++) { |
| 533 | if (arena_get(tsd_tsdn(tsd), i, false) != NULL) { |
| 534 | /* |
| 535 | * Choose the first arena that has the lowest |
| 536 | * number of threads assigned to it. |
| 537 | */ |
| 538 | for (j = 0; j < 2; j++) { |
| 539 | if (arena_nthreads_get(arena_get( |
| 540 | tsd_tsdn(tsd), i, false), !!j) < |
| 541 | arena_nthreads_get(arena_get( |
| 542 | tsd_tsdn(tsd), choose[j], false), |
| 543 | !!j)) { |
| 544 | choose[j] = i; |
| 545 | } |
| 546 | } |
| 547 | } else if (first_null == narenas_auto) { |
| 548 | /* |
| 549 | * Record the index of the first uninitialized |
| 550 | * arena, in case all extant arenas are in use. |
| 551 | * |
| 552 | * NB: It is possible for there to be |
| 553 | * discontinuities in terms of initialized |
| 554 | * versus uninitialized arenas, due to the |
| 555 | * "thread.arena" mallctl. |
no test coverage detected