diff --git a/doc/jemalloc.xml.in b/doc/jemalloc.xml.in index 801fd497..ab90e30f 100644 --- a/doc/jemalloc.xml.in +++ b/doc/jemalloc.xml.in @@ -1554,45 +1554,45 @@ malloc_conf = "xmalloc:true";]]> (extent_hooks_t) rw - Get or set the chunk management hook functions for arena - <i>. The functions must be capable of operating on all extant - chunks associated with arena <i>, usually by passing unknown - chunks to the replaced functions. In practice, it is feasible to - control allocation for arenas created via Get or set the extent management hook functions for + arena <i>. The functions must be capable of operating on all + extant extents associated with arena <i>, usually by passing + unknown extents to the replaced functions. In practice, it is feasible + to control allocation for arenas created via arenas.extend such - that all chunks originate from an application-supplied chunk allocator + that all extents originate from an application-supplied extent allocator (by setting custom extent hook functions just after arena creation), but - the automatically created arenas may have already created chunks prior - to the application having an opportunity to take over chunk + the automatically created arenas may have already created extents prior + to the application having an opportunity to take over extent allocation. The extent_hooks_t structure comprises function pointers which are described individually below. jemalloc uses these - functions to manage chunk lifetime, which starts off with allocation of + functions to manage extent lifetime, which starts off with allocation of mapped committed memory, in the simplest case followed by deallocation. - However, there are performance and platform reasons to retain chunks for - later reuse. Cleanup attempts cascade from deallocation to decommit to - purging, which gives the chunk management functions opportunities to + However, there are performance and platform reasons to retain extents + for later reuse. Cleanup attempts cascade from deallocation to decommit + to purging, which gives the extent management functions opportunities to reject the most permanent cleanup operations in favor of less permanent - (and often less costly) operations. The chunk splitting and merging + (and often less costly) operations. The extent splitting and merging operations can also be opted out of, but this is mainly intended to support platforms on which virtual memory mappings provided by the operating system kernel do not automatically coalesce and split, e.g. Windows. - typedef void *(chunk_alloc_t) - void *chunk + typedef void *(extent_alloc_t) + void *new_addr size_t size size_t alignment bool *zero @@ -1600,62 +1600,62 @@ typedef struct { unsigned arena_ind - A chunk allocation function conforms to the - chunk_alloc_t type and upon success returns a pointer to + An extent allocation function conforms to the + extent_alloc_t type and upon success returns a pointer to size bytes of mapped memory on behalf of arena - arena_ind such that the chunk's base address is a - multiple of alignment, as well as setting - *zero to indicate whether the chunk is zeroed and - *commit to indicate whether the chunk is + arena_ind such that the extent's base address is + a multiple of alignment, as well as setting + *zero to indicate whether the extent is zeroed + and *commit to indicate whether the extent is committed. Upon error the function returns NULL and leaves *zero and *commit unmodified. The - size parameter is always a multiple of the chunk + size parameter is always a multiple of the page size. The alignment parameter is always a power - of two at least as large as the chunk size. Zeroing is mandatory if + of two at least as large as the page size. Zeroing is mandatory if *zero is true upon function entry. Committing is mandatory if *commit is true upon function entry. - If chunk is not NULL, the - returned pointer must be chunk on success or + If new_addr is not NULL, the + returned pointer must be new_addr on success or NULL on error. Committed memory may be committed in absolute terms as on a system that does not overcommit, or in implicit terms as on a system that overcommits and satisfies physical memory needs on demand via soft page faults. Note that replacing the - default chunk allocation function makes the arena's arena.<i>.dss setting irrelevant. - typedef bool (chunk_dalloc_t) - void *chunk + typedef bool (extent_dalloc_t) + void *addr size_t size bool committed unsigned arena_ind - A chunk deallocation function conforms to the - chunk_dalloc_t type and deallocates a - chunk of given size with + An extent deallocation function conforms to the + extent_dalloc_t type and deallocates an extent at given + addr and size with committed/decommited memory as indicated, on behalf of arena arena_ind, returning false upon success. If the function returns true, this indicates opt-out from - deallocation; the virtual memory mapping associated with the chunk + deallocation; the virtual memory mapping associated with the extent remains mapped, in the same commit state, and available for future use, in which case it will be automatically retained for later reuse. - typedef bool (chunk_commit_t) - void *chunk + typedef bool (extent_commit_t) + void *addr size_t size size_t offset size_t length unsigned arena_ind - A chunk commit function conforms to the - chunk_commit_t type and commits zeroed physical memory to - back pages within a chunk of given + An extent commit function conforms to the + extent_commit_t type and commits zeroed physical memory to + back pages within an extent at given addr and size at offset bytes, extending for length on behalf of arena arena_ind, returning false upon success. @@ -1666,46 +1666,48 @@ typedef struct { physical memory to satisfy the request. - typedef bool (chunk_decommit_t) - void *chunk + typedef bool (extent_decommit_t) + void *addr size_t size size_t offset size_t length unsigned arena_ind - A chunk decommit function conforms to the - chunk_decommit_t type and decommits any physical memory - that is backing pages within a chunk of given - size at offset bytes, - extending for length on behalf of arena + An extent decommit function conforms to the + extent_decommit_t type and decommits any physical memory + that is backing pages within an extent at given + addr and size at + offset bytes, extending for + length on behalf of arena arena_ind, returning false upon success, in which - case the pages will be committed via the chunk commit function before + case the pages will be committed via the extent commit function before being reused. If the function returns true, this indicates opt-out from decommit; the memory remains committed and available for future use, in which case it will be automatically retained for later reuse. - typedef bool (chunk_purge_t) - void *chunk + typedef bool (extent_purge_t) + void *addr size_tsize size_t offset size_t length unsigned arena_ind - A chunk purge function conforms to the chunk_purge_t - type and optionally discards physical pages within the virtual memory - mapping associated with chunk of given - size at offset bytes, - extending for length on behalf of arena + An extent purge function conforms to the + extent_purge_t type and optionally discards physical pages + within the virtual memory mapping associated with an extent at given + addr and size at + offset bytes, extending for + length on behalf of arena arena_ind, returning false if pages within the purged virtual memory range will be zero-filled the next time they are accessed. - typedef bool (chunk_split_t) - void *chunk + typedef bool (extent_split_t) + void *addr size_t size size_t size_a size_t size_b @@ -1713,35 +1715,35 @@ typedef struct { unsigned arena_ind - A chunk split function conforms to the chunk_split_t - type and optionally splits chunk of given - size into two adjacent chunks, the first of - size_a bytes, and the second of - size_b bytes, operating on + An extent split function conforms to the + extent_split_t type and optionally splits an extent at + given addr and size into + two adjacent extents, the first of size_a bytes, + and the second of size_b bytes, operating on committed/decommitted memory as indicated, on behalf of arena arena_ind, returning false upon - success. If the function returns true, this indicates that the chunk + success. If the function returns true, this indicates that the extent remains unsplit and therefore should continue to be operated on as a whole. - typedef bool (chunk_merge_t) - void *chunk_a + typedef bool (extent_merge_t) + void *addr_a size_t size_a - void *chunk_b + void *addr_b size_t size_b bool committed unsigned arena_ind - A chunk merge function conforms to the chunk_merge_t - type and optionally merges adjacent chunks, - chunk_a of given size_a - and chunk_b of given - size_b into one contiguous chunk, operating on + An extent merge function conforms to the + extent_merge_t type and optionally merges adjacent extents, + at given addr_a and size_a + with given addr_b and + size_b into one contiguous extent, operating on committed/decommitted memory as indicated, on behalf of arena arena_ind, returning false upon - success. If the function returns true, this indicates that the chunks + success. If the function returns true, this indicates that the extents remain distinct mappings and therefore should continue to be operated on independently. diff --git a/include/jemalloc/jemalloc_typedefs.h.in b/include/jemalloc/jemalloc_typedefs.h.in index 2b07e362..99f07ab2 100644 --- a/include/jemalloc/jemalloc_typedefs.h.in +++ b/include/jemalloc/jemalloc_typedefs.h.in @@ -1,57 +1,58 @@ /* * void * - * chunk_alloc(void *new_addr, size_t size, size_t alignment, bool *zero, + * extent_alloc(void *new_addr, size_t size, size_t alignment, bool *zero, * bool *commit, unsigned arena_ind); */ -typedef void *(chunk_alloc_t)(void *, size_t, size_t, bool *, bool *, unsigned); +typedef void *(extent_alloc_t)(void *, size_t, size_t, bool *, bool *, + unsigned); /* * bool - * chunk_dalloc(void *chunk, size_t size, bool committed, unsigned arena_ind); + * extent_dalloc(void *addr, size_t size, bool committed, unsigned arena_ind); */ -typedef bool (chunk_dalloc_t)(void *, size_t, bool, unsigned); +typedef bool (extent_dalloc_t)(void *, size_t, bool, unsigned); /* * bool - * chunk_commit(void *chunk, size_t size, size_t offset, size_t length, + * extent_commit(void *addr, size_t size, size_t offset, size_t length, * unsigned arena_ind); */ -typedef bool (chunk_commit_t)(void *, size_t, size_t, size_t, unsigned); +typedef bool (extent_commit_t)(void *, size_t, size_t, size_t, unsigned); /* * bool - * chunk_decommit(void *chunk, size_t size, size_t offset, size_t length, + * extent_decommit(void *addr, size_t size, size_t offset, size_t length, * unsigned arena_ind); */ -typedef bool (chunk_decommit_t)(void *, size_t, size_t, size_t, unsigned); +typedef bool (extent_decommit_t)(void *, size_t, size_t, size_t, unsigned); /* * bool - * chunk_purge(void *chunk, size_t size, size_t offset, size_t length, + * extent_purge(void *addr, size_t size, size_t offset, size_t length, * unsigned arena_ind); */ -typedef bool (chunk_purge_t)(void *, size_t, size_t, size_t, unsigned); +typedef bool (extent_purge_t)(void *, size_t, size_t, size_t, unsigned); /* * bool - * chunk_split(void *chunk, size_t size, size_t size_a, size_t size_b, + * extent_split(void *addr, size_t size, size_t size_a, size_t size_b, * bool committed, unsigned arena_ind); */ -typedef bool (chunk_split_t)(void *, size_t, size_t, size_t, bool, unsigned); +typedef bool (extent_split_t)(void *, size_t, size_t, size_t, bool, unsigned); /* * bool - * chunk_merge(void *chunk_a, size_t size_a, void *chunk_b, size_t size_b, + * extent_merge(void *addr_a, size_t size_a, void *addr_b, size_t size_b, * bool committed, unsigned arena_ind); */ -typedef bool (chunk_merge_t)(void *, size_t, void *, size_t, bool, unsigned); +typedef bool (extent_merge_t)(void *, size_t, void *, size_t, bool, unsigned); typedef struct { - chunk_alloc_t *alloc; - chunk_dalloc_t *dalloc; - chunk_commit_t *commit; - chunk_decommit_t *decommit; - chunk_purge_t *purge; - chunk_split_t *split; - chunk_merge_t *merge; + extent_alloc_t *alloc; + extent_dalloc_t *dalloc; + extent_commit_t *commit; + extent_decommit_t *decommit; + extent_purge_t *purge; + extent_split_t *split; + extent_merge_t *merge; } extent_hooks_t; diff --git a/src/chunk.c b/src/chunk.c index 6ca40572..78f08d49 100644 --- a/src/chunk.c +++ b/src/chunk.c @@ -18,29 +18,29 @@ size_t chunksize; size_t chunksize_mask; /* (chunksize - 1). */ size_t chunk_npages; -static void *chunk_alloc_default(void *new_addr, size_t size, +static void *extent_alloc_default(void *new_addr, size_t size, size_t alignment, bool *zero, bool *commit, unsigned arena_ind); -static bool chunk_dalloc_default(void *chunk, size_t size, bool committed, +static bool extent_dalloc_default(void *addr, size_t size, bool committed, unsigned arena_ind); -static bool chunk_commit_default(void *chunk, size_t size, size_t offset, +static bool extent_commit_default(void *addr, size_t size, size_t offset, size_t length, unsigned arena_ind); -static bool chunk_decommit_default(void *chunk, size_t size, size_t offset, +static bool extent_decommit_default(void *addr, size_t size, size_t offset, size_t length, unsigned arena_ind); -static bool chunk_purge_default(void *chunk, size_t size, size_t offset, +static bool extent_purge_default(void *addr, size_t size, size_t offset, size_t length, unsigned arena_ind); -static bool chunk_split_default(void *chunk, size_t size, size_t size_a, +static bool extent_split_default(void *addr, size_t size, size_t size_a, size_t size_b, bool committed, unsigned arena_ind); -static bool chunk_merge_default(void *chunk_a, size_t size_a, void *chunk_b, +static bool extent_merge_default(void *addr_a, size_t size_a, void *addr_b, size_t size_b, bool committed, unsigned arena_ind); const extent_hooks_t extent_hooks_default = { - chunk_alloc_default, - chunk_dalloc_default, - chunk_commit_default, - chunk_decommit_default, - chunk_purge_default, - chunk_split_default, - chunk_merge_default + extent_alloc_default, + extent_dalloc_default, + extent_commit_default, + extent_decommit_default, + extent_purge_default, + extent_split_default, + extent_merge_default }; /******************************************************************************/ @@ -107,7 +107,7 @@ extent_hooks_set(tsdn_t *tsdn, arena_t *arena, */ #define ATOMIC_COPY_HOOK(n) do { \ union { \ - chunk_##n##_t **n; \ + extent_##n##_t **n; \ void **v; \ } u; \ u.n = &arena->extent_hooks.n; \ @@ -503,7 +503,7 @@ chunk_arena_get(tsdn_t *tsdn, unsigned arena_ind) } static void * -chunk_alloc_default(void *new_addr, size_t size, size_t alignment, bool *zero, +extent_alloc_default(void *new_addr, size_t size, size_t alignment, bool *zero, bool *commit, unsigned arena_ind) { void *ret; @@ -690,12 +690,12 @@ chunk_dalloc_cache(tsdn_t *tsdn, arena_t *arena, extent_hooks_t *extent_hooks, } static bool -chunk_dalloc_default(void *chunk, size_t size, bool committed, +extent_dalloc_default(void *addr, size_t size, bool committed, unsigned arena_ind) { - if (!have_dss || !chunk_in_dss(tsdn_fetch(), chunk)) - return (chunk_dalloc_mmap(chunk, size)); + if (!have_dss || !chunk_in_dss(tsdn_fetch(), addr)) + return (chunk_dalloc_mmap(addr, size)); return (true); } @@ -737,11 +737,11 @@ chunk_dalloc_wrapper(tsdn_t *tsdn, arena_t *arena, extent_hooks_t *extent_hooks, } static bool -chunk_commit_default(void *chunk, size_t size, size_t offset, size_t length, +extent_commit_default(void *addr, size_t size, size_t offset, size_t length, unsigned arena_ind) { - return (pages_commit((void *)((uintptr_t)chunk + (uintptr_t)offset), + return (pages_commit((void *)((uintptr_t)addr + (uintptr_t)offset), length)); } @@ -756,11 +756,11 @@ chunk_commit_wrapper(tsdn_t *tsdn, arena_t *arena, extent_hooks_t *extent_hooks, } static bool -chunk_decommit_default(void *chunk, size_t size, size_t offset, size_t length, +extent_decommit_default(void *addr, size_t size, size_t offset, size_t length, unsigned arena_ind) { - return (pages_decommit((void *)((uintptr_t)chunk + (uintptr_t)offset), + return (pages_decommit((void *)((uintptr_t)addr + (uintptr_t)offset), length)); } @@ -776,16 +776,16 @@ chunk_decommit_wrapper(tsdn_t *tsdn, arena_t *arena, } static bool -chunk_purge_default(void *chunk, size_t size, size_t offset, size_t length, +extent_purge_default(void *addr, size_t size, size_t offset, size_t length, unsigned arena_ind) { - assert(chunk != NULL); + assert(addr != NULL); assert((offset & PAGE_MASK) == 0); assert(length != 0); assert((length & PAGE_MASK) == 0); - return (pages_purge((void *)((uintptr_t)chunk + (uintptr_t)offset), + return (pages_purge((void *)((uintptr_t)addr + (uintptr_t)offset), length)); } @@ -800,7 +800,7 @@ chunk_purge_wrapper(tsdn_t *tsdn, arena_t *arena, extent_hooks_t *extent_hooks, } static bool -chunk_split_default(void *chunk, size_t size, size_t size_a, size_t size_b, +extent_split_default(void *addr, size_t size, size_t size_a, size_t size_b, bool committed, unsigned arena_ind) { @@ -871,7 +871,7 @@ label_error_a: } static bool -chunk_merge_default(void *chunk_a, size_t size_a, void *chunk_b, size_t size_b, +extent_merge_default(void *addr_a, size_t size_a, void *addr_b, size_t size_b, bool committed, unsigned arena_ind) { @@ -879,7 +879,7 @@ chunk_merge_default(void *chunk_a, size_t size_a, void *chunk_b, size_t size_b, return (true); if (have_dss) { tsdn_t *tsdn = tsdn_fetch(); - if (chunk_in_dss(tsdn, chunk_a) != chunk_in_dss(tsdn, chunk_b)) + if (chunk_in_dss(tsdn, addr_a) != chunk_in_dss(tsdn, addr_b)) return (true); }