From a4a94544f27a66ea1189a3a5927ed2dafc28f88c Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Thu, 29 Sep 2011 11:45:01 +0200 Subject: Don't use implicit QAtomic* casts in QFreeList MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pair the _next.testAndSetRelease() call in QFreeList::release() with _next.loadAcquire(), to ensure that the update to the bucket being released is properly fenced. QFreeList: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 Reviewed-by: João Abecasis --- src/corelib/tools/qfreelist_p.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src/corelib') 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 inline QFreeList::~QFreeList() { for (int i = 0; i < ConstantsType::BlockCount; ++i) - delete [] static_cast(_v[i]); + delete [] _v[i].load(); } template inline typename QFreeList::ConstReferenceType QFreeList::at(int x) const { const int block = blockfor(x); - return _v[block][x].t(); + return (_v[block].load())[x].t(); } template inline typename QFreeList::ReferenceType QFreeList::operator[](int x) { const int block = blockfor(x); - return _v[block][x].t(); + return (_v[block].load())[x].t(); } template @@ -241,24 +241,24 @@ inline int QFreeList::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::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); -- cgit v1.2.3