| 266 | } |
| 267 | |
| 268 | bool MemoryPool::provision(const std::vector<uint32_t>& slabsDistribution) { |
| 269 | if (slabsDistribution.size() != ac_.size()) { |
| 270 | throw std::invalid_argument( |
| 271 | fmt::format("Invalid slabs distribution. Expected {} ACs, Got {}", |
| 272 | ac_.size(), slabsDistribution.size())); |
| 273 | } |
| 274 | |
| 275 | auto freeAllSlabs = [this](const std::list<Slab*>& slabs) { |
| 276 | for (auto* s : slabs) { |
| 277 | slabAllocator_.freeSlab(s); |
| 278 | currSlabAllocSize_ -= Slab::kSize; |
| 279 | } |
| 280 | }; |
| 281 | |
| 282 | LockHolder l(lock_); |
| 283 | uint32_t totalSlabsToAllocate = |
| 284 | std::accumulate(slabsDistribution.begin(), slabsDistribution.end(), 0); |
| 285 | std::list<Slab*> slabs; |
| 286 | for (uint32_t i = 0; i < totalSlabsToAllocate; i++) { |
| 287 | auto slab = getSlabLocked(); |
| 288 | if (slab == nullptr) { |
| 289 | freeAllSlabs(slabs); |
| 290 | XLOGF(ERR, |
| 291 | "Failed to find enough slabs to provision for pool {}. Need: {}, " |
| 292 | "Found: {}", |
| 293 | id_, totalSlabsToAllocate, i); |
| 294 | return false; |
| 295 | } |
| 296 | slabs.push_back(slab); |
| 297 | } |
| 298 | for (size_t i = 0; i < slabsDistribution.size(); i++) { |
| 299 | for (size_t j = 0; j < slabsDistribution[i]; ++j) { |
| 300 | ac_[i]->addSlab(slabs.front()); |
| 301 | slabs.pop_front(); |
| 302 | } |
| 303 | } |
| 304 | return true; |
| 305 | } |
| 306 | |
| 307 | void* MemoryPool::allocate(uint32_t size) { |
| 308 | auto& ac = getAllocationClassFor(size); |
no test coverage detected