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 | |
18 | typedef struct eset_bin_s eset_bin_t; |
19 | struct 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 | |
31 | typedef struct eset_bin_stats_s eset_bin_stats_t; |
32 | struct eset_bin_stats_s { |
33 | atomic_zu_t nextents; |
34 | atomic_zu_t nbytes; |
35 | }; |
36 | |
37 | typedef struct eset_s eset_t; |
38 | struct 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 | |
60 | void eset_init(eset_t *eset, extent_state_t state); |
61 | |
62 | size_t eset_npages_get(eset_t *eset); |
63 | /* Get the number of extents in the given page size index. */ |
64 | size_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. */ |
66 | size_t eset_nbytes_get(eset_t *eset, pszind_t ind); |
67 | |
68 | void eset_insert(eset_t *eset, edata_t *edata); |
69 | void 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 | */ |
74 | edata_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 | |