From de35b37c68991d87095ad087a635cd9d4e5fe185 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Fri, 10 Feb 2012 14:27:34 +0100 Subject: Add src/corelib/arch/qatomic_unix.h and qatomic_unix.cpp This provides a fallback implementation on UNIX when the Q_PROCESSOR_* and Q_CC_*/Q_COMPILER_* checks fail to find an implementation. Note that we always compile qatomic_unix.cpp, but code is only included when QATOMIC_UNIX_H is defined (meaning the checks above did not find an implementation). Change-Id: I8ce047847206003b4fa96eb3fb76b1c2ffbc2dfc Reviewed-by: Thiago Macieira --- src/corelib/arch/arch.pri | 6 ++ src/corelib/arch/qatomic_unix.cpp | 82 ++++++++++++++++++++++++++ src/corelib/arch/qatomic_unix.h | 117 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 205 insertions(+) create mode 100644 src/corelib/arch/qatomic_unix.cpp create mode 100644 src/corelib/arch/qatomic_unix.h (limited to 'src/corelib/arch') diff --git a/src/corelib/arch/arch.pri b/src/corelib/arch/arch.pri index 2a4fddb913..14e90b8736 100644 --- a/src/corelib/arch/arch.pri +++ b/src/corelib/arch/arch.pri @@ -25,6 +25,12 @@ integrity:HEADERS += arch/qatomic_integrity.h arch/qatomic_gcc.h \ arch/qatomic_cxx11.h +unix { + # fallback implementation when no other appropriate qatomic_*.h exists + HEADERS += arch/qatomic_unix.h + SOURCES += arch/qatomic_unix.cpp +} + QT_ARCH_CPP = $$QT_SOURCE_TREE/src/corelib/arch/$$QT_ARCH exists($$QT_ARCH_CPP) { DEPENDPATH += $$QT_ARCH_CPP diff --git a/src/corelib/arch/qatomic_unix.cpp b/src/corelib/arch/qatomic_unix.cpp new file mode 100644 index 0000000000..a709be3fa1 --- /dev/null +++ b/src/corelib/arch/qatomic_unix.cpp @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qplatformdefs.h" + +#include + +// If operating system, processor, and compiler detection fails, we fall back +// to this generic, out-of-line implementation + +#if defined(QATOMIC_UNIX_H) + +QT_BEGIN_NAMESPACE +static pthread_mutex_t qAtomicMutex = PTHREAD_MUTEX_INITIALIZER; + +Q_CORE_EXPORT +bool QAtomicOps::testAndSetRelaxed(int &_q_value, int expectedValue, int newValue) +{ + bool returnValue = false; + pthread_mutex_lock(&qAtomicMutex); + if (_q_value == expectedValue) { + _q_value = newValue; + returnValue = true; + } + pthread_mutex_unlock(&qAtomicMutex); + return returnValue; +} + +Q_CORE_EXPORT +bool QAtomicOps::testAndSetRelaxed(void *&_q_value, void *expectedValue, void *newValue) +{ + bool returnValue = false; + pthread_mutex_lock(&qAtomicMutex); + if (_q_value == expectedValue) { + _q_value = newValue; + returnValue = true; + } + pthread_mutex_unlock(&qAtomicMutex); + return returnValue; +} + +QT_END_NAMESPACE + +#endif // QATOMIC_UNIX_H diff --git a/src/corelib/arch/qatomic_unix.h b/src/corelib/arch/qatomic_unix.h new file mode 100644 index 0000000000..3dc168c0ae --- /dev/null +++ b/src/corelib/arch/qatomic_unix.h @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QATOMIC_UNIX_H +#define QATOMIC_UNIX_H + +#include + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +#if 0 +// silence syncqt warnings +QT_END_NAMESPACE +QT_END_HEADER + +#pragma qt_sync_stop_processing +#endif + +#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE +#define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE +#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_NOT_NATIVE +#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE + +#define Q_ATOMIC_INT32_IS_SUPPORTED + +#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE +#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NOT_NATIVE +#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE + +template<> struct QAtomicIntegerTraits { enum { IsInteger = 1 }; }; + +// No definition, needs specialization +template struct QAtomicOps; + +template <> +struct QAtomicOps : QGenericAtomicOps > +{ + typedef int Type; + + static inline bool isTestAndSetNative() { return false; } + static inline bool isTestAndSetWaitFree() { return false; } + Q_CORE_EXPORT static bool testAndSetRelaxed(int &_q_value, int expectedValue, int newValue); +}; + +template <> +struct QAtomicOps : QGenericAtomicOps > +{ + typedef void *Type; + + static inline bool isTestAndSetNative() { return false; } + static inline bool isTestAndSetWaitFree() { return false; } + Q_CORE_EXPORT static bool testAndSetRelaxed(void *&_q_value, void *expectedValue, void *newValue); +}; + +template +struct QAtomicOps : QGenericAtomicOps > +{ + typedef T *Type; + + // helper to strip cv qualifiers + static inline void *nocv(const T *p) { return const_cast(static_cast(p)); } + + static inline bool isTestAndSetNative() { return false; } + static inline bool isTestAndSetWaitFree() { return false; } + static inline bool testAndSetRelaxed(T *&_q_value, T *expectedValue, T *newValue) + { + // forward to the void* specialization + void *voidp = nocv(_q_value); + bool returnValue = QAtomicOps::testAndSetRelaxed(voidp, nocv(expectedValue), nocv(newValue)); + _q_value = reinterpret_cast(voidp); + return returnValue; + } +}; + +QT_END_NAMESPACE +QT_END_HEADER + +#endif // QATOMIC_UNIX_H -- cgit v1.2.3