MCPcopy Create free account
hub / github.com/Snapchat/KeyDB / base_block_alloc

Function base_block_alloc

deps/jemalloc/src/base.c:247–301  ·  view source on GitHub ↗

* Allocate a block of virtual memory that is large enough to start with a * base_block_t header, followed by an object of specified size and alignment. * On success a pointer to the initialized base_block_t header is returned. */

Source from the content-addressed store, hash-verified

245 * On success a pointer to the initialized base_block_t header is returned.
246 */
247static base_block_t *
248base_block_alloc(tsdn_t *tsdn, base_t *base, extent_hooks_t *extent_hooks,
249 unsigned ind, pszind_t *pind_last, size_t *extent_sn_next, size_t size,
250 size_t alignment) {
251 alignment = ALIGNMENT_CEILING(alignment, QUANTUM);
252 size_t usize = ALIGNMENT_CEILING(size, alignment);
253 size_t header_size = sizeof(base_block_t);
254 size_t gap_size = ALIGNMENT_CEILING(header_size, alignment) -
255 header_size;
256 /*
257 * Create increasingly larger blocks in order to limit the total number
258 * of disjoint virtual memory ranges. Choose the next size in the page
259 * size class series (skipping size classes that are not a multiple of
260 * HUGEPAGE), or a size large enough to satisfy the requested size and
261 * alignment, whichever is larger.
262 */
263 size_t min_block_size = HUGEPAGE_CEILING(sz_psz2u(header_size + gap_size
264 + usize));
265 pszind_t pind_next = (*pind_last + 1 < sz_psz2ind(SC_LARGE_MAXCLASS)) ?
266 *pind_last + 1 : *pind_last;
267 size_t next_block_size = HUGEPAGE_CEILING(sz_pind2sz(pind_next));
268 size_t block_size = (min_block_size > next_block_size) ? min_block_size
269 : next_block_size;
270 base_block_t *block = (base_block_t *)base_map(tsdn, extent_hooks, ind,
271 block_size);
272 if (block == NULL) {
273 return NULL;
274 }
275
276 if (metadata_thp_madvise()) {
277 void *addr = (void *)block;
278 assert(((uintptr_t)addr & HUGEPAGE_MASK) == 0 &&
279 (block_size & HUGEPAGE_MASK) == 0);
280 if (opt_metadata_thp == metadata_thp_always) {
281 pages_huge(addr, block_size);
282 } else if (opt_metadata_thp == metadata_thp_auto &&
283 base != NULL) {
284 /* base != NULL indicates this is not a new base. */
285 malloc_mutex_lock(tsdn, &base->mtx);
286 base_auto_thp_switch(tsdn, base);
287 if (base->auto_thp_switched) {
288 pages_huge(addr, block_size);
289 }
290 malloc_mutex_unlock(tsdn, &base->mtx);
291 }
292 }
293
294 *pind_last = sz_psz2ind(block_size);
295 block->size = block_size;
296 block->next = NULL;
297 assert(block_size >= header_size);
298 base_extent_init(extent_sn_next, &block->extent,
299 (void *)((uintptr_t)block + header_size), block_size - header_size);
300 return block;
301}
302
303/*
304 * Allocate an extent that is at least as large as specified size, with

Callers 2

base_extent_allocFunction · 0.70
base_newFunction · 0.70

Calls 10

metadata_thp_madviseFunction · 0.85
base_auto_thp_switchFunction · 0.85
base_mapFunction · 0.70
pages_hugeFunction · 0.70
base_extent_initFunction · 0.70
sz_psz2uFunction · 0.50
sz_psz2indFunction · 0.50
sz_pind2szFunction · 0.50
malloc_mutex_lockFunction · 0.50
malloc_mutex_unlockFunction · 0.50

Tested by

no test coverage detected