1 #ifndef JEMALLOC_INTERNAL_CACHE_BIN_H 2 #define JEMALLOC_INTERNAL_CACHE_BIN_H 3 4 #include "jemalloc/internal/ql.h" 5 #include "jemalloc/internal/sz.h" 6 7 /* 8 * The cache_bins are the mechanism that the tcache and the arena use to 9 * communicate. The tcache fills from and flushes to the arena by passing a 10 * cache_bin_t to fill/flush. When the arena needs to pull stats from the 11 * tcaches associated with it, it does so by iterating over its 12 * cache_bin_array_descriptor_t objects and reading out per-bin stats it 13 * contains. This makes it so that the arena need not know about the existence 14 * of the tcache at all. 15 */ 16 17 /* 18 * The size in bytes of each cache bin stack. We also use this to indicate 19 * *counts* of individual objects. 20 */ 21 typedef uint16_t cache_bin_sz_t; 22 23 /* 24 * Leave a noticeable mark pattern on the cache bin stack boundaries, in case a 25 * bug starts leaking those. Make it look like the junk pattern but be distinct 26 * from it. 27 */ 28 static const uintptr_t cache_bin_preceding_junk = 29 (uintptr_t)0x7a7a7a7a7a7a7a7aULL; 30 /* Note: a7 vs. 7a above -- this tells you which pointer leaked. */ 31 static const uintptr_t cache_bin_trailing_junk = 32 (uintptr_t)0xa7a7a7a7a7a7a7a7ULL; 33 34 /* 35 * That implies the following value, for the maximum number of items in any 36 * individual bin. The cache bins track their bounds looking just at the low 37 * bits of a pointer, compared against a cache_bin_sz_t. So that's 38 * 1 << (sizeof(cache_bin_sz_t) * 8) 39 * bytes spread across pointer sized objects to get the maximum. 40 */ 41 #define CACHE_BIN_NCACHED_MAX (((size_t)1 << sizeof(cache_bin_sz_t) * 8) \ 42 / sizeof(void *) - 1) 43 44 /* 45 * This lives inside the cache_bin (for locality reasons), and is initialized 46 * alongside it, but is otherwise not modified by any cache bin operations. 47 * It's logically public and maintained by its callers. 48 */ 49 typedef struct cache_bin_stats_s cache_bin_stats_t; 50 struct cache_bin_stats_s { 51 /* 52 * Number of allocation requests that corresponded to the size of this 53 * bin. 54 */ 55 uint64_t nrequests; 56 }; 57 58 /* 59 * Read-only information associated with each element of tcache_t's tbins array 60 * is stored separately, mainly to reduce memory usage. 61 */ 62 typedef struct cache_bin_info_s cache_bin_info_t; 63 struct cache_bin_info_s { 64 cache_bin_sz_t ncached_max; 65 }; 66 67 /* 68 * Responsible for caching allocations associated with a single size. 69 * 70 * Several pointers are used to track the stack. To save on metadata bytes, 71 * only the stack_head is a full sized pointer (which is dereferenced on the 72 * fastpath), while the others store only the low 16 bits -- this is correct 73 * because a single stack never takes more space than 2^16 bytes, and at the 74 * same time only equality checks are performed on the low bits. 75 * 76 * (low addr) (high addr) 77 * |------stashed------|------available------|------cached-----| 78 * ^ ^ ^ ^ 79 * low_bound(derived) low_bits_full stack_head low_bits_empty 80 */ 81 typedef struct cache_bin_s cache_bin_t; 82 struct cache_bin_s { 83 /* 84 * The stack grows down. Whenever the bin is nonempty, the head points 85 * to an array entry containing a valid allocation. When it is empty, 86 * the head points to one element past the owned array. 87 */ 88 void **stack_head; 89 /* 90 * cur_ptr and stats are both modified frequently. Let's keep them 91 * close so that they have a higher chance of being on the same 92 * cacheline, thus less write-backs. 93 */ 94 cache_bin_stats_t tstats; 95 96 /* 97 * The low bits of the address of the first item in the stack that 98 * hasn't been used since the last GC, to track the low water mark (min 99 * # of cached items). 100 * 101 * Since the stack grows down, this is a higher address than 102 * low_bits_full. 103 */ 104 uint16_t low_bits_low_water; 105 106 /* 107 * The low bits of the value that stack_head will take on when the array 108 * is full (of cached & stashed items). But remember that stack_head 109 * always points to a valid item when the array is nonempty -- this is 110 * in the array. 111 * 112 * Recall that since the stack grows down, this is the lowest available 113 * address in the array for caching. Only adjusted when stashing items. 114 */ 115 uint16_t low_bits_full; 116 117 /* 118 * The low bits of the value that stack_head will take on when the array 119 * is empty. 120 * 121 * The stack grows down -- this is one past the highest address in the 122 * array. Immutable after initialization. 123 */ 124 uint16_t low_bits_empty; 125 }; 126 127 /* 128 * The cache_bins live inside the tcache, but the arena (by design) isn't 129 * supposed to know much about tcache internals. To let the arena iterate over 130 * associated bins, we keep (with the tcache) a linked list of 131 * cache_bin_array_descriptor_ts that tell the arena how to find the bins. 132 */ 133 typedef struct cache_bin_array_descriptor_s cache_bin_array_descriptor_t; 134 struct cache_bin_array_descriptor_s { 135 /* 136 * The arena keeps a list of the cache bins associated with it, for 137 * stats collection. 138 */ 139 ql_elm(cache_bin_array_descriptor_t) link; 140 /* Pointers to the tcache bins. */ 141 cache_bin_t *bins; 142 }; 143 144 static inline void 145 cache_bin_array_descriptor_init(cache_bin_array_descriptor_t *descriptor, 146 cache_bin_t *bins) { 147 ql_elm_new(descriptor, link); 148 descriptor->bins = bins; 149 } 150 151 JEMALLOC_ALWAYS_INLINE bool 152 cache_bin_nonfast_aligned(const void *ptr) { 153 if (!config_uaf_detection) { 154 return false; 155 } 156 /* 157 * Currently we use alignment to decide which pointer to junk & stash on 158 * dealloc (for catching use-after-free). In some common cases a 159 * page-aligned check is needed already (sdalloc w/ config_prof), so we 160 * are getting it more or less for free -- no added instructions on 161 * free_fastpath. 162 * 163 * Another way of deciding which pointer to sample, is adding another 164 * thread_event to pick one every N bytes. That also adds no cost on 165 * the fastpath, however it will tend to pick large allocations which is 166 * not the desired behavior. 167 */ 168 return ((uintptr_t)ptr & san_cache_bin_nonfast_mask) == 0; 169 } 170 171 /* Returns ncached_max: Upper limit on ncached. */ 172 static inline cache_bin_sz_t 173 cache_bin_info_ncached_max(cache_bin_info_t *info) { 174 return info->ncached_max; 175 } 176 177 /* 178 * Internal. 179 * 180 * Asserts that the pointer associated with earlier is <= the one associated 181 * with later. 182 */ 183 static inline void 184 cache_bin_assert_earlier(cache_bin_t *bin, uint16_t earlier, uint16_t later) { 185 if (earlier > later) { 186 assert(bin->low_bits_full > bin->low_bits_empty); 187 } 188 } 189 190 /* 191 * Internal. 192 * 193 * Does difference calculations that handle wraparound correctly. Earlier must 194 * be associated with the position earlier in memory. 195 */ 196 static inline uint16_t 197 cache_bin_diff(cache_bin_t *bin, uint16_t earlier, uint16_t later, bool racy) { 198 /* 199 * When it's racy, bin->low_bits_full can be modified concurrently. It 200 * can cross the uint16_t max value and become less than 201 * bin->low_bits_empty at the time of the check. 202 */ 203 if (!racy) { 204 cache_bin_assert_earlier(bin, earlier, later); 205 } 206 return later - earlier; 207 } 208 209 /* 210 * Number of items currently cached in the bin, without checking ncached_max. 211 * We require specifying whether or not the request is racy or not (i.e. whether 212 * or not concurrent modifications are possible). 213 */ 214 static inline cache_bin_sz_t 215 cache_bin_ncached_get_internal(cache_bin_t *bin, bool racy) { 216 cache_bin_sz_t diff = cache_bin_diff(bin, 217 (uint16_t)(uintptr_t)bin->stack_head, bin->low_bits_empty, racy); 218 cache_bin_sz_t n = diff / sizeof(void *); 219 /* 220 * We have undefined behavior here; if this function is called from the 221 * arena stats updating code, then stack_head could change from the 222 * first line to the next one. Morally, these loads should be atomic, 223 * but compilers won't currently generate comparisons with in-memory 224 * operands against atomics, and these variables get accessed on the 225 * fast paths. This should still be "safe" in the sense of generating 226 * the correct assembly for the foreseeable future, though. 227 */ 228 assert(n == 0 || *(bin->stack_head) != NULL || racy); 229 return n; 230 } 231 232 /* 233 * Number of items currently cached in the bin, with checking ncached_max. The 234 * caller must know that no concurrent modification of the cache_bin is 235 * possible. 236 */ 237 static inline cache_bin_sz_t 238 cache_bin_ncached_get_local(cache_bin_t *bin, cache_bin_info_t *info) { 239 cache_bin_sz_t n = cache_bin_ncached_get_internal(bin, 240 /* racy */ false); 241 assert(n <= cache_bin_info_ncached_max(info)); 242 return n; 243 } 244 245 /* 246 * Internal. 247 * 248 * A pointer to the position one past the end of the backing array. 249 * 250 * Do not call if racy, because both 'bin->stack_head' and 'bin->low_bits_full' 251 * are subject to concurrent modifications. 252 */ 253 static inline void ** 254 cache_bin_empty_position_get(cache_bin_t *bin) { 255 cache_bin_sz_t diff = cache_bin_diff(bin, 256 (uint16_t)(uintptr_t)bin->stack_head, bin->low_bits_empty, 257 /* racy */ false); 258 uintptr_t empty_bits = (uintptr_t)bin->stack_head + diff; 259 void **ret = (void **)empty_bits; 260 261 assert(ret >= bin->stack_head); 262 263 return ret; 264 } 265 266 /* 267 * Internal. 268 * 269 * Calculates low bits of the lower bound of the usable cache bin's range (see 270 * cache_bin_t visual representation above). 271 * 272 * No values are concurrently modified, so should be safe to read in a 273 * multithreaded environment. Currently concurrent access happens only during 274 * arena statistics collection. 275 */ 276 static inline uint16_t 277 cache_bin_low_bits_low_bound_get(cache_bin_t *bin, cache_bin_info_t *info) { 278 return (uint16_t)bin->low_bits_empty - 279 info->ncached_max * sizeof(void *); 280 } 281 282 /* 283 * Internal. 284 * 285 * A pointer to the position with the lowest address of the backing array. 286 */ 287 static inline void ** 288 cache_bin_low_bound_get(cache_bin_t *bin, cache_bin_info_t *info) { 289 cache_bin_sz_t ncached_max = cache_bin_info_ncached_max(info); 290 void **ret = cache_bin_empty_position_get(bin) - ncached_max; 291 assert(ret <= bin->stack_head); 292 293 return ret; 294 } 295 296 /* 297 * As the name implies. This is important since it's not correct to try to 298 * batch fill a nonempty cache bin. 299 */ 300 static inline void 301 cache_bin_assert_empty(cache_bin_t *bin, cache_bin_info_t *info) { 302 assert(cache_bin_ncached_get_local(bin, info) == 0); 303 assert(cache_bin_empty_position_get(bin) == bin->stack_head); 304 } 305 306 /* 307 * Get low water, but without any of the correctness checking we do for the 308 * caller-usable version, if we are temporarily breaking invariants (like 309 * ncached >= low_water during flush). 310 */ 311 static inline cache_bin_sz_t 312 cache_bin_low_water_get_internal(cache_bin_t *bin) { 313 return cache_bin_diff(bin, bin->low_bits_low_water, 314 bin->low_bits_empty, /* racy */ false) / sizeof(void *); 315 } 316 317 /* Returns the numeric value of low water in [0, ncached]. */ 318 static inline cache_bin_sz_t 319 cache_bin_low_water_get(cache_bin_t *bin, cache_bin_info_t *info) { 320 cache_bin_sz_t low_water = cache_bin_low_water_get_internal(bin); 321 assert(low_water <= cache_bin_info_ncached_max(info)); 322 assert(low_water <= cache_bin_ncached_get_local(bin, info)); 323 324 cache_bin_assert_earlier(bin, (uint16_t)(uintptr_t)bin->stack_head, 325 bin->low_bits_low_water); 326 327 return low_water; 328 } 329 330 /* 331 * Indicates that the current cache bin position should be the low water mark 332 * going forward. 333 */ 334 static inline void 335 cache_bin_low_water_set(cache_bin_t *bin) { 336 bin->low_bits_low_water = (uint16_t)(uintptr_t)bin->stack_head; 337 } 338 339 static inline void 340 cache_bin_low_water_adjust(cache_bin_t *bin) { 341 if (cache_bin_ncached_get_internal(bin, /* racy */ false) 342 < cache_bin_low_water_get_internal(bin)) { 343 cache_bin_low_water_set(bin); 344 } 345 } 346 347 JEMALLOC_ALWAYS_INLINE void * 348 cache_bin_alloc_impl(cache_bin_t *bin, bool *success, bool adjust_low_water) { 349 /* 350 * success (instead of ret) should be checked upon the return of this 351 * function. We avoid checking (ret == NULL) because there is never a 352 * null stored on the avail stack (which is unknown to the compiler), 353 * and eagerly checking ret would cause pipeline stall (waiting for the 354 * cacheline). 355 */ 356 357 /* 358 * This may read from the empty position; however the loaded value won't 359 * be used. It's safe because the stack has one more slot reserved. 360 */ 361 void *ret = *bin->stack_head; 362 uint16_t low_bits = (uint16_t)(uintptr_t)bin->stack_head; 363 void **new_head = bin->stack_head + 1; 364 365 /* 366 * Note that the low water mark is at most empty; if we pass this check, 367 * we know we're non-empty. 368 */ 369 if (likely(low_bits != bin->low_bits_low_water)) { 370 bin->stack_head = new_head; 371 *success = true; 372 return ret; 373 } 374 if (!adjust_low_water) { 375 *success = false; 376 return NULL; 377 } 378 /* 379 * In the fast-path case where we call alloc_easy and then alloc, the 380 * previous checking and computation is optimized away -- we didn't 381 * actually commit any of our operations. 382 */ 383 if (likely(low_bits != bin->low_bits_empty)) { 384 bin->stack_head = new_head; 385 bin->low_bits_low_water = (uint16_t)(uintptr_t)new_head; 386 *success = true; 387 return ret; 388 } 389 *success = false; 390 return NULL; 391 } 392 393 /* 394 * Allocate an item out of the bin, failing if we're at the low-water mark. 395 */ 396 JEMALLOC_ALWAYS_INLINE void * 397 cache_bin_alloc_easy(cache_bin_t *bin, bool *success) { 398 /* We don't look at info if we're not adjusting low-water. */ 399 return cache_bin_alloc_impl(bin, success, false); 400 } 401 402 /* 403 * Allocate an item out of the bin, even if we're currently at the low-water 404 * mark (and failing only if the bin is empty). 405 */ 406 JEMALLOC_ALWAYS_INLINE void * 407 cache_bin_alloc(cache_bin_t *bin, bool *success) { 408 return cache_bin_alloc_impl(bin, success, true); 409 } 410 411 JEMALLOC_ALWAYS_INLINE cache_bin_sz_t 412 cache_bin_alloc_batch(cache_bin_t *bin, size_t num, void **out) { 413 cache_bin_sz_t n = cache_bin_ncached_get_internal(bin, 414 /* racy */ false); 415 if (n > num) { 416 n = (cache_bin_sz_t)num; 417 } 418 memcpy(out, bin->stack_head, n * sizeof(void *)); 419 bin->stack_head += n; 420 cache_bin_low_water_adjust(bin); 421 422 return n; 423 } 424 425 JEMALLOC_ALWAYS_INLINE bool 426 cache_bin_full(cache_bin_t *bin) { 427 return ((uint16_t)(uintptr_t)bin->stack_head == bin->low_bits_full); 428 } 429 430 /* 431 * Free an object into the given bin. Fails only if the bin is full. 432 */ 433 JEMALLOC_ALWAYS_INLINE bool 434 cache_bin_dalloc_easy(cache_bin_t *bin, void *ptr) { 435 if (unlikely(cache_bin_full(bin))) { 436 return false; 437 } 438 439 bin->stack_head--; 440 *bin->stack_head = ptr; 441 cache_bin_assert_earlier(bin, bin->low_bits_full, 442 (uint16_t)(uintptr_t)bin->stack_head); 443 444 return true; 445 } 446 447 /* Returns false if failed to stash (i.e. bin is full). */ 448 JEMALLOC_ALWAYS_INLINE bool 449 cache_bin_stash(cache_bin_t *bin, void *ptr) { 450 if (cache_bin_full(bin)) { 451 return false; 452 } 453 454 /* Stash at the full position, in the [full, head) range. */ 455 uint16_t low_bits_head = (uint16_t)(uintptr_t)bin->stack_head; 456 /* Wraparound handled as well. */ 457 uint16_t diff = cache_bin_diff(bin, bin->low_bits_full, low_bits_head, 458 /* racy */ false); 459 *(void **)((uintptr_t)bin->stack_head - diff) = ptr; 460 461 assert(!cache_bin_full(bin)); 462 bin->low_bits_full += sizeof(void *); 463 cache_bin_assert_earlier(bin, bin->low_bits_full, low_bits_head); 464 465 return true; 466 } 467 468 /* 469 * Get the number of stashed pointers. 470 * 471 * When called from a thread not owning the TLS (i.e. racy = true), it's 472 * important to keep in mind that 'bin->stack_head' and 'bin->low_bits_full' can 473 * be modified concurrently and almost none assertions about their values can be 474 * made. 475 */ 476 JEMALLOC_ALWAYS_INLINE cache_bin_sz_t 477 cache_bin_nstashed_get_internal(cache_bin_t *bin, cache_bin_info_t *info, 478 bool racy) { 479 cache_bin_sz_t ncached_max = cache_bin_info_ncached_max(info); 480 uint16_t low_bits_low_bound = cache_bin_low_bits_low_bound_get(bin, 481 info); 482 483 cache_bin_sz_t n = cache_bin_diff(bin, low_bits_low_bound, 484 bin->low_bits_full, racy) / sizeof(void *); 485 assert(n <= ncached_max); 486 487 if (!racy) { 488 /* Below are for assertions only. */ 489 void **low_bound = cache_bin_low_bound_get(bin, info); 490 491 assert((uint16_t)(uintptr_t)low_bound == low_bits_low_bound); 492 void *stashed = *(low_bound + n - 1); 493 bool aligned = cache_bin_nonfast_aligned(stashed); 494 #ifdef JEMALLOC_JET 495 /* Allow arbitrary pointers to be stashed in tests. */ 496 aligned = true; 497 #endif 498 assert(n == 0 || (stashed != NULL && aligned)); 499 } 500 501 return n; 502 } 503 504 JEMALLOC_ALWAYS_INLINE cache_bin_sz_t 505 cache_bin_nstashed_get_local(cache_bin_t *bin, cache_bin_info_t *info) { 506 cache_bin_sz_t n = cache_bin_nstashed_get_internal(bin, info, 507 /* racy */ false); 508 assert(n <= cache_bin_info_ncached_max(info)); 509 return n; 510 } 511 512 /* 513 * Obtain a racy view of the number of items currently in the cache bin, in the 514 * presence of possible concurrent modifications. 515 */ 516 static inline void 517 cache_bin_nitems_get_remote(cache_bin_t *bin, cache_bin_info_t *info, 518 cache_bin_sz_t *ncached, cache_bin_sz_t *nstashed) { 519 cache_bin_sz_t n = cache_bin_ncached_get_internal(bin, /* racy */ true); 520 assert(n <= cache_bin_info_ncached_max(info)); 521 *ncached = n; 522 523 n = cache_bin_nstashed_get_internal(bin, info, /* racy */ true); 524 assert(n <= cache_bin_info_ncached_max(info)); 525 *nstashed = n; 526 /* Note that cannot assert ncached + nstashed <= ncached_max (racy). */ 527 } 528 529 /* 530 * Filling and flushing are done in batch, on arrays of void *s. For filling, 531 * the arrays go forward, and can be accessed with ordinary array arithmetic. 532 * For flushing, we work from the end backwards, and so need to use special 533 * accessors that invert the usual ordering. 534 * 535 * This is important for maintaining first-fit; the arena code fills with 536 * earliest objects first, and so those are the ones we should return first for 537 * cache_bin_alloc calls. When flushing, we should flush the objects that we 538 * wish to return later; those at the end of the array. This is better for the 539 * first-fit heuristic as well as for cache locality; the most recently freed 540 * objects are the ones most likely to still be in cache. 541 * 542 * This all sounds very hand-wavey and theoretical, but reverting the ordering 543 * on one or the other pathway leads to measurable slowdowns. 544 */ 545 546 typedef struct cache_bin_ptr_array_s cache_bin_ptr_array_t; 547 struct cache_bin_ptr_array_s { 548 cache_bin_sz_t n; 549 void **ptr; 550 }; 551 552 /* 553 * Declare a cache_bin_ptr_array_t sufficient for nval items. 554 * 555 * In the current implementation, this could be just part of a 556 * cache_bin_ptr_array_init_... call, since we reuse the cache bin stack memory. 557 * Indirecting behind a macro, though, means experimenting with linked-list 558 * representations is easy (since they'll require an alloca in the calling 559 * frame). 560 */ 561 #define CACHE_BIN_PTR_ARRAY_DECLARE(name, nval) \ 562 cache_bin_ptr_array_t name; \ 563 name.n = (nval) 564 565 /* 566 * Start a fill. The bin must be empty, and This must be followed by a 567 * finish_fill call before doing any alloc/dalloc operations on the bin. 568 */ 569 static inline void 570 cache_bin_init_ptr_array_for_fill(cache_bin_t *bin, cache_bin_info_t *info, 571 cache_bin_ptr_array_t *arr, cache_bin_sz_t nfill) { 572 cache_bin_assert_empty(bin, info); 573 arr->ptr = cache_bin_empty_position_get(bin) - nfill; 574 } 575 576 /* 577 * While nfill in cache_bin_init_ptr_array_for_fill is the number we *intend* to 578 * fill, nfilled here is the number we actually filled (which may be less, in 579 * case of OOM. 580 */ 581 static inline void 582 cache_bin_finish_fill(cache_bin_t *bin, cache_bin_info_t *info, 583 cache_bin_ptr_array_t *arr, cache_bin_sz_t nfilled) { 584 cache_bin_assert_empty(bin, info); 585 void **empty_position = cache_bin_empty_position_get(bin); 586 if (nfilled < arr->n) { 587 memmove(empty_position - nfilled, empty_position - arr->n, 588 nfilled * sizeof(void *)); 589 } 590 bin->stack_head = empty_position - nfilled; 591 } 592 593 /* 594 * Same deal, but with flush. Unlike fill (which can fail), the user must flush 595 * everything we give them. 596 */ 597 static inline void 598 cache_bin_init_ptr_array_for_flush(cache_bin_t *bin, cache_bin_info_t *info, 599 cache_bin_ptr_array_t *arr, cache_bin_sz_t nflush) { 600 arr->ptr = cache_bin_empty_position_get(bin) - nflush; 601 assert(cache_bin_ncached_get_local(bin, info) == 0 602 || *arr->ptr != NULL); 603 } 604 605 static inline void 606 cache_bin_finish_flush(cache_bin_t *bin, cache_bin_info_t *info, 607 cache_bin_ptr_array_t *arr, cache_bin_sz_t nflushed) { 608 unsigned rem = cache_bin_ncached_get_local(bin, info) - nflushed; 609 memmove(bin->stack_head + nflushed, bin->stack_head, 610 rem * sizeof(void *)); 611 bin->stack_head = bin->stack_head + nflushed; 612 cache_bin_low_water_adjust(bin); 613 } 614 615 static inline void 616 cache_bin_init_ptr_array_for_stashed(cache_bin_t *bin, szind_t binind, 617 cache_bin_info_t *info, cache_bin_ptr_array_t *arr, 618 cache_bin_sz_t nstashed) { 619 assert(nstashed > 0); 620 assert(cache_bin_nstashed_get_local(bin, info) == nstashed); 621 622 void **low_bound = cache_bin_low_bound_get(bin, info); 623 arr->ptr = low_bound; 624 assert(*arr->ptr != NULL); 625 } 626 627 static inline void 628 cache_bin_finish_flush_stashed(cache_bin_t *bin, cache_bin_info_t *info) { 629 void **low_bound = cache_bin_low_bound_get(bin, info); 630 631 /* Reset the bin local full position. */ 632 bin->low_bits_full = (uint16_t)(uintptr_t)low_bound; 633 assert(cache_bin_nstashed_get_local(bin, info) == 0); 634 } 635 636 /* 637 * Initialize a cache_bin_info to represent up to the given number of items in 638 * the cache_bins it is associated with. 639 */ 640 void cache_bin_info_init(cache_bin_info_t *bin_info, 641 cache_bin_sz_t ncached_max); 642 /* 643 * Given an array of initialized cache_bin_info_ts, determine how big an 644 * allocation is required to initialize a full set of cache_bin_ts. 645 */ 646 void cache_bin_info_compute_alloc(cache_bin_info_t *infos, szind_t ninfos, 647 size_t *size, size_t *alignment); 648 649 /* 650 * Actually initialize some cache bins. Callers should allocate the backing 651 * memory indicated by a call to cache_bin_compute_alloc. They should then 652 * preincrement, call init once for each bin and info, and then call 653 * cache_bin_postincrement. *alloc_cur will then point immediately past the end 654 * of the allocation. 655 */ 656 void cache_bin_preincrement(cache_bin_info_t *infos, szind_t ninfos, 657 void *alloc, size_t *cur_offset); 658 void cache_bin_postincrement(cache_bin_info_t *infos, szind_t ninfos, 659 void *alloc, size_t *cur_offset); 660 void cache_bin_init(cache_bin_t *bin, cache_bin_info_t *info, void *alloc, 661 size_t *cur_offset); 662 663 /* 664 * If a cache bin was zero initialized (either because it lives in static or 665 * thread-local storage, or was memset to 0), this function indicates whether or 666 * not cache_bin_init was called on it. 667 */ 668 bool cache_bin_still_zero_initialized(cache_bin_t *bin); 669 670 #endif /* JEMALLOC_INTERNAL_CACHE_BIN_H */ 671