/**************************************************************************** ** ** Copyright (C) 2010 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$ ** ****************************************************************************/ #include #include #include QT_BEGIN_NAMESPACE // Heap and handle info printer. // 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 // Symbian MMP file. This particular file was chosen as it is the earliest symbian specific file. struct QSymbianPrintExitInfo { QSymbianPrintExitInfo() { RThread().HandleCount(initProcessHandleCount, initThreadHandleCount); initCells = User::CountAllocCells(); } ~QSymbianPrintExitInfo() { RProcess myProc; TFullName fullName = myProc.FileName(); TInt cells = User::CountAllocCells(); TInt processHandleCount=0; TInt threadHandleCount=0; RThread().HandleCount(processHandleCount, threadHandleCount); RDebug::Print(_L("%S exiting with %d allocated cells, %d handles"), &fullName, cells - initCells, (processHandleCount + threadHandleCount) - (initProcessHandleCount + initThreadHandleCount)); } TInt initCells; TInt initProcessHandleCount; 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 class QCriticalSection { public: QCriticalSection() { fastlock.CreateLocal(); } ~QCriticalSection() { fastlock.Close(); } void lock() { fastlock.Wait(); } void unlock() { fastlock.Signal(); } private: RFastLock fastlock; }; QCriticalSection qAtomicCriticalSection; 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 int QBasicAtomicInt_fetchAndStoreOrdered(volatile int *_q_value, int newValue) { int returnValue; qAtomicCriticalSection.lock(); returnValue = *_q_value; *_q_value = newValue; qAtomicCriticalSection.unlock(); return returnValue; } Q_CORE_EXPORT int QBasicAtomicInt_fetchAndAddOrdered(volatile int *_q_value, int valueToAdd) { int returnValue; qAtomicCriticalSection.lock(); returnValue = *_q_value; *_q_value += valueToAdd; qAtomicCriticalSection.unlock(); return returnValue; } 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; } 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