From aeac586476a6e47c7a8a6aa2121bfe39a29d8458 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 8 May 2009 20:42:44 +0200 Subject: Reorganize the qatomic_armv6.h file to receive the RVCT inline assembly. Move the *Relaxed, *Acquire and *Release functions (which are simply forwarding calls to the *Ordered version) to the bottom of the file. Reviewed-By: Shane Kearns --- src/corelib/arch/qatomic_armv6.h | 171 ++++++++++++++++++++------------------- 1 file changed, 90 insertions(+), 81 deletions(-) diff --git a/src/corelib/arch/qatomic_armv6.h b/src/corelib/arch/qatomic_armv6.h index 6862638..6eb9a7b 100644 --- a/src/corelib/arch/qatomic_armv6.h +++ b/src/corelib/arch/qatomic_armv6.h @@ -101,6 +101,8 @@ template Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isFetchAndAddWaitFree() { return false; } +#ifdef !Q_CC_RVCT + inline bool QBasicAtomicInt::ref() { register int newValue; @@ -155,21 +157,6 @@ inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) return result == 0; } -inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) { register int originalValue; @@ -188,21 +175,6 @@ inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) return originalValue; } -inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue) -{ - return fetchAndStoreOrdered(newValue); -} - inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) { register int originalValue; @@ -224,21 +196,6 @@ inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) return originalValue; } -inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - template Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetOrdered(T *expectedValue, T *newValue) { @@ -259,24 +216,6 @@ Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetOrdered(T *expectedValu } template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetRelaxed(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetAcquire(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -template -Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetRelease(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -template Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreOrdered(T *newValue) { register T *originalValue; @@ -296,24 +235,6 @@ Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreOrdered(T *newValue) } template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreRelaxed(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreAcquire(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -template -Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreRelease(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -template Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddOrdered(qptrdiff valueToAdd) { register T *originalValue; @@ -335,6 +256,94 @@ Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddOrdered(qptrdiff valueTo return originalValue; } +#else +// This is Q_CC_RVCT + +#endif + +// common code + +inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) +{ + return testAndSetOrdered(expectedValue, newValue); +} + +inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue) +{ + return testAndSetOrdered(expectedValue, newValue); +} + +inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue) +{ + return testAndSetOrdered(expectedValue, newValue); +} + +inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue) +{ + return fetchAndStoreOrdered(newValue); +} + +inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue) +{ + return fetchAndStoreOrdered(newValue); +} + +inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue) +{ + return fetchAndStoreOrdered(newValue); +} + +inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd) +{ + return fetchAndAddOrdered(valueToAdd); +} + +inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd) +{ + return fetchAndAddOrdered(valueToAdd); +} + +inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd) +{ + return fetchAndAddOrdered(valueToAdd); +} + +template +Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetRelaxed(T *expectedValue, T *newValue) +{ + return testAndSetOrdered(expectedValue, newValue); +} + +template +Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetAcquire(T *expectedValue, T *newValue) +{ + return testAndSetOrdered(expectedValue, newValue); +} + +template +Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetRelease(T *expectedValue, T *newValue) +{ + return testAndSetOrdered(expectedValue, newValue); +} + +template +Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreRelaxed(T *newValue) +{ + return fetchAndStoreOrdered(newValue); +} + +template +Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreAcquire(T *newValue) +{ + return fetchAndStoreOrdered(newValue); +} + +template +Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreRelease(T *newValue) +{ + return fetchAndStoreOrdered(newValue); +} + template Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddRelaxed(qptrdiff valueToAdd) { -- cgit v0.12 From 43c607383697ab506f9eb0d491ec6348f939e53d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 8 May 2009 20:45:24 +0200 Subject: Add the ARMv6 inline assembly code for compiling with RVCT. This is basically a copy & paste of the GCC inline assembly above, switched to the RVCT inline assembly model (which is actually easier to write and understand). I verified that this code compiles and assembles as expected. The output generated by RVCT is pretty much on the mark. However, I have not executed this code yet to see if it performs as expected. To be noted: - when expanding the inline template code, RVCT may be tempted to switch your entire function to ARM mode. Should we add __attribute__((noinline)) to prevent that? - There's no equivalent to GCC inline assembler's clobber, especially of "memory". Also, there's no "volatile" qualifier to the assembly. Does the compiler know it can't reorder the code? Does it know it shouldn't trust the value of the memory after this? My test indicates the code is fine... Reviewed-By: Shane Kearns --- src/corelib/arch/qatomic_armv6.h | 132 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) diff --git a/src/corelib/arch/qatomic_armv6.h b/src/corelib/arch/qatomic_armv6.h index 6eb9a7b..28655df 100644 --- a/src/corelib/arch/qatomic_armv6.h +++ b/src/corelib/arch/qatomic_armv6.h @@ -259,6 +259,138 @@ Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddOrdered(qptrdiff valueTo #else // This is Q_CC_RVCT +// RVCT inline assembly documentation: +// http://www.keil.com/support/man/docs/armcc/armcc_chdcffdb.htm +// RVCT embedded assembly documentation: +// http://www.keil.com/support/man/docs/armcc/armcc_chddbeib.htm + +// save our pragma state and switch to ARM mode +#pragma push +#pragma arm + +inline bool QBasicAtomicInt::ref() +{ + register int newValue; + register int result; + retry: + __asm { + ldrex newValue, [&_q_value] + add newValue, newValue, #1 + strex result, newValue, [&_q_value] + teq result, #0 + bne retry + } + return newValue != 0; +} + +inline bool QBasicAtomicInt::deref() +{ + register int newValue; + register int result; + retry: + __asm { + ldrex newValue, [&_q_value] + sub newValue, newValue, #1 + strex result, newValue, [&_q_value] + teq result, #0 + bne retry + } + return newValue != 0; +} + +inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) +{ + register int result; + retry: + __asm { + ldrex result, [&_q_value] + eors result, result, expectedValue + strexeq result, newValue, [&_q_value] + teqeq result, #1 + beq retry + } + return result == 0; +} + +inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) +{ + register int originalValue; + register int result; + retry: + __asm { + ldrex originalValue, [&_q_value] + strex result, newValue, [&_q_value] + teq result, #0 + bne retry + } + return originalValue; +} + +inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) +{ + register int originalValue; + register int newValue; + register int result; + retry: + __asm { + ldrex originalValue, [&_q_value] + add newValue, originalValue, valueToAdd + strex result, newValue, [&_q_value] + teq result, #0 + bne retry + } + return originalValue; +} + +template +Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetOrdered(T *expectedValue, T *newValue) +{ + register T *result; + retry: + __asm { + ldrex result, [&_q_value] + eors result, result, expectedValue + strexeq result, newValue, [&_q_value] + teqeq result, #1 + beq retry + } + return result == 0; +} + +template +Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreOrdered(T *newValue) +{ + register T *originalValue; + register int result; + retry: + __asm { + ldrex originalValue, [&_q_value] + strex result, newValue, [&_q_value] + teq result, #0 + bne retry + } + return originalValue; +} + +template +Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddOrdered(qptrdiff valueToAdd) +{ + register T *originalValue; + register T *newValue; + register int result; + retry: + __asm { + ldrex originalValue, [&_q_value] + add newValue, originalValue, valueToAdd * sizeof(T) + strex result, newValue, [&_q_value] + teq result, #0 + bne retry + } + return originalValue; +} + +// go back to the previous pragma state (probably Thumb mode) +#pragma pop #endif // common code -- cgit v0.12 From a53bbbf81ce2dbce143ebc08fd91418e51a44588 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Wed, 4 Nov 2009 22:26:00 +0100 Subject: Binary compatibility of Symbian ARMv5 and ARMv6 builds Use ARMv6 atomics where available Use OS atomics otherwise Integrate ARMV6 atomics to Symbian builds Use compiler defined macros to detect if ARMv6 instructions are available This defines the QT_HAVE_ARMV6 macro, replacing the way it was defined by the Symbian build system previously in qpainting.pri. qatomic_symbian now uses qatomic_arm or qatomic_armv6 automatically Port armv6 atomics to implement generic atomics interface The inline atomics are not inlined when we build for thumb using RVCT. So there is no performance improvement of using the "inline" versions vs a shared version called through a function call. The generic atomics interface is good for binary compatibility, as the same symbols are exported in all versions now. Changed the fallback generic atomics implementation from the unix one to a symbian specific one using RFastLock (identical code to the windows generic atomics, except for RFastLock replaces Win32 CRITICAL_SECTION) Note: GCCE atomics still need porting Tell git to ignore .lst listing files (produced by sbs/abld listing) ARMv6 support for GCCE compiler and fallback implementation using OS When building corelib with GCCE and -march=armv6, QT_HAVE_ARMV6 will be defined. This patch adds copies of the asm functions in GCC syntax. When building for the Symbian emulator, or ARMv5, then Symbian OS atomic functions are used as a fallback - these are more efficient than the unix atomics, and don't require data import (which the ARMv5 atomics use, but the OS loader doesn't support fully) Symbian OS functions are always used for QBasicAtomicInt::ref / deref, because these are faster than the generic function in all cases. They are machine coded for ARMv6, and are used internally by RFastLock. Reviewed-By: axis Reviewed-By: Brad --- .gitignore | 1 + src/corelib/arch/armv6/qatomic_generic_armv6.cpp | 260 +++++++++++++++++++++++ src/corelib/arch/qatomic_armv6.h | 3 +- src/corelib/arch/qatomic_symbian.h | 240 ++++++++++++++++++++- src/corelib/arch/symbian/arch.pri | 2 +- src/corelib/arch/symbian/qatomic_symbian.cpp | 104 +++++++-- src/corelib/global/qglobal.h | 7 +- src/gui/painting/painting.pri | 1 - src/s60installs/eabi/QtCoreu.def | 8 +- 9 files changed, 587 insertions(+), 39 deletions(-) create mode 100644 src/corelib/arch/armv6/qatomic_generic_armv6.cpp diff --git a/.gitignore b/.gitignore index feb1ea4..33c9b7c 100644 --- a/.gitignore +++ b/.gitignore @@ -191,6 +191,7 @@ plugin_commonU.def *.qtplugin *.sis *.sisx +*.lst # Generated by abldfast.bat from devtools. .abldsteps.* diff --git a/src/corelib/arch/armv6/qatomic_generic_armv6.cpp b/src/corelib/arch/armv6/qatomic_generic_armv6.cpp new file mode 100644 index 0000000..3078662 --- /dev/null +++ b/src/corelib/arch/armv6/qatomic_generic_armv6.cpp @@ -0,0 +1,260 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +** This file implements the generic atomics interface using ARMv6 assembly +** instructions. It is more efficent than the inline versions when Qt is +** built for the THUMB instruction set, as the required instructions are +** only available in ARM state. +****************************************************************************/ + +#include + +#ifdef QT_HAVE_ARMV6 + +QT_BEGIN_NAMESPACE + +QT_USE_NAMESPACE + +#ifdef Q_CC_RVCT +#pragma push +#pragma arm +Q_CORE_EXPORT asm +bool QBasicAtomicInt_testAndSetOrdered(volatile int *_q_value, int expectedValue, int newValue) +{ + CODE32 + //R0 = _q_value + //R1 = expectedValue + //R2 = newValue +retry_testAndSetOrdered + LDREX r3,[r0] //r3 = *_q_value + EORS r3,r3,r1 //if (r3 == expectedValue) { + STREXEQ r3,r2,[r0] //*_q_value = newvalue, r3 = error + TEQEQ r3,#1 //if error + BEQ retry_testAndSetOrdered //then goto retry } + RSBS r0,r3,#1 //return (r3 == 0) + MOVCC r0,#0 + BX r14 +} + +Q_CORE_EXPORT asm +int QBasicAtomicInt_fetchAndStoreOrdered(volatile int *_q_value, int newValue) +{ + CODE32 +//R0 = _q_value +//R1 = newValue +retry_fetchAndStoreOrdered + LDREX r3,[r0] //r3 = *_q_value + STREX r2,r1,[r0] //*_q_value = newValue, r2 = error + TEQ r2,#0 //if error + BNE retry_fetchAndStoreOrdered //then goto retry + MOV r0,r3 //return r3 + BX r14 +} + +Q_CORE_EXPORT asm +int QBasicAtomicInt_fetchAndAddOrdered(volatile int *_q_value, int valueToAdd) +{ + CODE32 + //R0 = _q_value + //R1 = valueToAdd + STMDB sp!,{r12,lr} +retry_fetchAndAddOrdered + LDREX r2,[r0] //r2 = *_q_value + ADD r3,r2,r1 //r3 = r2 + r1 + STREX r12,r3,[r0] //*_q_value = r3, r12 = error + TEQ r12,#0 //if error + BNE retry_fetchAndAddOrdered //then retry + MOV r0,r2 //return r2 + LDMIA sp!,{r12,pc} +} + +Q_CORE_EXPORT asm +bool QBasicAtomicPointer_testAndSetOrdered(void * volatile *_q_value, + void *expectedValue, + void *newValue) +{ + CODE32 + //R0 = _q_value + //R1 = expectedValue + //R2 = newValue +retryPointer_testAndSetOrdered + LDREX r3,[r0] //r3 = *_q_value + EORS r3,r3,r1 //if (r3 == expectedValue) { + STREXEQ r3,r2,[r0] //*_q_value = newvalue, r3 = error + TEQEQ r3,#1 //if error + BEQ retryPointer_testAndSetOrdered //then goto retry } + RSBS r0,r3,#1 //return (r3 == 0) + MOVCC r0,#0 + BX r14 +} + +Q_CORE_EXPORT asm +void *QBasicAtomicPointer_fetchAndStoreOrdered(void * volatile *_q_value, void *newValue) +{ + CODE32 + //R0 = _q_value + //R1 = newValue +retryPointer_fetchAndStoreOrdered + LDREX r3,[r0] //r3 = *_q_value + STREX r2,r1,[r0] //*_q_value = newValue, r2 = error + TEQ r2,#0 //if error + BNE retryPointer_fetchAndStoreOrdered //then goto retry + MOV r0,r3 //return r3 + BX r14 +} + +Q_CORE_EXPORT asm +void *QBasicAtomicPointer_fetchAndAddOrdered(void * volatile *_q_value, qptrdiff valueToAdd) +{ + CODE32 + //R0 = _q_value + //R1 = valueToAdd + STMDB sp!,{r12,lr} +retryPointer_fetchAndAddOrdered + LDREX r2,[r0] //r2 = *_q_value + ADD r3,r2,r1 //r3 = r2 + r1 + STREX r12,r3,[r0] //*_q_value = r3, r12 = error + TEQ r12,#0 //if error + BNE retryPointer_fetchAndAddOrdered //then retry + MOV r0,r2 //return r2 + LDMIA sp!,{r12,pc} +} + +#pragma pop +#elif defined (Q_CC_GCCE) +Q_CORE_EXPORT __declspec( naked ) +bool QBasicAtomicInt_testAndSetOrdered(volatile int *_q_value, int expectedValue, int newValue) +{ + //R0 = _q_value + //R1 = expectedValue + //R2 = newValue + asm("retry_testAndSetOrdered:"); + asm(" LDREX r3,[r0]"); //r3 = *_q_value + asm(" EORS r3,r3,r1"); //if (r3 == expectedValue) { + asm(" STREXEQ r3,r2,[r0]"); //*_q_value = newvalue, r3 = error + asm(" TEQEQ r3,#1"); //if error + asm(" BEQ retry_testAndSetOrdered"); //then goto retry } + asm(" RSBS r0,r3,#1"); //return (r3 == 0) + asm(" MOVCC r0,#0"); + asm(" BX r14"); +} + +Q_CORE_EXPORT __declspec( naked ) +int QBasicAtomicInt_fetchAndStoreOrdered(volatile int *_q_value, int newValue) +{ +//R0 = _q_value +//R1 = newValue + asm("retry_fetchAndStoreOrdered:"); + asm(" LDREX r3,[r0]"); //r3 = *_q_value + asm(" STREX r2,r1,[r0]"); //*_q_value = newValue, r2 = error + asm(" TEQ r2,#0"); //if error + asm(" BNE retry_fetchAndStoreOrdered"); //then goto retry + asm(" MOV r0,r3"); //return r3 + asm(" BX r14"); +} + +Q_CORE_EXPORT __declspec( naked ) +int QBasicAtomicInt_fetchAndAddOrdered(volatile int *_q_value, int valueToAdd) +{ + //R0 = _q_value + //R1 = valueToAdd + asm(" STMDB sp!,{r12,lr}"); + asm("retry_fetchAndAddOrdered:"); + asm(" LDREX r2,[r0]"); //r2 = *_q_value + asm(" ADD r3,r2,r1 "); //r3 = r2 + r1 + asm(" STREX r12,r3,[r0]"); //*_q_value = r3, r12 = error + asm(" TEQ r12,#0"); //if error + asm(" BNE retry_fetchAndAddOrdered"); //then retry + asm(" MOV r0,r2"); //return r2 + asm(" LDMIA sp!,{r12,pc}"); +} + +Q_CORE_EXPORT __declspec( naked ) +bool QBasicAtomicPointer_testAndSetOrdered(void * volatile *_q_value, + void *expectedValue, + void *newValue) +{ + //R0 = _q_value + //R1 = expectedValue + //R2 = newValue + asm("retryPointer_testAndSetOrdered:"); + asm(" LDREX r3,[r0]"); //r3 = *_q_value + asm(" EORS r3,r3,r1"); //if (r3 == expectedValue) { + asm(" STREXEQ r3,r2,[r0]"); //*_q_value = newvalue, r3 = error + asm(" TEQEQ r3,#1"); //if error + asm(" BEQ retryPointer_testAndSetOrdered"); //then goto retry } + asm(" RSBS r0,r3,#1"); //return (r3 == 0) + asm(" MOVCC r0,#0"); + asm(" BX r14"); +} + +Q_CORE_EXPORT __declspec( naked ) +void *QBasicAtomicPointer_fetchAndStoreOrdered(void * volatile *_q_value, void *newValue) +{ + //R0 = _q_value + //R1 = newValue + asm("retryPointer_fetchAndStoreOrdered:"); + asm(" LDREX r3,[r0]"); //r3 = *_q_value + asm(" STREX r2,r1,[r0]"); //*_q_value = newValue, r2 = error + asm(" TEQ r2,#0"); //if error + asm(" BNE retryPointer_fetchAndStoreOrdered"); //then goto retry + asm(" MOV r0,r3"); //return r3 + asm(" BX r14"); +} + +Q_CORE_EXPORT __declspec( naked ) +void *QBasicAtomicPointer_fetchAndAddOrdered(void * volatile *_q_value, qptrdiff valueToAdd) +{ + //R0 = _q_value + //R1 = valueToAdd + asm(" STMDB sp!,{r12,lr}"); + asm("retryPointer_fetchAndAddOrdered:"); + asm(" LDREX r2,[r0]"); //r2 = *_q_value + asm(" ADD r3,r2,r1"); //r3 = r2 + r1 + asm(" STREX r12,r3,[r0]"); //*_q_value = r3, r12 = error + asm(" TEQ r12,#0"); //if error + asm(" BNE retryPointer_fetchAndAddOrdered"); //then retry + asm(" MOV r0,r2"); //return r2 + asm(" LDMIA sp!,{r12,pc}"); +} +#else +#error unknown arm compiler +#endif +QT_END_NAMESPACE +#endif diff --git a/src/corelib/arch/qatomic_armv6.h b/src/corelib/arch/qatomic_armv6.h index 28655df..1e9f0c4 100644 --- a/src/corelib/arch/qatomic_armv6.h +++ b/src/corelib/arch/qatomic_armv6.h @@ -45,7 +45,6 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE - #define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE inline bool QBasicAtomicInt::isReferenceCountingNative() @@ -101,7 +100,7 @@ template Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isFetchAndAddWaitFree() { return false; } -#ifdef !Q_CC_RVCT +#ifndef Q_CC_RVCT inline bool QBasicAtomicInt::ref() { diff --git a/src/corelib/arch/qatomic_symbian.h b/src/corelib/arch/qatomic_symbian.h index 3721aca..571f628 100644 --- a/src/corelib/arch/qatomic_symbian.h +++ b/src/corelib/arch/qatomic_symbian.h @@ -42,12 +42,8 @@ #ifndef QATOMIC_SYMBIAN_H #define QATOMIC_SYMBIAN_H -#if defined(Q_CC_RVCT) -# define QT_NO_ARM_EABI -# include -#elif defined(Q_CC_NOKIAX86) || defined(Q_CC_GCCE) -# include -#endif +#include +#include QT_BEGIN_HEADER @@ -55,7 +51,237 @@ QT_BEGIN_NAMESPACE QT_MODULE(Core) -// Empty, but needed to avoid warnings +#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE + +inline bool QBasicAtomicInt::isReferenceCountingNative() +{ return false; } +inline bool QBasicAtomicInt::isReferenceCountingWaitFree() +{ return false; } + +#define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE + +inline bool QBasicAtomicInt::isTestAndSetNative() +{ return false; } +inline bool QBasicAtomicInt::isTestAndSetWaitFree() +{ return false; } + +#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_NOT_NATIVE + +inline bool QBasicAtomicInt::isFetchAndStoreNative() +{ return false; } +inline bool QBasicAtomicInt::isFetchAndStoreWaitFree() +{ return false; } + +#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE + +inline bool QBasicAtomicInt::isFetchAndAddNative() +{ return false; } +inline bool QBasicAtomicInt::isFetchAndAddWaitFree() +{ return false; } + +#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE + +template +Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isTestAndSetNative() +{ return false; } +template +Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isTestAndSetWaitFree() +{ return false; } + +#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE + +template +Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isFetchAndStoreNative() +{ return false; } +template +Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isFetchAndStoreWaitFree() +{ return false; } + +#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE + +template +Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isFetchAndAddNative() +{ return false; } +template +Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isFetchAndAddWaitFree() +{ return false; } + +Q_CORE_EXPORT bool QBasicAtomicInt_testAndSetOrdered(volatile int *, int, int); +Q_CORE_EXPORT int QBasicAtomicInt_fetchAndStoreOrdered(volatile int *, int); +Q_CORE_EXPORT int QBasicAtomicInt_fetchAndAddOrdered(volatile int *, int); + +Q_CORE_EXPORT bool QBasicAtomicPointer_testAndSetOrdered(void * volatile *, void *, void *); +Q_CORE_EXPORT void *QBasicAtomicPointer_fetchAndStoreOrdered(void * volatile *, void *); +Q_CORE_EXPORT void *QBasicAtomicPointer_fetchAndAddOrdered(void * volatile *, qptrdiff); + +// Reference counting + +//LockedInc and LockedDec are machine coded for ARMv6 (and future proof) +inline bool QBasicAtomicInt::ref() +{ + int original = User::LockedInc((TInt&)_q_value); + return original != -1; +} + +inline bool QBasicAtomicInt::deref() +{ + int original = User::LockedDec((TInt&)_q_value); + return original != 1; +} + +// Test and set for integers + +inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) +{ + return QBasicAtomicInt_testAndSetOrdered(&_q_value, expectedValue, newValue); +} + +inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) +{ + return testAndSetOrdered(expectedValue, newValue); +} + +inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue) +{ + return testAndSetOrdered(expectedValue, newValue); +} + +inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue) +{ + return testAndSetOrdered(expectedValue, newValue); +} + +// Fetch and store for integers + +inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) +{ + return QBasicAtomicInt_fetchAndStoreOrdered(&_q_value, newValue); +} + +inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue) +{ + return fetchAndStoreOrdered(newValue); +} + +inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue) +{ + return fetchAndStoreOrdered(newValue); +} + +inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue) +{ + return fetchAndStoreOrdered(newValue); +} + +// Fetch and add for integers + +inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) +{ + return QBasicAtomicInt_fetchAndAddOrdered(&_q_value, valueToAdd); +} + +inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd) +{ + return fetchAndAddOrdered(valueToAdd); +} + +inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd) +{ + return fetchAndAddOrdered(valueToAdd); +} + +inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd) +{ + return fetchAndAddOrdered(valueToAdd); +} + +// Test and set for pointers + +template +Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetOrdered(T *expectedValue, T *newValue) +{ + union { T * volatile * typed; void * volatile * voidp; } pointer; + pointer.typed = &_q_value; + return QBasicAtomicPointer_testAndSetOrdered(pointer.voidp, expectedValue, newValue); +} + +template +Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetRelaxed(T *expectedValue, T *newValue) +{ + return testAndSetOrdered(expectedValue, newValue); +} + +template +Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetAcquire(T *expectedValue, T *newValue) +{ + return testAndSetOrdered(expectedValue, newValue); +} + +template +Q_INLINE_TEMPLATE bool QBasicAtomicPointer::testAndSetRelease(T *expectedValue, T *newValue) +{ + return testAndSetOrdered(expectedValue, newValue); +} + +// Fetch and store for pointers + +template +Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreOrdered(T *newValue) +{ + union { T * volatile * typed; void * volatile * voidp; } pointer; + union { T *typed; void *voidp; } returnValue; + pointer.typed = &_q_value; + returnValue.voidp = QBasicAtomicPointer_fetchAndStoreOrdered(pointer.voidp, newValue); + return returnValue.typed; +} + +template +Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreRelaxed(T *newValue) +{ + return fetchAndStoreOrdered(newValue); +} + +template +Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreAcquire(T *newValue) +{ + return fetchAndStoreOrdered(newValue); +} + +template +Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndStoreRelease(T *newValue) +{ + return fetchAndStoreOrdered(newValue); +} + +// Fetch and add for pointers + +template +Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddOrdered(qptrdiff valueToAdd) +{ + union { T * volatile *typed; void * volatile *voidp; } pointer; + union { T *typed; void *voidp; } returnValue; + pointer.typed = &_q_value; + returnValue.voidp = QBasicAtomicPointer_fetchAndAddOrdered(pointer.voidp, valueToAdd * sizeof(T)); + return returnValue.typed; +} + +template +Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddRelaxed(qptrdiff valueToAdd) +{ + return fetchAndAddOrdered(valueToAdd); +} + +template +Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddAcquire(qptrdiff valueToAdd) +{ + return fetchAndAddOrdered(valueToAdd); +} + +template +Q_INLINE_TEMPLATE T *QBasicAtomicPointer::fetchAndAddRelease(qptrdiff valueToAdd) +{ + return fetchAndAddOrdered(valueToAdd); +} QT_END_NAMESPACE diff --git a/src/corelib/arch/symbian/arch.pri b/src/corelib/arch/symbian/arch.pri index deb94b1..3ef1c9e 100644 --- a/src/corelib/arch/symbian/arch.pri +++ b/src/corelib/arch/symbian/arch.pri @@ -2,4 +2,4 @@ # Symbian architecture # SOURCES += $$QT_ARCH_CPP/qatomic_symbian.cpp \ - $$QT_ARCH_CPP/../generic/qatomic_generic_unix.cpp + $$QT_ARCH_CPP/../armv6/qatomic_generic_armv6.cpp diff --git a/src/corelib/arch/symbian/qatomic_symbian.cpp b/src/corelib/arch/symbian/qatomic_symbian.cpp index 8f02155..2ab5ae9 100644 --- a/src/corelib/arch/symbian/qatomic_symbian.cpp +++ b/src/corelib/arch/symbian/qatomic_symbian.cpp @@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE // This way we can report on heap cells and handles that are really not owned by anything which still exists. // This information can be used to detect whether memory leaks are happening, particularly if these numbers grow as the app is used more. // This code is placed here as it happens to make it the very last static to be destroyed in a Qt app. The -// reason assumed is that this file appears before any other file declaring static data in the generated +// reason assumed is that this file appears before any other file declaring static data in the generated // Symbian MMP file. This particular file was chosen as it is the earliest symbian specific file. struct QSymbianPrintExitInfo { @@ -77,37 +77,95 @@ struct QSymbianPrintExitInfo TInt initThreadHandleCount; } symbian_printExitInfo; -QT_END_NAMESPACE +//For ARMv6, the generic atomics are machine coded +#ifndef QT_HAVE_ARMV6 +class QCriticalSection +{ +public: + QCriticalSection() { fastlock.CreateLocal(); } + ~QCriticalSection() { fastlock.Close(); } + void lock() { fastlock.Wait(); } + void unlock() { fastlock.Signal(); } -#if defined(Q_CC_RVCT) +private: + RFastLock fastlock; +}; -#include "../arm/qatomic_arm.cpp" +QCriticalSection qAtomicCriticalSection; -QT_BEGIN_NAMESPACE +Q_CORE_EXPORT +bool QBasicAtomicInt_testAndSetOrdered(volatile int *_q_value, int expectedValue, int newValue) +{ + bool returnValue = false; + qAtomicCriticalSection.lock(); + if (*_q_value == expectedValue) { + *_q_value = newValue; + returnValue = true; + } + qAtomicCriticalSection.unlock(); + return returnValue; +} -Q_CORE_EXPORT __asm char q_atomic_swp(volatile char *ptr, char newval) +Q_CORE_EXPORT +int QBasicAtomicInt_fetchAndStoreOrdered(volatile int *_q_value, int newValue) { - add r2, pc, #0 - bx r2 - arm - swpb r2,r1,[r0] - mov r0, r2 - bx lr - thumb + int returnValue; + qAtomicCriticalSection.lock(); + returnValue = *_q_value; + *_q_value = newValue; + qAtomicCriticalSection.unlock(); + return returnValue; } -Q_CORE_EXPORT __asm int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) +Q_CORE_EXPORT +int QBasicAtomicInt_fetchAndAddOrdered(volatile int *_q_value, int valueToAdd) { - add r2, pc, #0 - bx r2 - arm - swp r2,r1,[r0] - mov r0, r2 - bx lr - thumb + int returnValue; + qAtomicCriticalSection.lock(); + returnValue = *_q_value; + *_q_value += valueToAdd; + qAtomicCriticalSection.unlock(); + return returnValue; } -QT_END_NAMESPACE +Q_CORE_EXPORT +bool QBasicAtomicPointer_testAndSetOrdered(void * volatile *_q_value, + void *expectedValue, + void *newValue) +{ + bool returnValue = false; + qAtomicCriticalSection.lock(); + if (*_q_value == expectedValue) { + *_q_value = newValue; + returnValue = true; + } + qAtomicCriticalSection.unlock(); + return returnValue; +} -#endif // Q_CC_RVCT +Q_CORE_EXPORT +void *QBasicAtomicPointer_fetchAndStoreOrdered(void * volatile *_q_value, void *newValue) +{ + void *returnValue; + qAtomicCriticalSection.lock(); + returnValue = *_q_value; + *_q_value = newValue; + qAtomicCriticalSection.unlock(); + return returnValue; +} + +Q_CORE_EXPORT +void *QBasicAtomicPointer_fetchAndAddOrdered(void * volatile *_q_value, qptrdiff valueToAdd) +{ + void *returnValue; + qAtomicCriticalSection.lock(); + returnValue = *_q_value; + *_q_value = reinterpret_cast(returnValue) + valueToAdd; + qAtomicCriticalSection.unlock(); + return returnValue; +} + +#endif // QT_HAVE_ARMV6 + +QT_END_NAMESPACE diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index d113e02..9558256 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -437,13 +437,18 @@ namespace QT_NAMESPACE {} #elif defined(__GCCE__) # define Q_CC_GCCE # define QT_VISIBILITY_AVAILABLE +# if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) +# define QT_HAVE_ARMV6 +# endif /* ARM Realview Compiler Suite RVCT compiler also defines __EDG__ and __GNUC__ (if --gnu flag is given), so check for it before that */ #elif defined(__ARMCC__) || defined(__CC_ARM) # define Q_CC_RVCT - +# if __TARGET_ARCH_ARM >= 6 +# define QT_HAVE_ARMV6 +# endif #elif defined(__GNUC__) # define Q_CC_GNU # define Q_C_CALLBACKS diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index c35c33a..628a109 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -370,7 +370,6 @@ symbian { SOURCES += painting/qwindowsurface_s60.cpp armccIfdefBlock = \ "$${LITERAL_HASH}if defined(ARMV6)" \ - "MACRO QT_HAVE_ARMV6" \ "SOURCEPATH painting" \ "SOURCE qblendfunctions_armv6_rvct.s" \ "SOURCE qdrawhelper_armv6_rvct.s" \ diff --git a/src/s60installs/eabi/QtCoreu.def b/src/s60installs/eabi/QtCoreu.def index faf8b1e..17693ea 100644 --- a/src/s60installs/eabi/QtCoreu.def +++ b/src/s60installs/eabi/QtCoreu.def @@ -13,7 +13,7 @@ EXPORTS _Z11qt_int_sqrtj @ 12 NONAME _Z12noforcepointR11QTextStream @ 13 NONAME _Z12qSharedBuildv @ 14 NONAME - _Z12q_atomic_swpPVcc @ 15 NONAME + _Z12q_atomic_swpPVcc @ 15 NONAME ABSENT _Z12qt_s60GetRFsv @ 16 NONAME _Z13lowercasebaseR11QTextStream @ 17 NONAME _Z13qErrnoWarningPKcz @ 18 NONAME @@ -24,7 +24,7 @@ EXPORTS _Z15lowercasedigitsR11QTextStream @ 23 NONAME _Z15qAddPostRoutinePFvvE @ 24 NONAME _Z15qInitResourceIOv @ 25 NONAME - _Z15qt_atomic_yieldPi @ 26 NONAME + _Z15qt_atomic_yieldPi @ 26 NONAME ABSENT _Z15qt_error_stringi @ 27 NONAME _Z15uppercasedigitsR11QTextStream @ 28 NONAME _Z16qt_QString2HBufCRK7QString @ 29 NONAME @@ -706,7 +706,7 @@ EXPORTS _ZN15QAnimationGroupD0Ev @ 705 NONAME _ZN15QAnimationGroupD1Ev @ 706 NONAME _ZN15QAnimationGroupD2Ev @ 707 NONAME - _ZN15QBasicAtomicInt20fetchAndStoreOrderedEi @ 708 NONAME + _ZN15QBasicAtomicInt20fetchAndStoreOrderedEi @ 708 NONAME ABSENT _ZN15QDateTimeParser11parseFormatERK7QString @ 709 NONAME _ZN15QLinkedListData11shared_nullE @ 710 NONAME DATA 20 _ZN15QObjectUserDataD0Ev @ 711 NONAME @@ -3566,7 +3566,7 @@ EXPORTS inflateSync @ 3565 NONAME inflateSyncPoint @ 3566 NONAME qMetaTypeGuiHelper @ 3567 NONAME DATA 4 - q_atomic_lock @ 3568 NONAME DATA 1 + q_atomic_lock @ 3568 NONAME DATA 1 ABSENT qt_addObject @ 3569 NONAME qt_global_mutexpool @ 3570 NONAME DATA 4 qt_locale_initialized @ 3571 NONAME DATA 1 -- cgit v0.12 From 99c42254480fb147b0aaa01458300bae4472e3d8 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Fri, 6 Nov 2009 13:44:04 +0100 Subject: Fix functions that return whether atomics are natives following review comments Reviewed-By: Brad --- src/corelib/arch/qatomic_symbian.h | 31 ++++++-------- src/corelib/arch/symbian/qatomic_symbian.cpp | 63 ++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 18 deletions(-) diff --git a/src/corelib/arch/qatomic_symbian.h b/src/corelib/arch/qatomic_symbian.h index 571f628..92f6ef9 100644 --- a/src/corelib/arch/qatomic_symbian.h +++ b/src/corelib/arch/qatomic_symbian.h @@ -51,57 +51,52 @@ QT_BEGIN_NAMESPACE QT_MODULE(Core) -#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE +#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE -inline bool QBasicAtomicInt::isReferenceCountingNative() -{ return false; } inline bool QBasicAtomicInt::isReferenceCountingWaitFree() { return false; } -#define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE +#define Q_ATOMIC_INT_TEST_AND_SET_IS_SOMETIMES_NATIVE -inline bool QBasicAtomicInt::isTestAndSetNative() -{ return false; } inline bool QBasicAtomicInt::isTestAndSetWaitFree() { return false; } -#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_NOT_NATIVE +#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_SOMETIMES_NATIVE -inline bool QBasicAtomicInt::isFetchAndStoreNative() -{ return false; } inline bool QBasicAtomicInt::isFetchAndStoreWaitFree() { return false; } -#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE +#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_SOMETIMES_NATIVE -inline bool QBasicAtomicInt::isFetchAndAddNative() -{ return false; } inline bool QBasicAtomicInt::isFetchAndAddWaitFree() { return false; } -#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE +#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_SOMETIMES_NATIVE +Q_CORE_EXPORT bool QBasicAtomicPointer_isTestAndSetNative(); template Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isTestAndSetNative() -{ return false; } +{ return QBasicAtomicPointer_isTestAndSetNative(); } template Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isTestAndSetWaitFree() { return false; } -#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE +#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_SOMETIMES_NATIVE +Q_CORE_EXPORT bool QBasicAtomicPointer_isFetchAndStoreNative(); template Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isFetchAndStoreNative() -{ return false; } +{ return QBasicAtomicPointer_isFetchAndStoreNative(); } template Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isFetchAndStoreWaitFree() { return false; } -#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE +#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_SOMETIMES_NATIVE +Q_CORE_EXPORT bool QBasicAtomicPointer_isFetchAndAddNative(); template Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isFetchAndAddNative() -{ return false; } +{ return QBasicAtomicPointer_isFetchAndAddNative(); } template Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isFetchAndAddWaitFree() { return false; } diff --git a/src/corelib/arch/symbian/qatomic_symbian.cpp b/src/corelib/arch/symbian/qatomic_symbian.cpp index 2ab5ae9..91b49c7 100644 --- a/src/corelib/arch/symbian/qatomic_symbian.cpp +++ b/src/corelib/arch/symbian/qatomic_symbian.cpp @@ -77,6 +77,69 @@ struct QSymbianPrintExitInfo TInt initThreadHandleCount; } symbian_printExitInfo; +Q_CORE_EXPORT bool QBasicAtomicInt::isReferenceCountingNative() +{ +#ifdef QT_HAVE_ARMV6 + return true; +#else + return false; +#endif +} + +Q_CORE_EXPORT bool QBasicAtomicInt::isTestAndSetNative() +{ +#ifdef QT_HAVE_ARMV6 + return true; +#else + return false; +#endif +} + +Q_CORE_EXPORT bool QBasicAtomicInt::isFetchAndStoreNative() +{ +#ifdef QT_HAVE_ARMV6 + return true; +#else + return false; +#endif +} + +Q_CORE_EXPORT bool QBasicAtomicInt::isFetchAndAddNative() +{ +#ifdef QT_HAVE_ARMV6 + return true; +#else + return false; +#endif +} + +Q_CORE_EXPORT bool QBasicAtomicPointer_isTestAndSetNative() +{ +#ifdef QT_HAVE_ARMV6 + return true; +#else + return false; +#endif +} + +Q_CORE_EXPORT bool QBasicAtomicPointer_isFetchAndStoreNative() +{ +#ifdef QT_HAVE_ARMV6 + return true; +#else + return false; +#endif +} + +Q_CORE_EXPORT bool QBasicAtomicPointer_isFetchAndAddNative() +{ +#ifdef QT_HAVE_ARMV6 + return true; +#else + return false; +#endif +} + //For ARMv6, the generic atomics are machine coded #ifndef QT_HAVE_ARMV6 -- cgit v0.12 From 0a07ca79318ba1b735ce0b3a208e471e4a24e1f2 Mon Sep 17 00:00:00 2001 From: Shane Kearns Date: Thu, 12 Nov 2009 19:21:25 +0100 Subject: Fix corelib def files for the new atomics implementation 4.6.0 has the wrong atomics implementation for symbian, as the team branch was not merged before the freeze. This updates the def files to match the implementation on the team branch so that it can be cherry-picked. Task-number: QTBUG-5752 Reviewed-by: Iain --- src/s60installs/bwins/QtCoreu.def | 3 +++ src/s60installs/eabi/QtCoreu.def | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/src/s60installs/bwins/QtCoreu.def b/src/s60installs/bwins/QtCoreu.def index 146d47e..1218b75 100644 --- a/src/s60installs/bwins/QtCoreu.def +++ b/src/s60installs/bwins/QtCoreu.def @@ -4384,4 +4384,7 @@ EXPORTS ?staticMetaObject@QAbstractTableModel@@2UQMetaObject@@B @ 4383 NONAME ; struct QMetaObject const QAbstractTableModel::staticMetaObject ?staticMetaObject@QFile@@2UQMetaObject@@B @ 4384 NONAME ; struct QMetaObject const QFile::staticMetaObject ?staticMetaObject@QHistoryState@@2UQMetaObject@@B @ 4385 NONAME ; struct QMetaObject const QHistoryState::staticMetaObject + ?QBasicAtomicPointer_isFetchAndAddNative@@YA_NXZ @ 4386 NONAME ; bool QBasicAtomicPointer_isFetchAndAddNative(void) + ?QBasicAtomicPointer_isFetchAndStoreNative@@YA_NXZ @ 4387 NONAME ; bool QBasicAtomicPointer_isFetchAndStoreNative(void) + ?QBasicAtomicPointer_isTestAndSetNative@@YA_NXZ @ 4388 NONAME ; bool QBasicAtomicPointer_isTestAndSetNative(void) diff --git a/src/s60installs/eabi/QtCoreu.def b/src/s60installs/eabi/QtCoreu.def index 17693ea..99be68e 100644 --- a/src/s60installs/eabi/QtCoreu.def +++ b/src/s60installs/eabi/QtCoreu.def @@ -3612,4 +3612,11 @@ EXPORTS _ZNK13QStateMachine10isAnimatedEv @ 3611 NONAME _ZNK18QAbstractAnimation15currentLoopTimeEv @ 3612 NONAME _ZNK7QRegExp12captureCountEv @ 3613 NONAME + _Z38QBasicAtomicPointer_isTestAndSetNativev @ 3614 NONAME + _Z39QBasicAtomicPointer_isFetchAndAddNativev @ 3615 NONAME + _Z41QBasicAtomicPointer_isFetchAndStoreNativev @ 3616 NONAME + _ZN15QBasicAtomicInt18isTestAndSetNativeEv @ 3617 NONAME + _ZN15QBasicAtomicInt19isFetchAndAddNativeEv @ 3618 NONAME + _ZN15QBasicAtomicInt21isFetchAndStoreNativeEv @ 3619 NONAME + _ZN15QBasicAtomicInt25isReferenceCountingNativeEv @ 3620 NONAME -- cgit v0.12 From d0edd9b3d6ee5dba8e9a23d0fb9aaab74924d2ad Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Wed, 11 Nov 2009 12:25:56 +0100 Subject: Add mkspec for Maemo 5 & 6 Reviewed-By: Robert Griebl Reviewed-By: Thiago Macieira --- mkspecs/linux-g++-maemo/qmake.conf | 28 ++++++++++++++++++++++ mkspecs/linux-g++-maemo/qplatformdefs.h | 42 +++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 mkspecs/linux-g++-maemo/qmake.conf create mode 100644 mkspecs/linux-g++-maemo/qplatformdefs.h diff --git a/mkspecs/linux-g++-maemo/qmake.conf b/mkspecs/linux-g++-maemo/qmake.conf new file mode 100644 index 0000000..067d857 --- /dev/null +++ b/mkspecs/linux-g++-maemo/qmake.conf @@ -0,0 +1,28 @@ +# +# qmake configuration for Maemo 5 & 6 +# + +MAKEFILE_GENERATOR = UNIX +TEMPLATE = app +CONFIG += qt warn_on release incremental link_prl +QT += core gui +QMAKE_INCREMENTAL_STYLE = sublib + +include(../common/g++.conf) +include(../common/linux.conf) + +# Work round scratchbox not having standard paths in it's default search path +QMAKE_LFLAGS += -Wl,-rpath-link=/lib +QMAKE_LFLAGS += -Wl,-rpath-link=/usr/lib + +# Override the default lib/include directories for scratchbox: +QMAKE_INCDIR_X11 = /usr/include/X11 +QMAKE_INCDIR_OPENGL = /usr/include +QMAKE_LIBDIR_X11 = /usr/lib +QMAKE_LIBDIR_OPENGL = /usr/lib + +# Work round PowerVR SGX 1.3 driver bug with glScissor & FBOs: +DEFINES += QT_GL_NO_SCISSOR_TEST + + +load(qt_config) diff --git a/mkspecs/linux-g++-maemo/qplatformdefs.h b/mkspecs/linux-g++-maemo/qplatformdefs.h new file mode 100644 index 0000000..857eaf3 --- /dev/null +++ b/mkspecs/linux-g++-maemo/qplatformdefs.h @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../linux-g++/qplatformdefs.h" -- cgit v0.12 From c95acfda6aae0dcf4285bb759a271598bb2dccea Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Wed, 11 Nov 2009 12:32:04 +0100 Subject: Generate debug symbols in release mode on Maemo Reviewed-By: Stefano Pironato --- mkspecs/linux-g++-maemo/qmake.conf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mkspecs/linux-g++-maemo/qmake.conf b/mkspecs/linux-g++-maemo/qmake.conf index 067d857..2195329 100644 --- a/mkspecs/linux-g++-maemo/qmake.conf +++ b/mkspecs/linux-g++-maemo/qmake.conf @@ -21,6 +21,10 @@ QMAKE_INCDIR_OPENGL = /usr/include QMAKE_LIBDIR_X11 = /usr/lib QMAKE_LIBDIR_OPENGL = /usr/lib +# We still need to generate debug symbols in release mode to put into the *-dbg packages: +QMAKE_CFLAGS_RELEASE += -g +QMAKE_CXXFLAGS_RELEASE += -g + # Work round PowerVR SGX 1.3 driver bug with glScissor & FBOs: DEFINES += QT_GL_NO_SCISSOR_TEST -- cgit v0.12 From c9211c691b370332b9165a9d80f03220789c1d53 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Wed, 11 Nov 2009 13:43:55 +0100 Subject: Disable optimisations which break stack traces on Maemo The -O2 mode enables omit-frame-pointer & optimize-sibling-calls, which can break stack traces. So, even in release mode, disable these optimisations so that we can at least still get a backtrace when a Qt application dies. Reviewed-By: Stefano Pironato --- mkspecs/linux-g++-maemo/qmake.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mkspecs/linux-g++-maemo/qmake.conf b/mkspecs/linux-g++-maemo/qmake.conf index 2195329..c39ba2c 100644 --- a/mkspecs/linux-g++-maemo/qmake.conf +++ b/mkspecs/linux-g++-maemo/qmake.conf @@ -22,8 +22,8 @@ QMAKE_LIBDIR_X11 = /usr/lib QMAKE_LIBDIR_OPENGL = /usr/lib # We still need to generate debug symbols in release mode to put into the *-dbg packages: -QMAKE_CFLAGS_RELEASE += -g -QMAKE_CXXFLAGS_RELEASE += -g +QMAKE_CFLAGS_RELEASE += -g -fno-omit-frame-pointer -fno-optimize-sibling-calls +QMAKE_CXXFLAGS_RELEASE += -g -fno-omit-frame-pointer -fno-optimize-sibling-calls # Work round PowerVR SGX 1.3 driver bug with glScissor & FBOs: DEFINES += QT_GL_NO_SCISSOR_TEST -- cgit v0.12