1 /******************************************************************************/ 2 #ifdef JEMALLOC_H_TYPES 3 4 typedef struct extent_node_s extent_node_t; 5 6 #endif /* JEMALLOC_H_TYPES */ 7 /******************************************************************************/ 8 #ifdef JEMALLOC_H_STRUCTS 9 10 /* Tree of extents. Use accessor functions for en_* fields. */ 11 struct extent_node_s { 12 /* Arena from which this extent came, if any. */ 13 arena_t *en_arena; 14 15 /* Pointer to the extent that this tree node is responsible for. */ 16 void *en_addr; 17 18 /* Total region size. */ 19 size_t en_size; 20 21 /* 22 * Serial number (potentially non-unique). 23 * 24 * In principle serial numbers can wrap around on 32-bit systems if 25 * JEMALLOC_MUNMAP is defined, but as long as comparison functions fall 26 * back on address comparison for equal serial numbers, stable (if 27 * imperfect) ordering is maintained. 28 * 29 * Serial numbers may not be unique even in the absence of wrap-around, 30 * e.g. when splitting an extent and assigning the same serial number to 31 * both resulting adjacent extents. 32 */ 33 size_t en_sn; 34 35 /* 36 * The zeroed flag is used by chunk recycling code to track whether 37 * memory is zero-filled. 38 */ 39 bool en_zeroed; 40 41 /* 42 * True if physical memory is committed to the extent, whether 43 * explicitly or implicitly as on a system that overcommits and 44 * satisfies physical memory needs on demand via soft page faults. 45 */ 46 bool en_committed; 47 48 /* 49 * The achunk flag is used to validate that huge allocation lookups 50 * don't return arena chunks. 51 */ 52 bool en_achunk; 53 54 /* Profile counters, used for huge objects. */ 55 prof_tctx_t *en_prof_tctx; 56 57 /* Linkage for arena's runs_dirty and chunks_cache rings. */ 58 arena_runs_dirty_link_t rd; 59 qr(extent_node_t) cc_link; 60 61 union { 62 /* Linkage for the size/sn/address-ordered tree. */ 63 rb_node(extent_node_t) szsnad_link; 64 65 /* Linkage for arena's achunks, huge, and node_cache lists. */ 66 ql_elm(extent_node_t) ql_link; 67 }; 68 69 /* Linkage for the address-ordered tree. */ 70 rb_node(extent_node_t) ad_link; 71 }; 72 typedef rb_tree(extent_node_t) extent_tree_t; 73 74 #endif /* JEMALLOC_H_STRUCTS */ 75 /******************************************************************************/ 76 #ifdef JEMALLOC_H_EXTERNS 77 78 rb_proto(, extent_tree_szsnad_, extent_tree_t, extent_node_t) 79 80 rb_proto(, extent_tree_ad_, extent_tree_t, extent_node_t) 81 82 #endif /* JEMALLOC_H_EXTERNS */ 83 /******************************************************************************/ 84 #ifdef JEMALLOC_H_INLINES 85 86 #ifndef JEMALLOC_ENABLE_INLINE 87 arena_t *extent_node_arena_get(const extent_node_t *node); 88 void *extent_node_addr_get(const extent_node_t *node); 89 size_t extent_node_size_get(const extent_node_t *node); 90 size_t extent_node_sn_get(const extent_node_t *node); 91 bool extent_node_zeroed_get(const extent_node_t *node); 92 bool extent_node_committed_get(const extent_node_t *node); 93 bool extent_node_achunk_get(const extent_node_t *node); 94 prof_tctx_t *extent_node_prof_tctx_get(const extent_node_t *node); 95 void extent_node_arena_set(extent_node_t *node, arena_t *arena); 96 void extent_node_addr_set(extent_node_t *node, void *addr); 97 void extent_node_size_set(extent_node_t *node, size_t size); 98 void extent_node_sn_set(extent_node_t *node, size_t sn); 99 void extent_node_zeroed_set(extent_node_t *node, bool zeroed); 100 void extent_node_committed_set(extent_node_t *node, bool committed); 101 void extent_node_achunk_set(extent_node_t *node, bool achunk); 102 void extent_node_prof_tctx_set(extent_node_t *node, prof_tctx_t *tctx); 103 void extent_node_init(extent_node_t *node, arena_t *arena, void *addr, 104 size_t size, size_t sn, bool zeroed, bool committed); 105 void extent_node_dirty_linkage_init(extent_node_t *node); 106 void extent_node_dirty_insert(extent_node_t *node, 107 arena_runs_dirty_link_t *runs_dirty, extent_node_t *chunks_dirty); 108 void extent_node_dirty_remove(extent_node_t *node); 109 #endif 110 111 #if (defined(JEMALLOC_ENABLE_INLINE) || defined(JEMALLOC_EXTENT_C_)) 112 JEMALLOC_INLINE arena_t * 113 extent_node_arena_get(const extent_node_t *node) 114 { 115 116 return (node->en_arena); 117 } 118 119 JEMALLOC_INLINE void * 120 extent_node_addr_get(const extent_node_t *node) 121 { 122 123 return (node->en_addr); 124 } 125 126 JEMALLOC_INLINE size_t 127 extent_node_size_get(const extent_node_t *node) 128 { 129 130 return (node->en_size); 131 } 132 133 JEMALLOC_INLINE size_t 134 extent_node_sn_get(const extent_node_t *node) 135 { 136 137 return (node->en_sn); 138 } 139 140 JEMALLOC_INLINE bool 141 extent_node_zeroed_get(const extent_node_t *node) 142 { 143 144 return (node->en_zeroed); 145 } 146 147 JEMALLOC_INLINE bool 148 extent_node_committed_get(const extent_node_t *node) 149 { 150 151 assert(!node->en_achunk); 152 return (node->en_committed); 153 } 154 155 JEMALLOC_INLINE bool 156 extent_node_achunk_get(const extent_node_t *node) 157 { 158 159 return (node->en_achunk); 160 } 161 162 JEMALLOC_INLINE prof_tctx_t * 163 extent_node_prof_tctx_get(const extent_node_t *node) 164 { 165 166 return (node->en_prof_tctx); 167 } 168 169 JEMALLOC_INLINE void 170 extent_node_arena_set(extent_node_t *node, arena_t *arena) 171 { 172 173 node->en_arena = arena; 174 } 175 176 JEMALLOC_INLINE void 177 extent_node_addr_set(extent_node_t *node, void *addr) 178 { 179 180 node->en_addr = addr; 181 } 182 183 JEMALLOC_INLINE void 184 extent_node_size_set(extent_node_t *node, size_t size) 185 { 186 187 node->en_size = size; 188 } 189 190 JEMALLOC_INLINE void 191 extent_node_sn_set(extent_node_t *node, size_t sn) 192 { 193 194 node->en_sn = sn; 195 } 196 197 JEMALLOC_INLINE void 198 extent_node_zeroed_set(extent_node_t *node, bool zeroed) 199 { 200 201 node->en_zeroed = zeroed; 202 } 203 204 JEMALLOC_INLINE void 205 extent_node_committed_set(extent_node_t *node, bool committed) 206 { 207 208 node->en_committed = committed; 209 } 210 211 JEMALLOC_INLINE void 212 extent_node_achunk_set(extent_node_t *node, bool achunk) 213 { 214 215 node->en_achunk = achunk; 216 } 217 218 JEMALLOC_INLINE void 219 extent_node_prof_tctx_set(extent_node_t *node, prof_tctx_t *tctx) 220 { 221 222 node->en_prof_tctx = tctx; 223 } 224 225 JEMALLOC_INLINE void 226 extent_node_init(extent_node_t *node, arena_t *arena, void *addr, size_t size, 227 size_t sn, bool zeroed, bool committed) 228 { 229 230 extent_node_arena_set(node, arena); 231 extent_node_addr_set(node, addr); 232 extent_node_size_set(node, size); 233 extent_node_sn_set(node, sn); 234 extent_node_zeroed_set(node, zeroed); 235 extent_node_committed_set(node, committed); 236 extent_node_achunk_set(node, false); 237 if (config_prof) 238 extent_node_prof_tctx_set(node, NULL); 239 } 240 241 JEMALLOC_INLINE void 242 extent_node_dirty_linkage_init(extent_node_t *node) 243 { 244 245 qr_new(&node->rd, rd_link); 246 qr_new(node, cc_link); 247 } 248 249 JEMALLOC_INLINE void 250 extent_node_dirty_insert(extent_node_t *node, 251 arena_runs_dirty_link_t *runs_dirty, extent_node_t *chunks_dirty) 252 { 253 254 qr_meld(runs_dirty, &node->rd, rd_link); 255 qr_meld(chunks_dirty, node, cc_link); 256 } 257 258 JEMALLOC_INLINE void 259 extent_node_dirty_remove(extent_node_t *node) 260 { 261 262 qr_remove(&node->rd, rd_link); 263 qr_remove(node, cc_link); 264 } 265 266 #endif 267 268 #endif /* JEMALLOC_H_INLINES */ 269 /******************************************************************************/ 270 271