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:
David Faure 2014-05-23 20:22:02 +02:00 committed by The Qt Project
parent 958a4c9087
commit 8636bade17

View File

@ -73,7 +73,7 @@ struct QFreeListElement
typedef T &ReferenceType;
T _t;
int next;
QAtomicInt next;
inline ConstReferenceType t() const { return _t; }
inline ReferenceType t() { return _t; }
@ -90,7 +90,7 @@ struct QFreeListElement<void>
typedef void ConstReferenceType;
typedef void ReferenceType;
int next;
QAtomicInt next;
inline void t() const { }
inline void t() { }
@ -172,7 +172,7 @@ class QFreeList
// qDebug("QFreeList: allocating %d elements (%ld bytes) with offset %d", size, size * sizeof(ElementType), offset);
ElementType *v = new ElementType[size];
for (int i = 0; i < size; ++i)
v[i].next = offset + i + 1;
v[i].next.store(offset + i + 1);
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));
// qDebug("QFreeList::next(): returning %d (_next now %d, serial %d)",
// id & ConstantsType::IndexMask,
@ -273,7 +273,7 @@ inline void QFreeList<T, ConstantsType>::release(int id)
int x, newid;
do {
x = _next.loadAcquire();
v[at].next = x & ConstantsType::IndexMask;
v[at].next.store(x & ConstantsType::IndexMask);
newid = incrementserial(x, id);
} while (!_next.testAndSetRelease(x, newid));