| 343 | } |
| 344 | |
| 345 | void* unsynchronized_pool_resource::do_allocate(size_t bytes, size_t align) { |
| 346 | // A pointer to allocated storage (6.6.4.4.1) with a size of at least bytes. |
| 347 | // The size and alignment of the allocated memory shall meet the requirements for |
| 348 | // a class derived from memory_resource (23.12). |
| 349 | // If the pool selected for a block of size bytes is unable to satisfy the memory request |
| 350 | // from its own internal data structures, it will call upstream_resource()->allocate() |
| 351 | // to obtain more memory. If bytes is larger than that which the largest pool can handle, |
| 352 | // then memory will be allocated using upstream_resource()->allocate(). |
| 353 | |
| 354 | int i = __pool_index(bytes, align); |
| 355 | if (i == __num_fixed_pools_) |
| 356 | return __adhoc_pool_.__do_allocate(__res_, bytes, align); |
| 357 | else { |
| 358 | if (__fixed_pools_ == nullptr) { |
| 359 | __fixed_pools_ = |
| 360 | (__fixed_pool*)__res_->allocate(__num_fixed_pools_ * sizeof(__fixed_pool), alignof(__fixed_pool)); |
| 361 | __fixed_pool* first = __fixed_pools_; |
| 362 | __fixed_pool* last = __fixed_pools_ + __num_fixed_pools_; |
| 363 | for (__fixed_pool* pool = first; pool != last; ++pool) |
| 364 | ::new ((void*)pool) __fixed_pool; |
| 365 | } |
| 366 | void* result = __fixed_pools_[i].__try_allocate_from_vacancies(); |
| 367 | if (result == nullptr) { |
| 368 | auto min = [](size_t a, size_t b) { return a < b ? a : b; }; |
| 369 | auto max = [](size_t a, size_t b) { return a < b ? b : a; }; |
| 370 | |
| 371 | size_t prev_chunk_size_in_bytes = __fixed_pools_[i].__previous_chunk_size_in_bytes(); |
| 372 | size_t prev_chunk_size_in_blocks = prev_chunk_size_in_bytes >> __log2_pool_block_size(i); |
| 373 | |
| 374 | size_t chunk_size_in_blocks; |
| 375 | |
| 376 | if (prev_chunk_size_in_blocks == 0) { |
| 377 | size_t min_blocks_per_chunk = max(__min_bytes_per_chunk >> __log2_pool_block_size(i), __min_blocks_per_chunk); |
| 378 | chunk_size_in_blocks = min_blocks_per_chunk; |
| 379 | } else { |
| 380 | static_assert(__max_bytes_per_chunk <= SIZE_MAX - (__max_bytes_per_chunk / 4), "unsigned overflow is possible"); |
| 381 | chunk_size_in_blocks = prev_chunk_size_in_blocks + (prev_chunk_size_in_blocks / 4); |
| 382 | } |
| 383 | |
| 384 | size_t max_blocks_per_chunk = |
| 385 | min((__max_bytes_per_chunk >> __log2_pool_block_size(i)), |
| 386 | min(__max_blocks_per_chunk, __options_max_blocks_per_chunk_)); |
| 387 | if (chunk_size_in_blocks > max_blocks_per_chunk) |
| 388 | chunk_size_in_blocks = max_blocks_per_chunk; |
| 389 | |
| 390 | size_t block_size = __pool_block_size(i); |
| 391 | |
| 392 | size_t chunk_size_in_bytes = (chunk_size_in_blocks << __log2_pool_block_size(i)); |
| 393 | result = __fixed_pools_[i].__allocate_in_new_chunk(__res_, block_size, chunk_size_in_bytes); |
| 394 | } |
| 395 | return result; |
| 396 | } |
| 397 | } |
| 398 | |
| 399 | void unsynchronized_pool_resource::do_deallocate(void* p, size_t bytes, size_t align) { |
| 400 | // Returns the memory at p to the pool. It is unspecified if, |
nothing calls this directly
no test coverage detected