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