| 347 | } |
| 348 | |
| 349 | base_t * |
| 350 | base_new(tsdn_t *tsdn, unsigned ind, extent_hooks_t *extent_hooks) { |
| 351 | pszind_t pind_last = 0; |
| 352 | size_t extent_sn_next = 0; |
| 353 | base_block_t *block = base_block_alloc(tsdn, NULL, extent_hooks, ind, |
| 354 | &pind_last, &extent_sn_next, sizeof(base_t), QUANTUM); |
| 355 | if (block == NULL) { |
| 356 | return NULL; |
| 357 | } |
| 358 | |
| 359 | size_t gap_size; |
| 360 | size_t base_alignment = CACHELINE; |
| 361 | size_t base_size = ALIGNMENT_CEILING(sizeof(base_t), base_alignment); |
| 362 | base_t *base = (base_t *)base_extent_bump_alloc_helper(&block->extent, |
| 363 | &gap_size, base_size, base_alignment); |
| 364 | base->ind = ind; |
| 365 | atomic_store_p(&base->extent_hooks, extent_hooks, ATOMIC_RELAXED); |
| 366 | if (malloc_mutex_init(&base->mtx, "base", WITNESS_RANK_BASE, |
| 367 | malloc_mutex_rank_exclusive)) { |
| 368 | base_unmap(tsdn, extent_hooks, ind, block, block->size); |
| 369 | return NULL; |
| 370 | } |
| 371 | base->pind_last = pind_last; |
| 372 | base->extent_sn_next = extent_sn_next; |
| 373 | base->blocks = block; |
| 374 | base->auto_thp_switched = false; |
| 375 | for (szind_t i = 0; i < SC_NSIZES; i++) { |
| 376 | extent_heap_new(&base->avail[i]); |
| 377 | } |
| 378 | if (config_stats) { |
| 379 | base->allocated = sizeof(base_block_t); |
| 380 | base->resident = PAGE_CEILING(sizeof(base_block_t)); |
| 381 | base->mapped = block->size; |
| 382 | base->n_thp = (opt_metadata_thp == metadata_thp_always) && |
| 383 | metadata_thp_madvise() ? HUGEPAGE_CEILING(sizeof(base_block_t)) |
| 384 | >> LG_HUGEPAGE : 0; |
| 385 | assert(base->allocated <= base->resident); |
| 386 | assert(base->resident <= base->mapped); |
| 387 | assert(base->n_thp << LG_HUGEPAGE <= base->mapped); |
| 388 | } |
| 389 | base_extent_bump_alloc_post(base, &block->extent, gap_size, base, |
| 390 | base_size); |
| 391 | |
| 392 | return base; |
| 393 | } |
| 394 | |
| 395 | void |
| 396 | base_delete(tsdn_t *tsdn, base_t *base) { |