1 #ifndef JEMALLOC_INTERNAL_ARENA_STRUCTS_B_H 2 #define JEMALLOC_INTERNAL_ARENA_STRUCTS_B_H 3 4 #include "jemalloc/internal/arena_stats.h" 5 #include "jemalloc/internal/atomic.h" 6 #include "jemalloc/internal/bin.h" 7 #include "jemalloc/internal/bitmap.h" 8 #include "jemalloc/internal/extent_dss.h" 9 #include "jemalloc/internal/jemalloc_internal_types.h" 10 #include "jemalloc/internal/mutex.h" 11 #include "jemalloc/internal/nstime.h" 12 #include "jemalloc/internal/ql.h" 13 #include "jemalloc/internal/sc.h" 14 #include "jemalloc/internal/smoothstep.h" 15 #include "jemalloc/internal/ticker.h" 16 17 struct arena_decay_s { 18 /* Synchronizes all non-atomic fields. */ 19 malloc_mutex_t mtx; 20 /* 21 * True if a thread is currently purging the extents associated with 22 * this decay structure. 23 */ 24 bool purging; 25 /* 26 * Approximate time in milliseconds from the creation of a set of unused 27 * dirty pages until an equivalent set of unused dirty pages is purged 28 * and/or reused. 29 */ 30 atomic_zd_t time_ms; 31 /* time / SMOOTHSTEP_NSTEPS. */ 32 nstime_t interval; 33 /* 34 * Time at which the current decay interval logically started. We do 35 * not actually advance to a new epoch until sometime after it starts 36 * because of scheduling and computation delays, and it is even possible 37 * to completely skip epochs. In all cases, during epoch advancement we 38 * merge all relevant activity into the most recently recorded epoch. 39 */ 40 nstime_t epoch; 41 /* Deadline randomness generator. */ 42 uint64_t jitter_state; 43 /* 44 * Deadline for current epoch. This is the sum of interval and per 45 * epoch jitter which is a uniform random variable in [0..interval). 46 * Epochs always advance by precise multiples of interval, but we 47 * randomize the deadline to reduce the likelihood of arenas purging in 48 * lockstep. 49 */ 50 nstime_t deadline; 51 /* 52 * Number of unpurged pages at beginning of current epoch. During epoch 53 * advancement we use the delta between arena->decay_*.nunpurged and 54 * extents_npages_get(&arena->extents_*) to determine how many dirty 55 * pages, if any, were generated. 56 */ 57 size_t nunpurged; 58 /* 59 * Trailing log of how many unused dirty pages were generated during 60 * each of the past SMOOTHSTEP_NSTEPS decay epochs, where the last 61 * element is the most recent epoch. Corresponding epoch times are 62 * relative to epoch. 63 */ 64 size_t backlog[SMOOTHSTEP_NSTEPS]; 65 66 /* 67 * Pointer to associated stats. These stats are embedded directly in 68 * the arena's stats due to how stats structures are shared between the 69 * arena and ctl code. 70 * 71 * Synchronization: Same as associated arena's stats field. */ 72 arena_stats_decay_t *stats; 73 /* Peak number of pages in associated extents. Used for debug only. */ 74 uint64_t ceil_npages; 75 }; 76 77 struct arena_s { 78 /* 79 * Number of threads currently assigned to this arena. Each thread has 80 * two distinct assignments, one for application-serving allocation, and 81 * the other for internal metadata allocation. Internal metadata must 82 * not be allocated from arenas explicitly created via the arenas.create 83 * mallctl, because the arena.<i>.reset mallctl indiscriminately 84 * discards all allocations for the affected arena. 85 * 86 * 0: Application allocation. 87 * 1: Internal metadata allocation. 88 * 89 * Synchronization: atomic. 90 */ 91 atomic_u_t nthreads[2]; 92 93 /* Next bin shard for binding new threads. Synchronization: atomic. */ 94 atomic_u_t binshard_next; 95 96 /* 97 * When percpu_arena is enabled, to amortize the cost of reading / 98 * updating the current CPU id, track the most recent thread accessing 99 * this arena, and only read CPU if there is a mismatch. 100 */ 101 tsdn_t *last_thd; 102 103 /* Synchronization: internal. */ 104 arena_stats_t stats; 105 106 /* 107 * Lists of tcaches and cache_bin_array_descriptors for extant threads 108 * associated with this arena. Stats from these are merged 109 * incrementally, and at exit if opt_stats_print is enabled. 110 * 111 * Synchronization: tcache_ql_mtx. 112 */ 113 ql_head(tcache_t) tcache_ql; 114 ql_head(cache_bin_array_descriptor_t) cache_bin_array_descriptor_ql; 115 malloc_mutex_t tcache_ql_mtx; 116 117 /* Synchronization: internal. */ 118 prof_accum_t prof_accum; 119 120 /* 121 * PRNG state for cache index randomization of large allocation base 122 * pointers. 123 * 124 * Synchronization: atomic. 125 */ 126 atomic_zu_t offset_state; 127 128 /* 129 * Extent serial number generator state. 130 * 131 * Synchronization: atomic. 132 */ 133 atomic_zu_t extent_sn_next; 134 135 /* 136 * Represents a dss_prec_t, but atomically. 137 * 138 * Synchronization: atomic. 139 */ 140 atomic_u_t dss_prec; 141 142 /* 143 * Number of pages in active extents. 144 * 145 * Synchronization: atomic. 146 */ 147 atomic_zu_t nactive; 148 149 /* 150 * Extant large allocations. 151 * 152 * Synchronization: large_mtx. 153 */ 154 extent_list_t large; 155 /* Synchronizes all large allocation/update/deallocation. */ 156 malloc_mutex_t large_mtx; 157 158 /* 159 * Collections of extents that were previously allocated. These are 160 * used when allocating extents, in an attempt to re-use address space. 161 * 162 * Synchronization: internal. 163 */ 164 extents_t extents_dirty; 165 extents_t extents_muzzy; 166 extents_t extents_retained; 167 168 /* 169 * Decay-based purging state, responsible for scheduling extent state 170 * transitions. 171 * 172 * Synchronization: internal. 173 */ 174 arena_decay_t decay_dirty; /* dirty --> muzzy */ 175 arena_decay_t decay_muzzy; /* muzzy --> retained */ 176 177 /* 178 * Next extent size class in a growing series to use when satisfying a 179 * request via the extent hooks (only if opt_retain). This limits the 180 * number of disjoint virtual memory ranges so that extent merging can 181 * be effective even if multiple arenas' extent allocation requests are 182 * highly interleaved. 183 * 184 * retain_grow_limit is the max allowed size ind to expand (unless the 185 * required size is greater). Default is no limit, and controlled 186 * through mallctl only. 187 * 188 * Synchronization: extent_grow_mtx 189 */ 190 pszind_t extent_grow_next; 191 pszind_t retain_grow_limit; 192 malloc_mutex_t extent_grow_mtx; 193 194 /* 195 * Available extent structures that were allocated via 196 * base_alloc_extent(). 197 * 198 * Synchronization: extent_avail_mtx. 199 */ 200 extent_tree_t extent_avail; 201 atomic_zu_t extent_avail_cnt; 202 malloc_mutex_t extent_avail_mtx; 203 204 /* 205 * bins is used to store heaps of free regions. 206 * 207 * Synchronization: internal. 208 */ 209 bins_t bins[SC_NBINS]; 210 211 /* 212 * Base allocator, from which arena metadata are allocated. 213 * 214 * Synchronization: internal. 215 */ 216 base_t *base; 217 /* Used to determine uptime. Read-only after initialization. */ 218 nstime_t create_time; 219 }; 220 221 /* Used in conjunction with tsd for fast arena-related context lookup. */ 222 struct arena_tdata_s { 223 ticker_t decay_ticker; 224 }; 225 226 /* Used to pass rtree lookup context down the path. */ 227 struct alloc_ctx_s { 228 szind_t szind; 229 bool slab; 230 }; 231 232 #endif /* JEMALLOC_INTERNAL_ARENA_STRUCTS_B_H */ 233