QContiguousCache: drag the initialization of atomic ref behind ABI boundary
All callers of QContiguousCache<T>::allocateData() followed the call with a storeRelaxed(1) to the ref member. So we can just drag that into the function itself. Next, it's UB to storeRelaxed() into a default-constructed std::atomic (and, therefore, into a QBasicAtomicInt), because until C++17 (inclusive) you're supposed to use std::atomic_init to assign the first (and only the first) value to a default-constructed std::atomic. QBasicAtomic doesn't have API for that, so you can never assign anything to a default-constructed QBasicAtomic. To fix, use placement new to be able to create a QBasicAtomic directly with an initial value (replacing QBasicAtomic with QAtomic wouldn't help here, either, since a malloc doesn't run ctors). A proper fix has to wait until we can depend on C++20's atomic_ref, which decouples the underlying type from the atomic operations performed on it, letting us depend on malloc's zero-initialization of an int member properly initializing it even for a following atomic operation on it. Task-number: QTBUG-137465 Pick-to: 6.10 6.9 6.8 6.5 Change-Id: Ic22d0766bcffb967a86c8ec28b63ee480aebd4a0 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
4896448ffd
commit
49db71bb19
@ -22,7 +22,8 @@ void QContiguousCacheData::dump() const
|
||||
|
||||
QContiguousCacheData *QContiguousCacheData::allocateData(qsizetype size, qsizetype alignment)
|
||||
{
|
||||
return static_cast<QContiguousCacheData *>(qMallocAligned(size_t(size), size_t(alignment)));
|
||||
void *mem = qMallocAligned(size_t(size), size_t(alignment));
|
||||
return new (mem) QContiguousCacheData{/*ref=*/1, 0, 0, 0, 0};
|
||||
}
|
||||
|
||||
void QContiguousCacheData::freeData(QContiguousCacheData *data)
|
||||
|
@ -152,7 +152,6 @@ template <typename T>
|
||||
void QContiguousCache<T>::detach_helper()
|
||||
{
|
||||
Data *x = allocateData(d->alloc);
|
||||
x->ref.storeRelaxed(1);
|
||||
x->count = d->count;
|
||||
x->start = d->start;
|
||||
x->offset = d->offset;
|
||||
@ -184,7 +183,6 @@ void QContiguousCache<T>::setCapacity(qsizetype asize)
|
||||
return;
|
||||
detach();
|
||||
Data *x = allocateData(asize);
|
||||
x->ref.storeRelaxed(1);
|
||||
x->alloc = asize;
|
||||
x->count = qMin(d->count, asize);
|
||||
x->offset = d->offset + d->count - x->count;
|
||||
@ -231,7 +229,6 @@ void QContiguousCache<T>::clear()
|
||||
d->count = d->start = d->offset = 0;
|
||||
} else {
|
||||
Data *x = allocateData(d->alloc);
|
||||
x->ref.storeRelaxed(1);
|
||||
x->alloc = d->alloc;
|
||||
x->count = x->start = x->offset = 0;
|
||||
if (!d->ref.deref())
|
||||
@ -251,7 +248,6 @@ QContiguousCache<T>::QContiguousCache(qsizetype cap)
|
||||
{
|
||||
Q_ASSERT(cap >= 0);
|
||||
d = allocateData(cap);
|
||||
d->ref.storeRelaxed(1);
|
||||
d->alloc = cap;
|
||||
d->count = d->start = d->offset = 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user