diff options
author | Bradley T. Hughes <bradley.hughes@nokia.com> | 2011-09-29 11:45:01 +0200 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-10-05 16:31:37 +0200 |
commit | a4a94544f27a66ea1189a3a5927ed2dafc28f88c (patch) | |
tree | d83848aa6191436ad13608101773de9709f66218 | |
parent | 0e339e2ef5138f93480a5cc60add1c8a26858907 (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.h | 18 |
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); |