summaryrefslogtreecommitdiff
path: root/examples/redis-unstable/deps/jemalloc/src/psset.c
diff options
context:
space:
mode:
Diffstat (limited to 'examples/redis-unstable/deps/jemalloc/src/psset.c')
-rw-r--r--examples/redis-unstable/deps/jemalloc/src/psset.c385
1 files changed, 0 insertions, 385 deletions
diff --git a/examples/redis-unstable/deps/jemalloc/src/psset.c b/examples/redis-unstable/deps/jemalloc/src/psset.c
deleted file mode 100644
index 9a8f054..0000000
--- a/examples/redis-unstable/deps/jemalloc/src/psset.c
+++ /dev/null
@@ -1,385 +0,0 @@
-#include "jemalloc/internal/jemalloc_preamble.h"
-#include "jemalloc/internal/jemalloc_internal_includes.h"
-
-#include "jemalloc/internal/psset.h"
-
-#include "jemalloc/internal/fb.h"
-
-void
-psset_init(psset_t *psset) {
- for (unsigned i = 0; i < PSSET_NPSIZES; i++) {
- hpdata_age_heap_new(&psset->pageslabs[i]);
- }
- fb_init(psset->pageslab_bitmap, PSSET_NPSIZES);
- memset(&psset->merged_stats, 0, sizeof(psset->merged_stats));
- memset(&psset->stats, 0, sizeof(psset->stats));
- hpdata_empty_list_init(&psset->empty);
- for (int i = 0; i < PSSET_NPURGE_LISTS; i++) {
- hpdata_purge_list_init(&psset->to_purge[i]);
- }
- fb_init(psset->purge_bitmap, PSSET_NPURGE_LISTS);
- hpdata_hugify_list_init(&psset->to_hugify);
-}
-
-static void
-psset_bin_stats_accum(psset_bin_stats_t *dst, psset_bin_stats_t *src) {
- dst->npageslabs += src->npageslabs;
- dst->nactive += src->nactive;
- dst->ndirty += src->ndirty;
-}
-
-void
-psset_stats_accum(psset_stats_t *dst, psset_stats_t *src) {
- psset_bin_stats_accum(&dst->full_slabs[0], &src->full_slabs[0]);
- psset_bin_stats_accum(&dst->full_slabs[1], &src->full_slabs[1]);
- psset_bin_stats_accum(&dst->empty_slabs[0], &src->empty_slabs[0]);
- psset_bin_stats_accum(&dst->empty_slabs[1], &src->empty_slabs[1]);
- for (pszind_t i = 0; i < PSSET_NPSIZES; i++) {
- psset_bin_stats_accum(&dst->nonfull_slabs[i][0],
- &src->nonfull_slabs[i][0]);
- psset_bin_stats_accum(&dst->nonfull_slabs[i][1],
- &src->nonfull_slabs[i][1]);
- }
-}
-
-/*
- * The stats maintenance strategy is to remove a pageslab's contribution to the
- * stats when we call psset_update_begin, and re-add it (to a potentially new
- * bin) when we call psset_update_end.
- */
-JEMALLOC_ALWAYS_INLINE void
-psset_bin_stats_insert_remove(psset_t *psset, psset_bin_stats_t *binstats,
- hpdata_t *ps, bool insert) {
- size_t mul = insert ? (size_t)1 : (size_t)-1;
- size_t huge_idx = (size_t)hpdata_huge_get(ps);
-
- binstats[huge_idx].npageslabs += mul * 1;
- binstats[huge_idx].nactive += mul * hpdata_nactive_get(ps);
- binstats[huge_idx].ndirty += mul * hpdata_ndirty_get(ps);
-
- psset->merged_stats.npageslabs += mul * 1;
- psset->merged_stats.nactive += mul * hpdata_nactive_get(ps);
- psset->merged_stats.ndirty += mul * hpdata_ndirty_get(ps);
-
- if (config_debug) {
- psset_bin_stats_t check_stats = {0};
- for (size_t huge = 0; huge <= 1; huge++) {
- psset_bin_stats_accum(&check_stats,
- &psset->stats.full_slabs[huge]);
- psset_bin_stats_accum(&check_stats,
- &psset->stats.empty_slabs[huge]);
- for (pszind_t pind = 0; pind < PSSET_NPSIZES; pind++) {
- psset_bin_stats_accum(&check_stats,
- &psset->stats.nonfull_slabs[pind][huge]);
- }
- }
- assert(psset->merged_stats.npageslabs
- == check_stats.npageslabs);
- assert(psset->merged_stats.nactive == check_stats.nactive);
- assert(psset->merged_stats.ndirty == check_stats.ndirty);
- }
-}
-
-static void
-psset_bin_stats_insert(psset_t *psset, psset_bin_stats_t *binstats,
- hpdata_t *ps) {
- psset_bin_stats_insert_remove(psset, binstats, ps, true);
-}
-
-static void
-psset_bin_stats_remove(psset_t *psset, psset_bin_stats_t *binstats,
- hpdata_t *ps) {
- psset_bin_stats_insert_remove(psset, binstats, ps, false);
-}
-
-static void
-psset_hpdata_heap_remove(psset_t *psset, pszind_t pind, hpdata_t *ps) {
- hpdata_age_heap_remove(&psset->pageslabs[pind], ps);
- if (hpdata_age_heap_empty(&psset->pageslabs[pind])) {
- fb_unset(psset->pageslab_bitmap, PSSET_NPSIZES, (size_t)pind);
- }
-}
-
-static void
-psset_hpdata_heap_insert(psset_t *psset, pszind_t pind, hpdata_t *ps) {
- if (hpdata_age_heap_empty(&psset->pageslabs[pind])) {
- fb_set(psset->pageslab_bitmap, PSSET_NPSIZES, (size_t)pind);
- }
- hpdata_age_heap_insert(&psset->pageslabs[pind], ps);
-}
-
-static void
-psset_stats_insert(psset_t* psset, hpdata_t *ps) {
- if (hpdata_empty(ps)) {
- psset_bin_stats_insert(psset, psset->stats.empty_slabs, ps);
- } else if (hpdata_full(ps)) {
- psset_bin_stats_insert(psset, psset->stats.full_slabs, ps);
- } else {
- size_t longest_free_range = hpdata_longest_free_range_get(ps);
-
- pszind_t pind = sz_psz2ind(sz_psz_quantize_floor(
- longest_free_range << LG_PAGE));
- assert(pind < PSSET_NPSIZES);
-
- psset_bin_stats_insert(psset, psset->stats.nonfull_slabs[pind],
- ps);
- }
-}
-
-static void
-psset_stats_remove(psset_t *psset, hpdata_t *ps) {
- if (hpdata_empty(ps)) {
- psset_bin_stats_remove(psset, psset->stats.empty_slabs, ps);
- } else if (hpdata_full(ps)) {
- psset_bin_stats_remove(psset, psset->stats.full_slabs, ps);
- } else {
- size_t longest_free_range = hpdata_longest_free_range_get(ps);
-
- pszind_t pind = sz_psz2ind(sz_psz_quantize_floor(
- longest_free_range << LG_PAGE));
- assert(pind < PSSET_NPSIZES);
-
- psset_bin_stats_remove(psset, psset->stats.nonfull_slabs[pind],
- ps);
- }
-}
-
-/*
- * Put ps into some container so that it can be found during future allocation
- * requests.
- */
-static void
-psset_alloc_container_insert(psset_t *psset, hpdata_t *ps) {
- assert(!hpdata_in_psset_alloc_container_get(ps));
- hpdata_in_psset_alloc_container_set(ps, true);
- if (hpdata_empty(ps)) {
- /*
- * This prepend, paired with popping the head in psset_fit,
- * means we implement LIFO ordering for the empty slabs set,
- * which seems reasonable.
- */
- hpdata_empty_list_prepend(&psset->empty, ps);
- } else if (hpdata_full(ps)) {
- /*
- * We don't need to keep track of the full slabs; we're never
- * going to return them from a psset_pick_alloc call.
- */
- } else {
- size_t longest_free_range = hpdata_longest_free_range_get(ps);
-
- pszind_t pind = sz_psz2ind(sz_psz_quantize_floor(
- longest_free_range << LG_PAGE));
- assert(pind < PSSET_NPSIZES);
-
- psset_hpdata_heap_insert(psset, pind, ps);
- }
-}
-
-/* Remove ps from those collections. */
-static void
-psset_alloc_container_remove(psset_t *psset, hpdata_t *ps) {
- assert(hpdata_in_psset_alloc_container_get(ps));
- hpdata_in_psset_alloc_container_set(ps, false);
-
- if (hpdata_empty(ps)) {
- hpdata_empty_list_remove(&psset->empty, ps);
- } else if (hpdata_full(ps)) {
- /* Same as above -- do nothing in this case. */
- } else {
- size_t longest_free_range = hpdata_longest_free_range_get(ps);
-
- pszind_t pind = sz_psz2ind(sz_psz_quantize_floor(
- longest_free_range << LG_PAGE));
- assert(pind < PSSET_NPSIZES);
-
- psset_hpdata_heap_remove(psset, pind, ps);
- }
-}
-
-static size_t
-psset_purge_list_ind(hpdata_t *ps) {
- size_t ndirty = hpdata_ndirty_get(ps);
- /* Shouldn't have something with no dirty pages purgeable. */
- assert(ndirty > 0);
- /*
- * Higher indices correspond to lists we'd like to purge earlier; make
- * the two highest indices correspond to empty lists, which we attempt
- * to purge before purging any non-empty list. This has two advantages:
- * - Empty page slabs are the least likely to get reused (we'll only
- * pick them for an allocation if we have no other choice).
- * - Empty page slabs can purge every dirty page they contain in a
- * single call, which is not usually the case.
- *
- * We purge hugeified empty slabs before nonhugeified ones, on the basis
- * that they are fully dirty, while nonhugified slabs might not be, so
- * we free up more pages more easily.
- */
- if (hpdata_nactive_get(ps) == 0) {
- if (hpdata_huge_get(ps)) {
- return PSSET_NPURGE_LISTS - 1;
- } else {
- return PSSET_NPURGE_LISTS - 2;
- }
- }
-
- pszind_t pind = sz_psz2ind(sz_psz_quantize_floor(ndirty << LG_PAGE));
- /*
- * For non-empty slabs, we may reuse them again. Prefer purging
- * non-hugeified slabs before hugeified ones then, among pages of
- * similar dirtiness. We still get some benefit from the hugification.
- */
- return (size_t)pind * 2 + (hpdata_huge_get(ps) ? 0 : 1);
-}
-
-static void
-psset_maybe_remove_purge_list(psset_t *psset, hpdata_t *ps) {
- /*
- * Remove the hpdata from its purge list (if it's in one). Even if it's
- * going to stay in the same one, by appending it during
- * psset_update_end, we move it to the end of its queue, so that we
- * purge LRU within a given dirtiness bucket.
- */
- if (hpdata_purge_allowed_get(ps)) {
- size_t ind = psset_purge_list_ind(ps);
- hpdata_purge_list_t *purge_list = &psset->to_purge[ind];
- hpdata_purge_list_remove(purge_list, ps);
- if (hpdata_purge_list_empty(purge_list)) {
- fb_unset(psset->purge_bitmap, PSSET_NPURGE_LISTS, ind);
- }
- }
-}
-
-static void
-psset_maybe_insert_purge_list(psset_t *psset, hpdata_t *ps) {
- if (hpdata_purge_allowed_get(ps)) {
- size_t ind = psset_purge_list_ind(ps);
- hpdata_purge_list_t *purge_list = &psset->to_purge[ind];
- if (hpdata_purge_list_empty(purge_list)) {
- fb_set(psset->purge_bitmap, PSSET_NPURGE_LISTS, ind);
- }
- hpdata_purge_list_append(purge_list, ps);
- }
-
-}
-
-void
-psset_update_begin(psset_t *psset, hpdata_t *ps) {
- hpdata_assert_consistent(ps);
- assert(hpdata_in_psset_get(ps));
- hpdata_updating_set(ps, true);
- psset_stats_remove(psset, ps);
- if (hpdata_in_psset_alloc_container_get(ps)) {
- /*
- * Some metadata updates can break alloc container invariants
- * (e.g. the longest free range determines the hpdata_heap_t the
- * pageslab lives in).
- */
- assert(hpdata_alloc_allowed_get(ps));
- psset_alloc_container_remove(psset, ps);
- }
- psset_maybe_remove_purge_list(psset, ps);
- /*
- * We don't update presence in the hugify list; we try to keep it FIFO,
- * even in the presence of other metadata updates. We'll update
- * presence at the end of the metadata update if necessary.
- */
-}
-
-void
-psset_update_end(psset_t *psset, hpdata_t *ps) {
- assert(hpdata_in_psset_get(ps));
- hpdata_updating_set(ps, false);
- psset_stats_insert(psset, ps);
-
- /*
- * The update begin should have removed ps from whatever alloc container
- * it was in.
- */
- assert(!hpdata_in_psset_alloc_container_get(ps));
- if (hpdata_alloc_allowed_get(ps)) {
- psset_alloc_container_insert(psset, ps);
- }
- psset_maybe_insert_purge_list(psset, ps);
-
- if (hpdata_hugify_allowed_get(ps)
- && !hpdata_in_psset_hugify_container_get(ps)) {
- hpdata_in_psset_hugify_container_set(ps, true);
- hpdata_hugify_list_append(&psset->to_hugify, ps);
- } else if (!hpdata_hugify_allowed_get(ps)
- && hpdata_in_psset_hugify_container_get(ps)) {
- hpdata_in_psset_hugify_container_set(ps, false);
- hpdata_hugify_list_remove(&psset->to_hugify, ps);
- }
- hpdata_assert_consistent(ps);
-}
-
-hpdata_t *
-psset_pick_alloc(psset_t *psset, size_t size) {
- assert((size & PAGE_MASK) == 0);
- assert(size <= HUGEPAGE);
-
- pszind_t min_pind = sz_psz2ind(sz_psz_quantize_ceil(size));
- pszind_t pind = (pszind_t)fb_ffs(psset->pageslab_bitmap, PSSET_NPSIZES,
- (size_t)min_pind);
- if (pind == PSSET_NPSIZES) {
- return hpdata_empty_list_first(&psset->empty);
- }
- hpdata_t *ps = hpdata_age_heap_first(&psset->pageslabs[pind]);
- if (ps == NULL) {
- return NULL;
- }
-
- hpdata_assert_consistent(ps);
-
- return ps;
-}
-
-hpdata_t *
-psset_pick_purge(psset_t *psset) {
- ssize_t ind_ssz = fb_fls(psset->purge_bitmap, PSSET_NPURGE_LISTS,
- PSSET_NPURGE_LISTS - 1);
- if (ind_ssz < 0) {
- return NULL;
- }
- pszind_t ind = (pszind_t)ind_ssz;
- assert(ind < PSSET_NPURGE_LISTS);
- hpdata_t *ps = hpdata_purge_list_first(&psset->to_purge[ind]);
- assert(ps != NULL);
- return ps;
-}
-
-hpdata_t *
-psset_pick_hugify(psset_t *psset) {
- return hpdata_hugify_list_first(&psset->to_hugify);
-}
-
-void
-psset_insert(psset_t *psset, hpdata_t *ps) {
- hpdata_in_psset_set(ps, true);
-
- psset_stats_insert(psset, ps);
- if (hpdata_alloc_allowed_get(ps)) {
- psset_alloc_container_insert(psset, ps);
- }
- psset_maybe_insert_purge_list(psset, ps);
-
- if (hpdata_hugify_allowed_get(ps)) {
- hpdata_in_psset_hugify_container_set(ps, true);
- hpdata_hugify_list_append(&psset->to_hugify, ps);
- }
-}
-
-void
-psset_remove(psset_t *psset, hpdata_t *ps) {
- hpdata_in_psset_set(ps, false);
-
- psset_stats_remove(psset, ps);
- if (hpdata_in_psset_alloc_container_get(ps)) {
- psset_alloc_container_remove(psset, ps);
- }
- psset_maybe_remove_purge_list(psset, ps);
- if (hpdata_in_psset_hugify_container_get(ps)) {
- hpdata_in_psset_hugify_container_set(ps, false);
- hpdata_hugify_list_remove(&psset->to_hugify, ps);
- }
-}