Use load() when constructing QSimpleCodec's reverse map
authorBradley T. Hughes <bradley.hughes@nokia.com>
Wed, 28 Sep 2011 10:14:01 +0000 (12:14 +0200)
committerQt by Nokia <qt-info@nokia.com>
Thu, 27 Oct 2011 09:12:38 +0000 (11:12 +0200)
The implicit casting results in unnecessary volatile loads. The
test-and-set-ordered doesn't need full ordering, test-and-set-release
is enough to ensure that the memory initialization done by
buildReverseMap() and test-and-set happen in program order.

Change-Id: I168b504271aeba050d6b8396becbdeb3ef938213
Reviewed-by: Olivier Goffart <ogoffart@kde.org>
src/corelib/codecs/qsimplecodec.cpp

index 728ebbb..d24b4d4 100644 (file)
@@ -622,7 +622,7 @@ QSimpleTextCodec::QSimpleTextCodec(int i) : forwardIndex(i), reverseMap(0)
 
 QSimpleTextCodec::~QSimpleTextCodec()
 {
-    delete reverseMap;
+    delete reverseMap.load();
 }
 
 static QByteArray *buildReverseMap(int forwardIndex)
@@ -674,10 +674,13 @@ QByteArray QSimpleTextCodec::convertFromUnicode(const QChar *in, int length, Con
     const char replacement = (state && state->flags & ConvertInvalidToNull) ? 0 : '?';
     int invalid = 0;
 
-    if (!reverseMap){
-        QByteArray *tmp = buildReverseMap(this->forwardIndex);
-        if (!reverseMap.testAndSetOrdered(0, tmp))
-            delete tmp;
+    QByteArray *rmap = reverseMap.load();
+    if (!rmap){
+        rmap = buildReverseMap(this->forwardIndex);
+        if (!reverseMap.testAndSetRelease(0, rmap)) {
+            delete rmap;
+            rmap = reverseMap.load();
+        }
     }
 
     QByteArray r(length, Qt::Uninitialized);
@@ -685,8 +688,8 @@ QByteArray QSimpleTextCodec::convertFromUnicode(const QChar *in, int length, Con
     int u;
     const QChar* ucp = in;
     unsigned char* rp = (unsigned char *)r.data();
-    const unsigned char* rmp = (const unsigned char *)reverseMap->constData();
-    int rmsize = (int) reverseMap->size();
+    const unsigned char* rmp = (const unsigned char *)rmap->constData();
+    int rmsize = (int) rmap->size();
     while(i--)
     {
         u = ucp->unicode();