1#ifndef JEMALLOC_INTERNAL_ESET_H
2#define JEMALLOC_INTERNAL_ESET_H
3
4#include "jemalloc/internal/atomic.h"
5#include "jemalloc/internal/fb.h"
6#include "jemalloc/internal/edata.h"
7#include "jemalloc/internal/mutex.h"
8
9/*
10 * An eset ("extent set") is a quantized collection of extents, with built-in
11 * LRU queue.
12 *
13 * This class is not thread-safe; synchronization must be done externally if
14 * there are mutating operations. One exception is the stats counters, which
15 * may be read without any locking.
16 */
17
18typedef struct eset_bin_s eset_bin_t;
19struct eset_bin_s {
20 edata_heap_t heap;
21 /*
22 * We do first-fit across multiple size classes. If we compared against
23 * the min element in each heap directly, we'd take a cache miss per
24 * extent we looked at. If we co-locate the edata summaries, we only
25 * take a miss on the edata we're actually going to return (which is
26 * inevitable anyways).
27 */
28 edata_cmp_summary_t heap_min;
29};
30
31typedef struct eset_bin_stats_s eset_bin_stats_t;
32struct eset_bin_stats_s {
33 atomic_zu_t nextents;
34 atomic_zu_t nbytes;
35};
36
37typedef struct eset_s eset_t;
38struct eset_s {
39 /* Bitmap for which set bits correspond to non-empty heaps. */
40 fb_group_t bitmap[FB_NGROUPS(SC_NPSIZES + 1)];
41
42 /* Quantized per size class heaps of extents. */
43 eset_bin_t bins[SC_NPSIZES + 1];
44
45 eset_bin_stats_t bin_stats[SC_NPSIZES + 1];
46
47 /* LRU of all extents in heaps. */
48 edata_list_inactive_t lru;
49
50 /* Page sum for all extents in heaps. */
51 atomic_zu_t npages;
52
53 /*
54 * A duplication of the data in the containing ecache. We use this only
55 * for assertions on the states of the passed-in extents.
56 */
57 extent_state_t state;
58};
59
60void eset_init(eset_t *eset, extent_state_t state);
61
62size_t eset_npages_get(eset_t *eset);
63/* Get the number of extents in the given page size index. */
64size_t eset_nextents_get(eset_t *eset, pszind_t ind);
65/* Get the sum total bytes of the extents in the given page size index. */
66size_t eset_nbytes_get(eset_t *eset, pszind_t ind);
67
68void eset_insert(eset_t *eset, edata_t *edata);
69void eset_remove(eset_t *eset, edata_t *edata);
70/*
71 * Select an extent from this eset of the given size and alignment. Returns
72 * null if no such item could be found.
73 */
74edata_t *eset_fit(eset_t *eset, size_t esize, size_t alignment, bool exact_only,
75 unsigned lg_max_fit);
76
77#endif /* JEMALLOC_INTERNAL_ESET_H */
78