qfreelist: fix data race on v[at].next
Detected by clang's -fsanitize=thread in tst_qcoreapplication. Task-number: QTBUG-39024 Change-Id: I60b7cece0384f89dc62ac5128faf39a4084e72e2 Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
This commit is contained in:
parent
958a4c9087
commit
8636bade17
@ -73,7 +73,7 @@ struct QFreeListElement
|
|||||||
typedef T &ReferenceType;
|
typedef T &ReferenceType;
|
||||||
|
|
||||||
T _t;
|
T _t;
|
||||||
int next;
|
QAtomicInt next;
|
||||||
|
|
||||||
inline ConstReferenceType t() const { return _t; }
|
inline ConstReferenceType t() const { return _t; }
|
||||||
inline ReferenceType t() { return _t; }
|
inline ReferenceType t() { return _t; }
|
||||||
@ -90,7 +90,7 @@ struct QFreeListElement<void>
|
|||||||
typedef void ConstReferenceType;
|
typedef void ConstReferenceType;
|
||||||
typedef void ReferenceType;
|
typedef void ReferenceType;
|
||||||
|
|
||||||
int next;
|
QAtomicInt next;
|
||||||
|
|
||||||
inline void t() const { }
|
inline void t() const { }
|
||||||
inline void t() { }
|
inline void t() { }
|
||||||
@ -172,7 +172,7 @@ class QFreeList
|
|||||||
// qDebug("QFreeList: allocating %d elements (%ld bytes) with offset %d", size, size * sizeof(ElementType), offset);
|
// qDebug("QFreeList: allocating %d elements (%ld bytes) with offset %d", size, size * sizeof(ElementType), offset);
|
||||||
ElementType *v = new ElementType[size];
|
ElementType *v = new ElementType[size];
|
||||||
for (int i = 0; i < size; ++i)
|
for (int i = 0; i < size; ++i)
|
||||||
v[i].next = offset + i + 1;
|
v[i].next.store(offset + i + 1);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,7 +254,7 @@ inline int QFreeList<T, ConstantsType>::next()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
newid = v[at].next | (id & ~ConstantsType::IndexMask);
|
newid = v[at].next.load() | (id & ~ConstantsType::IndexMask);
|
||||||
} while (!_next.testAndSetRelaxed(id, newid));
|
} while (!_next.testAndSetRelaxed(id, newid));
|
||||||
// qDebug("QFreeList::next(): returning %d (_next now %d, serial %d)",
|
// qDebug("QFreeList::next(): returning %d (_next now %d, serial %d)",
|
||||||
// id & ConstantsType::IndexMask,
|
// id & ConstantsType::IndexMask,
|
||||||
@ -273,7 +273,7 @@ inline void QFreeList<T, ConstantsType>::release(int id)
|
|||||||
int x, newid;
|
int x, newid;
|
||||||
do {
|
do {
|
||||||
x = _next.loadAcquire();
|
x = _next.loadAcquire();
|
||||||
v[at].next = x & ConstantsType::IndexMask;
|
v[at].next.store(x & ConstantsType::IndexMask);
|
||||||
|
|
||||||
newid = incrementserial(x, id);
|
newid = incrementserial(x, id);
|
||||||
} while (!_next.testAndSetRelease(x, newid));
|
} while (!_next.testAndSetRelease(x, newid));
|
||||||
|
Loading…
Reference in New Issue
Block a user