in dispenso/detail/concurrent_vector_impl.h [381:447]
void allocAsNecessary(const BucketInfo& binfo, ssize_t rangeLen, const BucketInfo& bend) {
const size_t indexToCheck = (kStrategy == ConcurrentVectorReallocStrategy::kFullBufferAhead)
? 0
: (kStrategy == ConcurrentVectorReallocStrategy::kHalfBufferAhead
? binfo.bucketCapacity / 2
: binfo.bucketCapacity - 1);
bool allocCurrentBucket =
binfo.bucketIndex <= indexToCheck && binfo.bucketIndex + rangeLen > indexToCheck;
if (DISPENSO_EXPECT(allocCurrentBucket || binfo.bucket < bend.bucket, 0)) {
size_t sizeToAlloc = 0;
size_t cap = binfo.bucketCapacity << ((bool)binfo.bucket + !allocCurrentBucket);
size_t bucket = binfo.bucket + 1 + !allocCurrentBucket;
for (; bucket <= bend.bucket; ++bucket, cap <<= 1) {
if (!this->buffers_[bucket].load(std::memory_order_acquire)) {
sizeToAlloc += cap;
}
}
assert(bucket == bend.bucket + 1);
assert((bucket == 1 && cap == bend.bucketCapacity) || cap == bend.bucketCapacity * 2);
const size_t endToCheck = (kStrategy == ConcurrentVectorReallocStrategy::kFullBufferAhead)
? 0
: (kStrategy == ConcurrentVectorReallocStrategy::kHalfBufferAhead
? bend.bucketCapacity / 2
: bend.bucketCapacity - 1);
if (DISPENSO_EXPECT(bend.bucketIndex > endToCheck, 0)) {
if (!this->buffers_[bucket].load(std::memory_order_acquire)) {
sizeToAlloc += cap;
}
}
T* allocBufs = nullptr;
if (sizeToAlloc) {
allocBufs = cv::alloc<T>(sizeToAlloc);
}
bool firstAccounted = false;
cap = binfo.bucketCapacity << ((bool)binfo.bucket + !allocCurrentBucket);
bucket = binfo.bucket + 1 + !allocCurrentBucket;
for (; bucket <= bend.bucket; ++bucket, cap <<= 1) {
if (!this->buffers_[bucket].load(std::memory_order_acquire)) {
this->buffers_[bucket].store(allocBufs, std::memory_order_release);
allocBufs += cap;
shouldDealloc_[bucket] = !firstAccounted;
firstAccounted = true;
}
}
assert(bucket == bend.bucket + 1);
assert((bucket == 1 && cap == bend.bucketCapacity) || cap == bend.bucketCapacity * 2);
if (DISPENSO_EXPECT(bend.bucketIndex > endToCheck, 0)) {
if (!this->buffers_[bucket].load(std::memory_order_acquire)) {
this->buffers_[bucket].store(allocBufs, std::memory_order_release);
shouldDealloc_[bucket] = !firstAccounted;
}
}
}
for (size_t bucket = binfo.bucket; bucket <= bend.bucket; ++bucket) {
while (DISPENSO_EXPECT(!this->buffers_[bucket].load(std::memory_order_acquire), 0)) {
}
}
}