summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBradley T. Hughes <bradley.hughes@nokia.com>2011-09-29 11:45:01 +0200
committerQt by Nokia <qt-info@nokia.com>2011-10-05 16:31:37 +0200
commita4a94544f27a66ea1189a3a5927ed2dafc28f88c (patch)
treed83848aa6191436ad13608101773de9709f66218
parent0e339e2ef5138f93480a5cc60add1c8a26858907 (diff)
Don't use implicit QAtomic* casts in QFreeList
Pair the _next.testAndSetRelease() call in QFreeList<T>::release() with _next.loadAcquire(), to ensure that the update to the bucket being released is properly fenced. QFreeList<T>:next() does not need a release fence, only an acquire fence, which is placed on the memory bucket address load. Change-Id: Ib5b9d6ef6107f87aa8e3ea2dd3a7f9116c75da70 Reviewed-by: Thiago Macieira Reviewed-on: http://codereview.qt-project.org/5802 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: João Abecasis <joao.abecasis@nokia.com>
-rw-r--r--src/corelib/tools/qfreelist_p.h18
1 files changed, 9 insertions, 9 deletions
diff --git a/src/corelib/tools/qfreelist_p.h b/src/corelib/tools/qfreelist_p.h
index 74ba3b587e..5af0bb1807 100644
--- a/src/corelib/tools/qfreelist_p.h
+++ b/src/corelib/tools/qfreelist_p.h
@@ -218,21 +218,21 @@ template <typename T, typename ConstantsType>
inline QFreeList<T, ConstantsType>::~QFreeList()
{
for (int i = 0; i < ConstantsType::BlockCount; ++i)
- delete [] static_cast<ElementType *>(_v[i]);
+ delete [] _v[i].load();
}
template <typename T, typename ConstantsType>
inline typename QFreeList<T, ConstantsType>::ConstReferenceType QFreeList<T, ConstantsType>::at(int x) const
{
const int block = blockfor(x);
- return _v[block][x].t();
+ return (_v[block].load())[x].t();
}
template <typename T, typename ConstantsType>
inline typename QFreeList<T, ConstantsType>::ReferenceType QFreeList<T, ConstantsType>::operator[](int x)
{
const int block = blockfor(x);
- return _v[block][x].t();
+ return (_v[block].load())[x].t();
}
template <typename T, typename ConstantsType>
@@ -241,24 +241,24 @@ inline int QFreeList<T, ConstantsType>::next()
int id, newid, at;
ElementType *v;
do {
- id = _next; // .loadAqcuire();
+ id = _next.load();
at = id & ConstantsType::IndexMask;
const int block = blockfor(at);
- v = _v[block];
+ v = _v[block].loadAcquire();
if (!v) {
v = allocate((id & ConstantsType::IndexMask) - at, ConstantsType::Sizes[block]);
if (!_v[block].testAndSetRelease(0, v)) {
// race with another thread lost
delete [] v;
- v = _v[block];
+ v = _v[block].loadAcquire();
Q_ASSERT(v != 0);
}
}
newid = v[at].next | (id & ~ConstantsType::IndexMask);
- } while (!_next.testAndSetRelease(id, newid));
+ } while (!_next.testAndSetRelaxed(id, newid));
// qDebug("QFreeList::next(): returning %d (_next now %d, serial %d)",
// id & ConstantsType::IndexMask,
// newid & ConstantsType::IndexMask,
@@ -271,11 +271,11 @@ inline void QFreeList<T, ConstantsType>::release(int id)
{
int at = id & ConstantsType::IndexMask;
const int block = blockfor(at);
- ElementType *v = _v[block];
+ ElementType *v = _v[block].load();
int x, newid;
do {
- x = _next; // .loadAcquire();
+ x = _next.loadAcquire();
v[at].next = x & ConstantsType::IndexMask;
newid = incrementserial(x, id);