diff options
Diffstat (limited to 'src/corelib/arch')
59 files changed, 2180 insertions, 3877 deletions
diff --git a/src/corelib/arch/alpha/qatomic_alpha.s b/src/corelib/arch/alpha/qatomic_alpha.s index 7dd09d4480..3bccd12849 100644 --- a/src/corelib/arch/alpha/qatomic_alpha.s +++ b/src/corelib/arch/alpha/qatomic_alpha.s @@ -1,8 +1,7 @@ ;/**************************************************************************** ;** ;** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -;** All rights reserved. -;** Contact: Nokia Corporation (qt-info@nokia.com) +;** Contact: http://www.qt-project.org/ ;** ;** This file is part of the QtGui module of the Qt Toolkit. ;** @@ -35,6 +34,7 @@ ;** ;** ;** +;** ;** $QT_END_LICENSE$ ;** ;****************************************************************************/ diff --git a/src/corelib/arch/arch.pri b/src/corelib/arch/arch.pri index 6185b92757..62b07a4a99 100644 --- a/src/corelib/arch/arch.pri +++ b/src/corelib/arch/arch.pri @@ -1,18 +1,18 @@ -win32:HEADERS += arch/qatomic_windows.h \ +win32:HEADERS += arch/qatomic_msvc.h \ arch/qatomic_generic.h win32-g++*:HEADERS += arch/qatomic_i386.h \ arch/qatomic_x86_64.h -mac:HEADERS += arch/qatomic_macosx.h \ +mac:HEADERS += arch/qatomic_i386.h \ + arch/qatomic_x86_64.h \ arch/qatomic_generic.h vxworks:HEADERS += arch/qatomic_vxworks.h integrity:HEADERS += arch/qatomic_integrity.h -!wince*:!win32:!mac:!symbian:HEADERS += arch/qatomic_alpha.h \ - arch/qatomic_avr32.h \ +!wince*:!win32:!mac:HEADERS += arch/qatomic_alpha.h \ arch/qatomic_ia64.h \ arch/qatomic_parisc.h \ arch/qatomic_sparc.h \ @@ -28,10 +28,12 @@ integrity:HEADERS += arch/qatomic_integrity.h arch/qatomic_s390.h \ arch/qatomic_x86_64.h \ arch/qatomic_sh.h \ - arch/qatomic_sh4a.h + arch/qatomic_sh4a.h \ + arch/qatomic_gcc.h \ + arch/qatomic_cxx11.h QT_ARCH_CPP = $$QT_SOURCE_TREE/src/corelib/arch/$$QT_ARCH -DEPENDPATH += $$QT_ARCH_CPP -!isEmpty(QT_ARCH) { - include($$QT_ARCH_CPP/arch.pri, "", true) +exists($$QT_ARCH_CPP) { + DEPENDPATH += $$QT_ARCH_CPP + include($$QT_ARCH_CPP/arch.pri, "", true) } diff --git a/src/corelib/arch/arm/arch.pri b/src/corelib/arch/arm/arch.pri deleted file mode 100644 index 79e4bfc115..0000000000 --- a/src/corelib/arch/arm/arch.pri +++ /dev/null @@ -1,4 +0,0 @@ -# -# ARM architecture -# -SOURCES += $$QT_ARCH_CPP/qatomic_arm.cpp diff --git a/src/corelib/arch/arm/qatomic_arm.cpp b/src/corelib/arch/arm/qatomic_arm.cpp deleted file mode 100644 index 0eaeb5a15b..0000000000 --- a/src/corelib/arch/arm/qatomic_arm.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 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$ -** 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 <QtCore/qglobal.h> - -#include <unistd.h> -#ifdef _POSIX_PRIORITY_SCHEDULING -# include <sched.h> -#endif -#include <time.h> - -QT_BEGIN_NAMESPACE - -QT_USE_NAMESPACE - -Q_CORE_EXPORT char q_atomic_lock = 0; - -Q_CORE_EXPORT void qt_atomic_yield(int *count) -{ -#ifdef _POSIX_PRIORITY_SCHEDULING - if((*count)++ < 50) { - sched_yield(); - } else -#endif - { - struct timespec tm; - tm.tv_sec = 0; - tm.tv_nsec = 2000001; - nanosleep(&tm, NULL); - *count = 0; - } -} - -QT_END_NAMESPACE diff --git a/src/corelib/arch/avr32/arch.pri b/src/corelib/arch/avr32/arch.pri deleted file mode 100644 index 37f231ee61..0000000000 --- a/src/corelib/arch/avr32/arch.pri +++ /dev/null @@ -1,3 +0,0 @@ -# -# AVR32 architecture -# diff --git a/src/corelib/arch/bfin/arch.pri b/src/corelib/arch/bfin/arch.pri deleted file mode 100644 index fa198ae8bb..0000000000 --- a/src/corelib/arch/bfin/arch.pri +++ /dev/null @@ -1,3 +0,0 @@ -# -# Blackfin architecture -# diff --git a/src/corelib/arch/generic/qatomic_generic_unix.cpp b/src/corelib/arch/generic/qatomic_generic_unix.cpp index 78292e7e49..eb1498fceb 100644 --- a/src/corelib/arch/generic/qatomic_generic_unix.cpp +++ b/src/corelib/arch/generic/qatomic_generic_unix.cpp @@ -1,8 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) +** Contact: http://www.qt-project.org/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** @@ -35,12 +34,11 @@ ** ** ** +** ** $QT_END_LICENSE$ ** ****************************************************************************/ -#if !defined(Q_OS_SYMBIAN) || (defined(Q_OS_SYMBIAN) && !defined(Q_CC_RVCT)) - #include "qplatformdefs.h" #include <QtCore/qatomic.h> @@ -120,4 +118,3 @@ void *QBasicAtomicPointer_fetchAndAddOrdered(void * volatile *_q_value, qptrdiff return returnValue; } QT_END_NAMESPACE -#endif //!defined(Q_OS_SYMBIAN) && !defined(Q_CC_RVCT) diff --git a/src/corelib/arch/generic/qatomic_generic_windows.cpp b/src/corelib/arch/generic/qatomic_generic_windows.cpp index 94129cb106..dafc8133b2 100644 --- a/src/corelib/arch/generic/qatomic_generic_windows.cpp +++ b/src/corelib/arch/generic/qatomic_generic_windows.cpp @@ -1,8 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) +** Contact: http://www.qt-project.org/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** @@ -35,6 +34,7 @@ ** ** ** +** ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/corelib/arch/i386/arch.pri b/src/corelib/arch/i386/arch.pri deleted file mode 100644 index 3101dae01b..0000000000 --- a/src/corelib/arch/i386/arch.pri +++ /dev/null @@ -1,4 +0,0 @@ -# -# i386 architecture -# -!*-g++*:!*-icc*:SOURCES += $$QT_ARCH_CPP/qatomic_i386.s diff --git a/src/corelib/arch/i386/qatomic_i386.s b/src/corelib/arch/i386/qatomic_i386.s deleted file mode 100644 index 08158f926b..0000000000 --- a/src/corelib/arch/i386/qatomic_i386.s +++ /dev/null @@ -1,103 +0,0 @@ - .text - - .align 4,0x90 - .globl q_atomic_test_and_set_int -q_atomic_test_and_set_int: - movl 4(%esp),%ecx - movl 8(%esp),%eax - movl 12(%esp),%edx - lock - cmpxchgl %edx,(%ecx) - mov $0,%eax - sete %al - ret - .align 4,0x90 - .type q_atomic_test_and_set_int,@function - .size q_atomic_test_and_set_int,.-q_atomic_test_and_set_int - - .align 4,0x90 - .globl q_atomic_test_and_set_ptr -q_atomic_test_and_set_ptr: - movl 4(%esp),%ecx - movl 8(%esp),%eax - movl 12(%esp),%edx - lock - cmpxchgl %edx,(%ecx) - mov $0,%eax - sete %al - ret - .align 4,0x90 - .type q_atomic_test_and_set_ptr,@function - .size q_atomic_test_and_set_ptr,.-q_atomic_test_and_set_ptr - - .align 4,0x90 - .globl q_atomic_increment -q_atomic_increment: - movl 4(%esp), %ecx - lock - incl (%ecx) - mov $0,%eax - setne %al - ret - .align 4,0x90 - .type q_atomic_increment,@function - .size q_atomic_increment,.-q_atomic_increment - - .align 4,0x90 - .globl q_atomic_decrement -q_atomic_decrement: - movl 4(%esp), %ecx - lock - decl (%ecx) - mov $0,%eax - setne %al - ret - .align 4,0x90 - .type q_atomic_decrement,@function - .size q_atomic_decrement,.-q_atomic_decrement - - .align 4,0x90 - .globl q_atomic_set_int -q_atomic_set_int: - mov 4(%esp),%ecx - mov 8(%esp),%eax - xchgl %eax,(%ecx) - ret - .align 4,0x90 - .type q_atomic_set_int,@function - .size q_atomic_set_int,.-q_atomic_set_int - - .align 4,0x90 - .globl q_atomic_set_ptr -q_atomic_set_ptr: - mov 4(%esp),%ecx - mov 8(%esp),%eax - xchgl %eax,(%ecx) - ret - .align 4,0x90 - .type q_atomic_set_ptr,@function - .size q_atomic_set_ptr,.-q_atomic_set_ptr - - .align 4,0x90 - .globl q_atomic_fetch_and_add_int -q_atomic_fetch_and_add_int: - mov 4(%esp),%ecx - mov 8(%esp),%eax - lock - xadd %eax,(%ecx) - ret - .align 4,0x90 - .type q_atomic_fetch_and_add_int,@function - .size q_atomic_fetch_and_add_int,.-q_atomic_fetch_and_add_int - - .align 4,0x90 - .globl q_atomic_fetch_and_add_ptr -q_atomic_fetch_and_add_ptr: - mov 4(%esp),%ecx - mov 8(%esp),%eax - lock - xadd %eax,(%ecx) - ret - .align 4,0x90 - .type q_atomic_fetch_and_add_ptr,@function - .size q_atomic_fetch_and_add_ptr,.-q_atomic_fetch_and_add_ptr diff --git a/src/corelib/arch/ia64/arch.pri b/src/corelib/arch/ia64/arch.pri deleted file mode 100644 index 63afa967a4..0000000000 --- a/src/corelib/arch/ia64/arch.pri +++ /dev/null @@ -1,4 +0,0 @@ -# -# Intel Itanium architecture -# -!*-g++:!*-icc:!hpuxi-acc-*:SOURCES += $$QT_ARCH_CPP/qatomic_ia64.s diff --git a/src/corelib/arch/ia64/qatomic_ia64.s b/src/corelib/arch/ia64/qatomic_ia64.s deleted file mode 100644 index f6b100c170..0000000000 --- a/src/corelib/arch/ia64/qatomic_ia64.s +++ /dev/null @@ -1,74 +0,0 @@ -;/**************************************************************************** -;** -;** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -;** All rights reserved. -;** Contact: Nokia Corporation (qt-info@nokia.com) -;** -;** This file is part of the QtGui 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$ -;** -;****************************************************************************/ - .pred.safe_across_calls p1-p5,p16-p63 -.text - .align 16 - .global q_atomic_test_and_set_int# - .proc q_atomic_test_and_set_int# -q_atomic_test_and_set_int: - .prologue - .body - mov ar.ccv=r33 - ;; - cmpxchg4.acq r34=[r32],r34,ar.ccv - ;; - cmp4.eq p6, p7 = r33, r34 - ;; - (p6) addl r8 = 1, r0 - (p7) mov r8 = r0 - br.ret.sptk.many b0 - .endp q_atomic_test_and_set_int# - .align 16 - .global q_atomic_test_and_set_ptr# - .proc q_atomic_test_and_set_ptr# -q_atomic_test_and_set_ptr: - .prologue - .body - mov ar.ccv=r33 - ;; - cmpxchg8.acq r34=[r32],r34,ar.ccv - ;; - cmp.eq p6, p7 = r33, r34 - ;; - (p6) addl r8 = 1, r0 - (p7) mov r8 = r0 - br.ret.sptk.many b0 - .endp q_atomic_test_and_set_ptr# diff --git a/src/corelib/arch/integrity/arch.pri b/src/corelib/arch/integrity/arch.pri deleted file mode 100644 index 2c4196ec32..0000000000 --- a/src/corelib/arch/integrity/arch.pri +++ /dev/null @@ -1,3 +0,0 @@ -# -# INTEGRITY RTOS architecture -# diff --git a/src/corelib/arch/macosx/arch.pri b/src/corelib/arch/macosx/arch.pri deleted file mode 100644 index a2b1bf759a..0000000000 --- a/src/corelib/arch/macosx/arch.pri +++ /dev/null @@ -1,6 +0,0 @@ -# -# Mac OS X architecture -# - -# Left blank intentionally since all the current compilers that we support can -# handle in-line assembly. diff --git a/src/corelib/arch/macosx/qatomic32_ppc.s b/src/corelib/arch/macosx/qatomic32_ppc.s deleted file mode 100644 index 97d68cba70..0000000000 --- a/src/corelib/arch/macosx/qatomic32_ppc.s +++ /dev/null @@ -1,169 +0,0 @@ -;/**************************************************************************** -;** -;** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -;** All rights reserved. -;** Contact: Nokia Corporation (qt-info@nokia.com) -;** -;** This file is part of the QtGui 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$ -;** -;****************************************************************************/ - .section __TEXT,__text,regular,pure_instructions - .section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32 - .section __TEXT,__text,regular,pure_instructions - .align 2 - .align 2 - .globl _q_atomic_test_and_set_int - .section __TEXT,__text,regular,pure_instructions - .align 2 -_q_atomic_test_and_set_int: - lwarx r6,0,r3 - cmpw r6,r4 - bne- $+20 - stwcx. r5,0,r3 - bne- $-16 - addi r3,0,1 - blr - addi r3,0,0 - blr - - .align 2 - .globl _q_atomic_test_and_set_acquire_int - .section __TEXT,__text,regular,pure_instructions - .align 2 -_q_atomic_test_and_set_acquire_int: - lwarx r6,0,r3 - cmpw r6,r4 - bne- $+20 - stwcx. r5,0,r3 - bne- $-16 - addi r3,0,1 - b $+8 - addi r3,0,0 - eieio - blr - - .align 2 - .globl _q_atomic_test_and_set_release_int - .section __TEXT,__text,regular,pure_instructions - .align 2 -_q_atomic_test_and_set_release_int: - eieio - lwarx r6,0,r3 - cmpw r6,r4 - bne- $+20 - stwcx. r5,0,r3 - bne- $-16 - addi r3,0,1 - blr - addi r3,0,0 - blr - - .align 2 - .globl _q_atomic_test_and_set_ptr - .section __TEXT,__text,regular,pure_instructions - .align 2 -_q_atomic_test_and_set_ptr: - lwarx r6,0,r3 - cmpw r6,r4 - bne- $+20 - stwcx. r5,0,r3 - bne- $-16 - addi r3,0,1 - blr - addi r3,0,0 - blr - - .align 2 - .globl _q_atomic_increment - .section __TEXT,__text,regular,pure_instructions - .align 2 -_q_atomic_increment: - lwarx r4,0,r3 - addi r4,r4,1 - stwcx. r4,0,r3 - bne- $-12 - mr r3,r4 - blr - - .align 2 - .globl _q_atomic_decrement - .section __TEXT,__text,regular,pure_instructions - .align 2 -_q_atomic_decrement: - lwarx r4,0,r3 - subi r4,r4,1 - stwcx. r4,0,r3 - bne- $-12 - mr r3,r4 - blr - - .align 2 - .globl _q_atomic_set_int - .section __TEXT,__text,regular,pure_instructions - .align 2 -_q_atomic_set_int: - lwarx r5,0,r3 - stwcx. r4,0,r3 - bne- $-8 - mr r3,r5 - blr - - .align 2 - .globl _q_atomic_set_ptr - .section __TEXT,__text,regular,pure_instructions - .align 2 -_q_atomic_set_ptr: - lwarx r5,0,r3 - stwcx. r4,0,r3 - bne- $-8 - mr r3,r5 - blr - -.globl q_atomic_test_and_set_int.eh - q_atomic_test_and_set_int.eh = 0 -.globl q_atomic_test_and_set_ptr.eh - q_atomic_test_and_set_ptr.eh = 0 -.globl q_atomic_increment.eh - q_atomic_increment.eh = 0 -.globl q_atomic_decrement.eh - q_atomic_decrement.eh = 0 -.globl q_atomic_set_int.eh - q_atomic_set_int.eh = 0 -.globl q_atomic_set_ptr.eh - q_atomic_set_ptr.eh = 0 -.data -.constructor -.data -.destructor -.align 1 diff --git a/src/corelib/arch/mips/arch.pri b/src/corelib/arch/mips/arch.pri deleted file mode 100644 index 296c845ab3..0000000000 --- a/src/corelib/arch/mips/arch.pri +++ /dev/null @@ -1,8 +0,0 @@ -# -# MIPS 3/4 architecture -# - -# note: even though we use inline assembler with gcc, we always -# include the compiled version to keep binary compatibility -*-64:SOURCES += $$QT_ARCH_CPP/qatomic_mips64.s -else:SOURCES += $$QT_ARCH_CPP/qatomic_mips32.s diff --git a/src/corelib/arch/mips/qatomic_mips32.s b/src/corelib/arch/mips/qatomic_mips32.s deleted file mode 100644 index b4013dfff5..0000000000 --- a/src/corelib/arch/mips/qatomic_mips32.s +++ /dev/null @@ -1,150 +0,0 @@ -;/**************************************************************************** -;** -;** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -;** All rights reserved. -;** Contact: Nokia Corporation (qt-info@nokia.com) -;** -;** This file is part of the QtGui 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$ -;** -;****************************************************************************/ - .set nobopt - .set noreorder - .option pic2 - .text - - .globl q_atomic_test_and_set_int - .ent q_atomic_test_and_set_int - .set mips2 -q_atomic_test_and_set_int: -1: ll $8,0($4) - bne $8,$5,2f - move $2,$6 - sc $2,0($4) - beqz $2,1b - nop - jr $31 - nop -2: jr $31 - move $2,$0 - .set mips0 - .end q_atomic_test_and_set_int - - .globl q_atomic_test_and_set_acquire_int - .ent q_atomic_test_and_set_acquire_int - .set mips2 -q_atomic_test_and_set_acquire_int: -1: ll $8,0($4) - bne $8,$5,2f - move $2,$6 - sc $2,0($4) - beqz $2,1b - nop - jr $31 - nop -2: sync - jr $31 - move $2,$0 - .set mips0 - .end q_atomic_test_and_set_acquire_int - - .globl q_atomic_test_and_set_release_int - .ent q_atomic_test_and_set_release_int - .set mips2 -q_atomic_test_and_set_release_int: - sync -1: ll $8,0($4) - bne $8,$5,2f - move $2,$6 - sc $2,0($4) - beqz $2,1b - nop - jr $31 - nop -2: jr $31 - move $2,$0 - .set mips0 - .end q_atomic_test_and_set_release_int - - .globl q_atomic_test_and_set_ptr - .ent q_atomic_test_and_set_ptr - .set mips2 -q_atomic_test_and_set_ptr: -1: ll $8,0($4) - bne $8,$5,2f - move $2,$6 - sc $2,0($4) - beqz $2,1b - nop - jr $31 - nop -2: jr $31 - move $2,$0 - .set mips0 - .end q_atomic_test_and_set_ptr - - .globl q_atomic_test_and_set_acquire_ptr - .ent q_atomic_test_and_set_acquire_ptr - .set mips2 -q_atomic_test_and_set_acquire_ptr: -1: ll $8,0($4) - bne $8,$5,2f - move $2,$6 - sc $2,0($4) - beqz $2,1b - nop - jr $31 - nop -2: sync - jr $31 - move $2,$0 - .set mips0 - .end q_atomic_test_and_set_acquire_ptr - - .globl q_atomic_test_and_set_release_ptr - .ent q_atomic_test_and_set_release_ptr - .set mips2 -q_atomic_test_and_set_release_ptr: - sync -1: ll $8,0($4) - bne $8,$5,2f - move $2,$6 - sc $2,0($4) - beqz $2,1b - nop - jr $31 - nop -2: jr $31 - move $2,$0 - .set mips0 - .end q_atomic_test_and_set_release_ptr diff --git a/src/corelib/arch/mips/qatomic_mips64.s b/src/corelib/arch/mips/qatomic_mips64.s deleted file mode 100644 index a66b785e30..0000000000 --- a/src/corelib/arch/mips/qatomic_mips64.s +++ /dev/null @@ -1,138 +0,0 @@ -;/**************************************************************************** -;** -;** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -;** All rights reserved. -;** Contact: Nokia Corporation (qt-info@nokia.com) -;** -;** This file is part of the QtGui 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$ -;** -;****************************************************************************/ - .set nobopt - .set noreorder - .option pic2 - .text - - .globl q_atomic_test_and_set_int - .ent q_atomic_test_and_set_int -q_atomic_test_and_set_int: -1: ll $8,0($4) - bne $8,$5,2f - move $2,$6 - sc $2,0($4) - beqz $2,1b - nop - jr $31 - nop -2: jr $31 - move $2,$0 - .end q_atomic_test_and_set_int - - .globl q_atomic_test_and_set_acquire_int - .ent q_atomic_test_and_set_acquire_int -q_atomic_test_and_set_acquire_int: -1: ll $8,0($4) - bne $8,$5,2f - move $2,$6 - sc $2,0($4) - beqz $2,1b - nop - jr $31 - nop -2: sync - jr $31 - move $2,$0 - .end q_atomic_test_and_set_acquire_int - - .globl q_atomic_test_and_set_release_int - .ent q_atomic_test_and_set_release_int -q_atomic_test_and_set_release_int: - sync -1: ll $8,0($4) - bne $8,$5,2f - move $2,$6 - sc $2,0($4) - beqz $2,1b - nop - jr $31 - nop -2: jr $31 - move $2,$0 - .end q_atomic_test_and_set_release_int - - .globl q_atomic_test_and_set_ptr - .ent q_atomic_test_and_set_ptr -q_atomic_test_and_set_ptr: -1: lld $8,0($4) - bne $8,$5,2f - move $2,$6 - scd $2,0($4) - beqz $2,1b - nop - jr $31 - nop -2: jr $31 - move $2,$0 - .end q_atomic_test_and_set_ptr - - .globl q_atomic_test_and_set_acquire_ptr - .ent q_atomic_test_and_set_acquire_ptr -q_atomic_test_and_set_acquire_ptr: -1: lld $8,0($4) - bne $8,$5,2f - move $2,$6 - scd $2,0($4) - beqz $2,1b - nop - jr $31 - nop -2: sync - jr $31 - move $2,$0 - .end q_atomic_test_and_set_acquire_ptr - - .globl q_atomic_test_and_set_release_ptr - .ent q_atomic_test_and_set_release_ptr -q_atomic_test_and_set_release_ptr: - sync -1: lld $8,0($4) - bne $8,$5,2f - move $2,$6 - scd $2,0($4) - beqz $2,1b - nop - jr $31 - nop -2: jr $31 - move $2,$0 - .end q_atomic_test_and_set_release_ptr diff --git a/src/corelib/arch/parisc/q_ldcw.s b/src/corelib/arch/parisc/q_ldcw.s index 0c1db6f394..8af2861c50 100644 --- a/src/corelib/arch/parisc/q_ldcw.s +++ b/src/corelib/arch/parisc/q_ldcw.s @@ -1,8 +1,7 @@ ;/**************************************************************************** ;** ;** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -;** All rights reserved. -;** Contact: Nokia Corporation (qt-info@nokia.com) +;** Contact: http://www.qt-project.org/ ;** ;** This file is part of the QtGui module of the Qt Toolkit. ;** @@ -35,6 +34,7 @@ ;** ;** ;** +;** ;** $QT_END_LICENSE$ ;** ;****************************************************************************/ diff --git a/src/corelib/arch/parisc/qatomic_parisc.cpp b/src/corelib/arch/parisc/qatomic_parisc.cpp index da8d480a4f..5e59669b22 100644 --- a/src/corelib/arch/parisc/qatomic_parisc.cpp +++ b/src/corelib/arch/parisc/qatomic_parisc.cpp @@ -1,8 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) +** Contact: http://www.qt-project.org/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** @@ -35,6 +34,7 @@ ** ** ** +** ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/corelib/arch/powerpc/qatomic32.s b/src/corelib/arch/powerpc/qatomic32.s index dfc0605cff..8e2dbe2e2f 100644 --- a/src/corelib/arch/powerpc/qatomic32.s +++ b/src/corelib/arch/powerpc/qatomic32.s @@ -1,8 +1,7 @@ ############################################################################ ## ## Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -## All rights reserved. -## Contact: Nokia Corporation (qt-info@nokia.com) +## Contact: http://www.qt-project.org/ ## ## This file is part of the QtGui module of the Qt Toolkit. ## @@ -35,6 +34,7 @@ ## ## ## +## ## $QT_END_LICENSE$ ## ############################################################################ diff --git a/src/corelib/arch/powerpc/qatomic64.s b/src/corelib/arch/powerpc/qatomic64.s index 9e81eb0bc0..84977d5a93 100644 --- a/src/corelib/arch/powerpc/qatomic64.s +++ b/src/corelib/arch/powerpc/qatomic64.s @@ -1,8 +1,7 @@ ############################################################################ ## ## Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -## All rights reserved. -## Contact: Nokia Corporation (qt-info@nokia.com) +## Contact: http://www.qt-project.org/ ## ## This file is part of the QtGui module of the Qt Toolkit. ## @@ -35,6 +34,7 @@ ## ## ## +## ## $QT_END_LICENSE$ ## ############################################################################ diff --git a/src/corelib/arch/qatomic_alpha.h b/src/corelib/arch/qatomic_alpha.h index b44b9f23f5..432fb62c0a 100644 --- a/src/corelib/arch/qatomic_alpha.h +++ b/src/corelib/arch/qatomic_alpha.h @@ -1,8 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) +** Contact: http://www.qt-project.org/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** @@ -35,6 +34,7 @@ ** ** ** +** ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/corelib/arch/qatomic_arch.h b/src/corelib/arch/qatomic_arch.h index 66e12cc95b..59c8de3cde 100644 --- a/src/corelib/arch/qatomic_arch.h +++ b/src/corelib/arch/qatomic_arch.h @@ -1,8 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) +** Contact: http://www.qt-project.org/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** @@ -35,6 +34,7 @@ ** ** ** +** ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -52,24 +52,10 @@ QT_BEGIN_HEADER # include "QtCore/qatomic_vxworks.h" #elif defined(QT_ARCH_ALPHA) # include "QtCore/qatomic_alpha.h" -#elif defined(QT_ARCH_ARM) -# include "QtCore/qatomic_arm.h" -#elif defined(QT_ARCH_ARMV6) -# include "QtCore/qatomic_armv6.h" -#elif defined(QT_ARCH_AVR32) -# include "QtCore/qatomic_avr32.h" #elif defined(QT_ARCH_BFIN) # include "QtCore/qatomic_bfin.h" #elif defined(QT_ARCH_GENERIC) # include "QtCore/qatomic_generic.h" -#elif defined(QT_ARCH_I386) -# include "QtCore/qatomic_i386.h" -#elif defined(QT_ARCH_IA64) -# include "QtCore/qatomic_ia64.h" -#elif defined(QT_ARCH_MACOSX) -# include "QtCore/qatomic_macosx.h" -#elif defined(QT_ARCH_MIPS) -# include "QtCore/qatomic_mips.h" #elif defined(QT_ARCH_PARISC) # include "QtCore/qatomic_parisc.h" #elif defined(QT_ARCH_POWERPC) @@ -78,18 +64,10 @@ QT_BEGIN_HEADER # include "QtCore/qatomic_s390.h" #elif defined(QT_ARCH_SPARC) # include "QtCore/qatomic_sparc.h" -#elif defined(QT_ARCH_WINDOWS) -# include "QtCore/qatomic_windows.h" -#elif defined(QT_ARCH_WINDOWSCE) -# include "QtCore/qatomic_windowsce.h" -#elif defined(QT_ARCH_X86_64) -# include "QtCore/qatomic_x86_64.h" #elif defined(QT_ARCH_SH) # include "QtCore/qatomic_sh.h" #elif defined(QT_ARCH_SH4A) # include "QtCore/qatomic_sh4a.h" -#elif defined(QT_ARCH_NACL) -# include "QtCore/qatomic_generic.h" #else # error "Qt has not been ported to this architecture" #endif diff --git a/src/corelib/arch/qatomic_arm.h b/src/corelib/arch/qatomic_arm.h index b5856102b2..3852bbb9e2 100644 --- a/src/corelib/arch/qatomic_arm.h +++ b/src/corelib/arch/qatomic_arm.h @@ -1,8 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) +** Contact: http://www.qt-project.org/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** @@ -35,6 +34,7 @@ ** ** ** +** ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -42,16 +42,12 @@ #ifndef QATOMIC_ARM_H #define QATOMIC_ARM_H -QT_BEGIN_HEADER - #if defined(__ARM_ARCH_7__) \ || defined(__ARM_ARCH_7A__) \ || defined(__ARM_ARCH_7R__) \ || defined(__ARM_ARCH_7M__) # define QT_ARCH_ARMV7 -QT_BEGIN_INCLUDE_HEADER # include "QtCore/qatomic_armv7.h" -QT_END_INCLUDE_HEADER #elif defined(__ARM_ARCH_6__) \ || defined(__ARM_ARCH_6J__) \ || defined(__ARM_ARCH_6T2__) \ @@ -61,16 +57,10 @@ QT_END_INCLUDE_HEADER || defined(__ARM_ARCH_6M__) \ || (defined(__TARGET_ARCH_ARM) && (__TARGET_ARCH_ARM-0 >= 6)) # define QT_ARCH_ARMV6 -QT_BEGIN_INCLUDE_HEADER # include "QtCore/qatomic_armv6.h" -QT_END_INCLUDE_HEADER #else # define QT_ARCH_ARMV5 -QT_BEGIN_INCLUDE_HEADER # include "QtCore/qatomic_armv5.h" -QT_END_INCLUDE_HEADER #endif -QT_END_HEADER - #endif // QATOMIC_ARM_H diff --git a/src/corelib/arch/qatomic_armv5.h b/src/corelib/arch/qatomic_armv5.h index d602e83e64..95ad73b713 100644 --- a/src/corelib/arch/qatomic_armv5.h +++ b/src/corelib/arch/qatomic_armv5.h @@ -1,8 +1,8 @@ /**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) +** Copyright (C) 2011 Thiago Macieira <thiago@kde.org> +** Contact: http://www.qt-project.org/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** @@ -35,6 +35,7 @@ ** ** ** +** ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -42,303 +43,112 @@ #ifndef QATOMIC_ARMV5_H #define QATOMIC_ARMV5_H +#include <QtCore/qgenericatomic.h> + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE - -inline bool QBasicAtomicInt::isReferenceCountingNative() -{ return false; } -inline bool QBasicAtomicInt::isReferenceCountingWaitFree() -{ return false; } +#if 0 +#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 - -inline bool QBasicAtomicInt::isTestAndSetNative() -{ return false; } -inline bool QBasicAtomicInt::isTestAndSetWaitFree() -{ return false; } - #define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE #define Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE - -inline bool QBasicAtomicInt::isFetchAndStoreNative() -{ return true; } -inline bool QBasicAtomicInt::isFetchAndStoreWaitFree() -{ return true; } - #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 <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative() -{ return false; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree() -{ return false; } - #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree() -{ return true; } - #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NOT_NATIVE -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative() -{ return false; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree() -{ return false; } - -#ifndef QT_NO_ARM_EABI - -// kernel places a restartable cmpxchg implementation at a fixed address -extern "C" typedef int (qt_atomic_eabi_cmpxchg_int_t)(int oldval, int newval, volatile int *ptr); -extern "C" typedef int (qt_atomic_eabi_cmpxchg_ptr_t)(const void *oldval, const void *newval, volatile void *ptr); -#define qt_atomic_eabi_cmpxchg_int (*reinterpret_cast<qt_atomic_eabi_cmpxchg_int_t *>(0xffff0fc0)) -#define qt_atomic_eabi_cmpxchg_ptr (*reinterpret_cast<qt_atomic_eabi_cmpxchg_ptr_t *>(0xffff0fc0)) +#ifdef QT_NO_ARM_EABI +# error "Sorry, ARM without EABI is no longer supported" +#endif +#ifndef Q_OS_LINUX +# error "Qt is misconfigured: this ARMv5 implementation is only possible on Linux" +#endif -#else +template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned int> { enum { IsInteger = 1 }; }; -extern Q_CORE_EXPORT char q_atomic_lock; -Q_CORE_EXPORT void qt_atomic_yield(int *); +template <int size> struct QBasicAtomicOps: QGenericAtomicOps<QBasicAtomicOps<size> > +{ + // kernel places a restartable cmpxchg implementation at a fixed address + template <typename T> + static int _q_cmpxchg(T oldval, T newval, volatile T *ptr) + { + typedef int (* kernel_cmpxchg_t)(T oldval, T newval, volatile T *ptr); + kernel_cmpxchg_t kernel_cmpxchg = *reinterpret_cast<kernel_cmpxchg_t>(0xffff0fc0); + return kernel_cmpxchg(oldval, newval, ptr); + } + static void _q_dmb() + { + typedef void (* kernel_dmb_t)(); + kernel_dmb_t kernel_dmb = *reinterpret_cast<kernel_dmb_t>(0xffff0fa0); + kernel_dmb(); + } -#ifdef Q_CC_RVCT + static void orderedMemoryFence() { _q_dmb(); } -Q_CORE_EXPORT __asm char q_atomic_swp(volatile char *ptr, char newval); + template <typename T> static bool ref(T &_q_value); + template <typename T> static bool deref(T &_q_value); -#else + static bool isTestAndSetNative() { return false; } + static bool isTestAndSetWaitFree() { return false; } + template <typename T> static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue); + template <typename T> static T fetchAndStoreRelaxed(T &_q_value, T newValue); + template <typename T> static + T fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd); +}; -inline char q_atomic_swp(volatile char *ptr, char newval) +template <typename T> struct QAtomicOps : QBasicAtomicOps<sizeof(T)> { - register char ret; - asm volatile("swpb %0,%2,[%3]" - : "=&r"(ret), "=m" (*ptr) - : "r"(newval), "r"(ptr) - : "cc", "memory"); - return ret; -} + typedef T Type; +}; -#endif // Q_CC_RVCT - -#endif // QT_NO_ARM_EABI - -// Reference counting - -inline bool QBasicAtomicInt::ref() +template<> template<typename T> inline +bool QBasicAtomicOps<4>::ref(T &_q_value) { -#ifndef QT_NO_ARM_EABI - register int originalValue; - register int newValue; + register T originalValue; + register T newValue; do { originalValue = _q_value; newValue = originalValue + 1; - } while (qt_atomic_eabi_cmpxchg_int(originalValue, newValue, &_q_value) != 0); + } while (_q_cmpxchg(originalValue, newValue, &_q_value) != 0); return newValue != 0; -#else - int count = 0; - while (q_atomic_swp(&q_atomic_lock, ~0) != 0) - qt_atomic_yield(&count); - int originalValue = _q_value++; - q_atomic_swp(&q_atomic_lock, 0); - return originalValue != -1; -#endif } -inline bool QBasicAtomicInt::deref() +template<> template <typename T> inline +bool QBasicAtomicOps<4>::deref(T &_q_value) { -#ifndef QT_NO_ARM_EABI - register int originalValue; - register int newValue; + register T originalValue; + register T newValue; do { originalValue = _q_value; newValue = originalValue - 1; - } while (qt_atomic_eabi_cmpxchg_int(originalValue, newValue, &_q_value) != 0); + } while (_q_cmpxchg(originalValue, newValue, &_q_value) != 0); return newValue != 0; -#else - int count = 0; - while (q_atomic_swp(&q_atomic_lock, ~0) != 0) - qt_atomic_yield(&count); - int originalValue = _q_value--; - q_atomic_swp(&q_atomic_lock, 0); - return originalValue != 1; -#endif } -// Test and set for integers - -inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) +template<> template <typename T> inline +bool QBasicAtomicOps<4>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) { -#ifndef QT_NO_ARM_EABI - register int originalValue; + register T originalValue; do { originalValue = _q_value; if (originalValue != expectedValue) return false; - } while (qt_atomic_eabi_cmpxchg_int(expectedValue, newValue, &_q_value) != 0); + } while (_q_cmpxchg(expectedValue, newValue, &_q_value) != 0); return true; -#else - bool returnValue = false; - int count = 0; - while (q_atomic_swp(&q_atomic_lock, ~0) != 0) - qt_atomic_yield(&count); - if (_q_value == expectedValue) { - _q_value = newValue; - returnValue = true; - } - q_atomic_swp(&q_atomic_lock, 0); - return returnValue; -#endif -} - -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 - -#ifndef Q_CC_RVCT - -inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) -{ - int originalValue; - asm volatile("swp %0,%2,[%3]" - : "=&r"(originalValue), "=m" (_q_value) - : "r"(newValue), "r"(&_q_value) - : "cc", "memory"); - return originalValue; -} - -#endif - -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) -{ -#ifndef QT_NO_ARM_EABI - register int originalValue; - register int newValue; - do { - originalValue = _q_value; - newValue = originalValue + valueToAdd; - } while (qt_atomic_eabi_cmpxchg_int(originalValue, newValue, &_q_value) != 0); - return originalValue; -#else - int count = 0; - while (q_atomic_swp(&q_atomic_lock, ~0) != 0) - qt_atomic_yield(&count); - int originalValue = _q_value; - _q_value += valueToAdd; - q_atomic_swp(&q_atomic_lock, 0); - return originalValue; -#endif -} - -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 <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue) -{ -#ifndef QT_NO_ARM_EABI - register T *originalValue; - do { - originalValue = _q_value; - if (originalValue != expectedValue) - return false; - } while (qt_atomic_eabi_cmpxchg_ptr(expectedValue, newValue, &_q_value) != 0); - return true; -#else - bool returnValue = false; - int count = 0; - while (q_atomic_swp(&q_atomic_lock, ~0) != 0) - qt_atomic_yield(&count); - if (_q_value == expectedValue) { - _q_value = newValue; - returnValue = true; - } - q_atomic_swp(&q_atomic_lock, 0); - return returnValue; -#endif -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -// Fetch and store for pointers - #ifdef Q_CC_RVCT - -template <typename T> -__asm T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue) +template<> template <typename T> inline +__asm T QBasicAtomicOps<4>::fetchAndStoreRelaxed(T &_q_value, T newValue) { add r2, pc, #0 bx r2 @@ -348,80 +158,29 @@ __asm T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue) bx lr thumb } - #else - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue) +template<> template <typename T> inline +T QBasicAtomicOps<4>::fetchAndStoreRelaxed(T &_q_value, T newValue) { - T *originalValue; + T originalValue; asm volatile("swp %0,%2,[%3]" : "=&r"(originalValue), "=m" (_q_value) : "r"(newValue), "r"(&_q_value) : "cc", "memory"); return originalValue; } - #endif // Q_CC_RVCT -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -// Fetch and add for pointers - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd) +template<> template <typename T> inline +T QBasicAtomicOps<4>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) { -#ifndef QT_NO_ARM_EABI - register T *originalValue; - register T *newValue; + register T originalValue; + register T newValue; do { originalValue = _q_value; newValue = originalValue + valueToAdd; - } while (qt_atomic_eabi_cmpxchg_ptr(originalValue, newValue, &_q_value) != 0); + } while (_q_cmpxchg(originalValue, newValue, &_q_value) != 0); return originalValue; -#else - int count = 0; - while (q_atomic_swp(&q_atomic_lock, ~0) != 0) - qt_atomic_yield(&count); - T *originalValue = (_q_value); - _q_value += valueToAdd; - q_atomic_swp(&q_atomic_lock, 0); - return originalValue; -#endif -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); } QT_END_NAMESPACE diff --git a/src/corelib/arch/qatomic_armv6.h b/src/corelib/arch/qatomic_armv6.h index 260f48d563..7095d13d9b 100644 --- a/src/corelib/arch/qatomic_armv6.h +++ b/src/corelib/arch/qatomic_armv6.h @@ -1,8 +1,8 @@ /**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) +** Copyright (C) 2011 Thiago Macieira <thiago@kde.org> +** Contact: http://www.qt-project.org/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** @@ -35,6 +35,7 @@ ** ** ** +** ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -42,77 +43,72 @@ #ifndef QATOMIC_ARMV6_H #define QATOMIC_ARMV6_H +#include <QtCore/qgenericatomic.h> + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE - -inline bool QBasicAtomicInt::isReferenceCountingNative() -{ return true; } -inline bool QBasicAtomicInt::isReferenceCountingWaitFree() -{ return false; } +#if 0 +#pragma qt_sync_stop_processing +#endif +#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE #define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE - -inline bool QBasicAtomicInt::isTestAndSetNative() -{ return true; } -inline bool QBasicAtomicInt::isTestAndSetWaitFree() -{ return false; } - #define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE - -inline bool QBasicAtomicInt::isFetchAndStoreNative() -{ return true; } -inline bool QBasicAtomicInt::isFetchAndStoreWaitFree() -{ return false; } - #define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE -inline bool QBasicAtomicInt::isFetchAndAddNative() -{ return true; } -inline bool QBasicAtomicInt::isFetchAndAddWaitFree() -{ return false; } +#define Q_ATOMIC_INT32_IS_SUPPORTED +#define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT32_TEST_AND_SET_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_ALWAYS_NATIVE #define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE +#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE +#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree() -{ return false; } +template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned int> { enum { IsInteger = 1 }; }; -#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE +template <int size> struct QBasicAtomicOps: QGenericAtomicOps<QBasicAtomicOps<size> > +{ + static void orderedMemoryFence(); -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree() -{ return false; } + static inline bool isReferenceCountingNative() { return true; } + template <typename T> static bool ref(T &_q_value); + template <typename T> static bool deref(T &_q_value); -#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE + static inline bool isTestAndSetNative() { return true; } + static inline bool isTestAndSetWaitFree() { return false; } + template <typename T> static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue); -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree() -{ return false; } + static inline bool isFetchAndStoreNative() { return true; } + template <typename T> static T fetchAndStoreRelaxed(T &_q_value, T newValue); + + static inline bool isFetchAndAddNative() { return true; } + template <typename T> static + T fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd); +}; + +template <typename T> struct QAtomicOps : QBasicAtomicOps<sizeof(T)> +{ + typedef T Type; +}; #ifndef Q_CC_RVCT #ifndef Q_DATA_MEMORY_BARRIER -# define Q_DATA_MEMORY_BARRIER asm volatile("":::"memory") +# define Q_DATA_MEMORY_BARRIER asm volatile("mcr p15, 0, r0, c7, c10, 5":::"memory") #endif #ifndef Q_COMPILER_MEMORY_BARRIER # define Q_COMPILER_MEMORY_BARRIER asm volatile("":::"memory") #endif -inline bool QBasicAtomicInt::ref() +template<> template<typename T> inline +bool QBasicAtomicOps<4>::ref(T &_q_value) { - register int newValue; + register T newValue; register int result; asm volatile("0:\n" "ldrex %[newValue], [%[_q_value]]\n" @@ -128,9 +124,10 @@ inline bool QBasicAtomicInt::ref() return newValue != 0; } -inline bool QBasicAtomicInt::deref() +template<> template <typename T> inline +bool QBasicAtomicOps<4>::deref(T &_q_value) { - register int newValue; + register T newValue; register int result; asm volatile("0:\n" "ldrex %[newValue], [%[_q_value]]\n" @@ -146,7 +143,8 @@ inline bool QBasicAtomicInt::deref() return newValue != 0; } -inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) +template<> template <typename T> inline +bool QBasicAtomicOps<4>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) { register int result; asm volatile("0:\n" @@ -165,9 +163,10 @@ inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) return result == 0; } -inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue) +template<> template <typename T> inline +T QBasicAtomicOps<4>::fetchAndStoreRelaxed(T &_q_value, T newValue) { - register int originalValue; + register T originalValue; register int result; asm volatile("0:\n" "ldrex %[originalValue], [%[_q_value]]\n" @@ -183,10 +182,11 @@ inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue) return originalValue; } -inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd) +template<> template <typename T> inline +T QBasicAtomicOps<4>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) { - register int originalValue; - register int newValue; + register T originalValue; + register T newValue; register int result; asm volatile("0:\n" "ldrex %[originalValue], [%[_q_value]]\n" @@ -198,21 +198,94 @@ inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd) [newValue] "=&r" (newValue), [result] "=&r" (result), "+m" (_q_value) - : [valueToAdd] "r" (valueToAdd), + : [valueToAdd] "r" (valueToAdd * QAtomicAdditiveType<T>::AddScale), [_q_value] "r" (&_q_value) : "cc"); return originalValue; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue) +#if defined(__ARM_ARCH_7__) \ + || defined(__ARM_ARCH_7A__) \ + || defined(__ARM_ARCH_7R__) \ + || defined(__ARM_ARCH_7M__) \ + || defined(__ARM_ARCH_6K__) +// LDREXB, LDREXH and LDREXD are available on ARMv6K or higher + +template<> struct QAtomicIntegerTraits<char> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<signed char> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned char> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<short> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned short> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<long> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned long> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<long long> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned long long> { enum { IsInteger = 1 }; }; + +#define Q_ATOMIC_INT8_IS_SUPPORTED +#define Q_ATOMIC_INT8_REFERENCE_COUNTING_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT8_TEST_AND_SET_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT8_FETCH_AND_STORE_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT8_FETCH_AND_ADD_IS_ALWAYS_NATIVE + +#define Q_ATOMIC_INT16_IS_SUPPORTED +#define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT16_TEST_AND_SET_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_ALWAYS_NATIVE + +#define Q_ATOMIC_INT64_IS_SUPPORTED +#define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT64_TEST_AND_SET_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT64_FETCH_AND_STORE_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_ALWAYS_NATIVE + +template<> template<typename T> inline +bool QBasicAtomicOps<1>::ref(T &_q_value) +{ + register T newValue; + register int result; + asm volatile("0:\n" + "ldrexb %[newValue], [%[_q_value]]\n" + "add %[newValue], %[newValue], #1\n" + "strexb %[result], %[newValue], [%[_q_value]]\n" + "teq %[result], #0\n" + "bne 0b\n" + : [newValue] "=&r" (newValue), + [result] "=&r" (result), + "+m" (_q_value) + : [_q_value] "r" (&_q_value) + : "cc", "memory"); + return newValue != 0; +} + +template<> template <typename T> inline +bool QBasicAtomicOps<1>::deref(T &_q_value) { - register T *result; + register T newValue; + register int result; asm volatile("0:\n" - "ldrex %[result], [%[_q_value]]\n" + "ldrexb %[newValue], [%[_q_value]]\n" + "sub %[newValue], %[newValue], #1\n" + "strexb %[result], %[newValue], [%[_q_value]]\n" + "teq %[result], #0\n" + "bne 0b\n" + : [newValue] "=&r" (newValue), + [result] "=&r" (result), + "+m" (_q_value) + : [_q_value] "r" (&_q_value) + : "cc", "memory"); + return newValue != 0; +} + +template<> template <typename T> inline +bool QBasicAtomicOps<1>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) +{ + register T result; + asm volatile("0:\n" + "ldrexb %[result], [%[_q_value]]\n" "eors %[result], %[result], %[expectedValue]\n" "itt eq\n" - "strexeq %[result], %[newValue], [%[_q_value]]\n" + "strexbeq %[result], %[newValue], [%[_q_value]]\n" "teqeq %[result], #1\n" "beq 0b\n" : [result] "=&r" (result), @@ -224,14 +297,14 @@ Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValu return result == 0; } -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue) +template<> template <typename T> inline +T QBasicAtomicOps<1>::fetchAndStoreRelaxed(T &_q_value, T newValue) { - register T *originalValue; + register T originalValue; register int result; asm volatile("0:\n" - "ldrex %[originalValue], [%[_q_value]]\n" - "strex %[result], %[newValue], [%[_q_value]]\n" + "ldrexb %[originalValue], [%[_q_value]]\n" + "strexb %[result], %[newValue], [%[_q_value]]\n" "teq %[result], #0\n" "bne 0b\n" : [originalValue] "=&r" (originalValue), @@ -243,28 +316,239 @@ Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue) return originalValue; } -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd) +template<> template <typename T> inline +T QBasicAtomicOps<1>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) { - register T *originalValue; - register T *newValue; + register T originalValue; + register T newValue; register int result; asm volatile("0:\n" - "ldrex %[originalValue], [%[_q_value]]\n" + "ldrexb %[originalValue], [%[_q_value]]\n" "add %[newValue], %[originalValue], %[valueToAdd]\n" - "strex %[result], %[newValue], [%[_q_value]]\n" + "strexb %[result], %[newValue], [%[_q_value]]\n" + "teq %[result], #0\n" + "bne 0b\n" + : [originalValue] "=&r" (originalValue), + [newValue] "=&r" (newValue), + [result] "=&r" (result), + "+m" (_q_value) + : [valueToAdd] "r" (valueToAdd * QAtomicAdditiveType<T>::AddScale), + [_q_value] "r" (&_q_value) + : "cc"); + return originalValue; +} + +template<> template<typename T> inline +bool QBasicAtomicOps<2>::ref(T &_q_value) +{ + register T newValue; + register int result; + asm volatile("0:\n" + "ldrexh %[newValue], [%[_q_value]]\n" + "add %[newValue], %[newValue], #1\n" + "strexh %[result], %[newValue], [%[_q_value]]\n" + "teq %[result], #0\n" + "bne 0b\n" + : [newValue] "=&r" (newValue), + [result] "=&r" (result), + "+m" (_q_value) + : [_q_value] "r" (&_q_value) + : "cc", "memory"); + return newValue != 0; +} + +template<> template <typename T> inline +bool QBasicAtomicOps<2>::deref(T &_q_value) +{ + register T newValue; + register int result; + asm volatile("0:\n" + "ldrexh %[newValue], [%[_q_value]]\n" + "sub %[newValue], %[newValue], #1\n" + "strexh %[result], %[newValue], [%[_q_value]]\n" + "teq %[result], #0\n" + "bne 0b\n" + : [newValue] "=&r" (newValue), + [result] "=&r" (result), + "+m" (_q_value) + : [_q_value] "r" (&_q_value) + : "cc", "memory"); + return newValue != 0; +} + +template<> template <typename T> inline +bool QBasicAtomicOps<2>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) +{ + register T result; + asm volatile("0:\n" + "ldrexh %[result], [%[_q_value]]\n" + "eors %[result], %[result], %[expectedValue]\n" + "strexheq %[result], %[newValue], [%[_q_value]]\n" + "teqeq %[result], #1\n" + "beq 0b\n" + : [result] "=&r" (result), + "+m" (_q_value) + : [expectedValue] "r" (expectedValue), + [newValue] "r" (newValue), + [_q_value] "r" (&_q_value) + : "cc"); + return result == 0; +} + +template<> template <typename T> inline +T QBasicAtomicOps<2>::fetchAndStoreRelaxed(T &_q_value, T newValue) +{ + register T originalValue; + register int result; + asm volatile("0:\n" + "ldrexh %[originalValue], [%[_q_value]]\n" + "strexh %[result], %[newValue], [%[_q_value]]\n" + "teq %[result], #0\n" + "bne 0b\n" + : [originalValue] "=&r" (originalValue), + [result] "=&r" (result), + "+m" (_q_value) + : [newValue] "r" (newValue), + [_q_value] "r" (&_q_value) + : "cc"); + return originalValue; +} + +template<> template <typename T> inline +T QBasicAtomicOps<2>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) +{ + register T originalValue; + register T newValue; + register int result; + asm volatile("0:\n" + "ldrexh %[originalValue], [%[_q_value]]\n" + "add %[newValue], %[originalValue], %[valueToAdd]\n" + "strexh %[result], %[newValue], [%[_q_value]]\n" "teq %[result], #0\n" "bne 0b\n" : [originalValue] "=&r" (originalValue), [newValue] "=&r" (newValue), [result] "=&r" (result), "+m" (_q_value) - : [valueToAdd] "r" (valueToAdd * sizeof(T)), + : [valueToAdd] "r" (valueToAdd * QAtomicAdditiveType<T>::AddScale), [_q_value] "r" (&_q_value) : "cc"); return originalValue; } +// Explanation from GCC's source code (config/arm/arm.c) on the modifiers below: +// Whenever you use "r" (dwordVariable), you get assigned a register pair: +// %[reg] - lower-numbered register +// %H[reg] - higher-numbered register +// %Q[reg] - low part of the value +// %R[reg] - high part of the value +// If this is a little-endian build, H and R are the same; otherwise, H and Q are the same. + +template<> template<typename T> inline +bool QBasicAtomicOps<8>::ref(T &_q_value) +{ + register T newValue; + register int result; + asm volatile("0:\n" + "ldrexd %[newValue], %H[newValue], [%[_q_value]]\n" + "adds %Q[newValue], %Q[newValue], #1\n" + "adc %R[newValue], %R[newValue], #0\n" + "strexd %[result], %[newValue], %H[newValue], [%[_q_value]]\n" + "teq %[result], #0\n" + "bne 0b\n" + : [newValue] "=&r" (newValue), + [result] "=&r" (result), + "+m" (_q_value) + : [_q_value] "r" (&_q_value) + : "cc", "memory"); + return newValue != 0; +} + +template<> template <typename T> inline +bool QBasicAtomicOps<8>::deref(T &_q_value) +{ + register T newValue; + register int result; + asm volatile("0:\n" + "ldrexd %[newValue], %H[newValue], [%[_q_value]]\n" + "subs %Q[newValue], %Q[newValue], #1\n" + "sbc %R[newValue], %R[newValue], #0\n" + "strexd %[result], %[newValue], %H[newValue], [%[_q_value]]\n" + "teq %[result], #0\n" + "bne 0b\n" + : [newValue] "=&r" (newValue), + [result] "=&r" (result), + "+m" (_q_value) + : [_q_value] "r" (&_q_value) + : "cc", "memory"); + return newValue != 0; +} + +template<> template <typename T> inline +bool QBasicAtomicOps<8>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) +{ + register T result; + asm volatile("0:\n" + "ldrexd %[result], %H[result], [%[_q_value]]\n" + "eor %[result], %[result], %[expectedValue]\n" + "eor %H[result], %H[result], %H[expectedValue]\n" + "orrs %[result], %[result], %H[result]\n" + "strexdeq %[result], %[newValue], %H[newValue], [%[_q_value]]\n" + "teqeq %[result], #1\n" + "beq 0b\n" + : [result] "=&r" (result), + "+m" (_q_value) + : [expectedValue] "r" (expectedValue), + [newValue] "r" (newValue), + [_q_value] "r" (&_q_value) + : "cc"); + return quint32(result) == 0; +} + +template<> template <typename T> inline +T QBasicAtomicOps<8>::fetchAndStoreRelaxed(T &_q_value, T newValue) +{ + register T originalValue; + register int result; + asm volatile("0:\n" + "ldrexd %[originalValue], %H[originalValue], [%[_q_value]]\n" + "strexd %[result], %[newValue], %H[newValue], [%[_q_value]]\n" + "teq %[result], #0\n" + "bne 0b\n" + : [originalValue] "=&r" (originalValue), + [result] "=&r" (result), + "+m" (_q_value) + : [newValue] "r" (newValue), + [_q_value] "r" (&_q_value) + : "cc"); + return originalValue; +} + +template<> template <typename T> inline +T QBasicAtomicOps<8>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) +{ + register T originalValue; + register T newValue; + register int result; + asm volatile("0:\n" + "ldrexd %[originalValue], %H[originalValue], [%[_q_value]]\n" + "adds %Q[newValue], %Q[originalValue], %Q[valueToAdd]\n" + "adc %R[newValue], %R[originalValue], %R[valueToAdd]\n" + "strexd %[result], %[newValue], %H[newValue], [%[_q_value]]\n" + "teq %[result], #0\n" + "bne 0b\n" + : [originalValue] "=&r" (originalValue), + [newValue] "=&r" (newValue), + [result] "=&r" (result), + "+m" (_q_value) + : [valueToAdd] "r" (valueToAdd * QAtomicAdditiveType<T>::AddScale), + [_q_value] "r" (&_q_value) + : "cc"); + return originalValue; +} + +#endif + #else // This is Q_CC_RVCT @@ -415,140 +699,10 @@ Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueTo // common code -inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue) -{ - bool returnValue = testAndSetRelaxed(expectedValue, newValue); - Q_DATA_MEMORY_BARRIER; - return returnValue; -} - -inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue) -{ - Q_DATA_MEMORY_BARRIER; - return testAndSetRelaxed(expectedValue, newValue); -} - -inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) -{ - Q_DATA_MEMORY_BARRIER; - bool returnValue = testAndSetRelaxed(expectedValue, newValue); - Q_COMPILER_MEMORY_BARRIER; - return returnValue; -} - -inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue) -{ - int returnValue = fetchAndStoreRelaxed(newValue); - Q_DATA_MEMORY_BARRIER; - return returnValue; -} - -inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue) -{ - Q_DATA_MEMORY_BARRIER; - return fetchAndStoreRelaxed(newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) -{ - Q_DATA_MEMORY_BARRIER; - int returnValue = fetchAndStoreRelaxed(newValue); - Q_COMPILER_MEMORY_BARRIER; - return returnValue; -} - - -inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd) -{ - int returnValue = fetchAndAddRelaxed(valueToAdd); - Q_DATA_MEMORY_BARRIER; - return returnValue; -} - -inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd) -{ - Q_DATA_MEMORY_BARRIER; - return fetchAndAddRelaxed(valueToAdd); -} - -inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) -{ - Q_DATA_MEMORY_BARRIER; - int returnValue = fetchAndAddRelaxed(valueToAdd); - Q_COMPILER_MEMORY_BARRIER; - return returnValue; -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue) -{ - bool returnValue = testAndSetRelaxed(expectedValue, newValue); - Q_DATA_MEMORY_BARRIER; - return returnValue; -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue) -{ - Q_DATA_MEMORY_BARRIER; - return testAndSetRelaxed(expectedValue, newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue) -{ - Q_DATA_MEMORY_BARRIER; - bool returnValue = testAndSetAcquire(expectedValue, newValue); - Q_COMPILER_MEMORY_BARRIER; - return returnValue; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue) -{ - T *returnValue = fetchAndStoreRelaxed(newValue); - Q_DATA_MEMORY_BARRIER; - return returnValue; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue) -{ - Q_DATA_MEMORY_BARRIER; - return fetchAndStoreRelaxed(newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue) -{ - Q_DATA_MEMORY_BARRIER; - T *returnValue = fetchAndStoreRelaxed(newValue); - Q_COMPILER_MEMORY_BARRIER; - return returnValue; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd) -{ - T *returnValue = fetchAndAddRelaxed(valueToAdd); - Q_DATA_MEMORY_BARRIER; - return returnValue; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd) -{ - Q_DATA_MEMORY_BARRIER; - return fetchAndAddRelaxed(valueToAdd); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd) +template <int size> inline +void QBasicAtomicOps<size>::orderedMemoryFence() { Q_DATA_MEMORY_BARRIER; - T *returnValue = fetchAndAddRelaxed(valueToAdd); - Q_COMPILER_MEMORY_BARRIER; - return returnValue; } #undef Q_DATA_MEMORY_BARRIER diff --git a/src/corelib/arch/qatomic_armv7.h b/src/corelib/arch/qatomic_armv7.h index 814eefb376..5b36708ad6 100644 --- a/src/corelib/arch/qatomic_armv7.h +++ b/src/corelib/arch/qatomic_armv7.h @@ -1,8 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) +** Contact: http://www.qt-project.org/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** @@ -35,6 +34,7 @@ ** ** ** +** ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -42,8 +42,6 @@ #ifndef QATOMIC_ARMV7_H #define QATOMIC_ARMV7_H -QT_BEGIN_HEADER - // use the DMB instruction when compiling for ARMv7, ... #ifndef Q_CC_RCVT # define Q_DATA_MEMORY_BARRIER asm volatile("dmb\n":::"memory") @@ -52,10 +50,6 @@ QT_BEGIN_HEADER #endif // ... but the implementation is otherwise identical to that for ARMv6 -QT_BEGIN_INCLUDE_HEADER #include "QtCore/qatomic_armv6.h" -QT_END_INCLUDE_HEADER - -QT_END_HEADER #endif // QATOMIC_ARMV7_H diff --git a/src/corelib/arch/qatomic_avr32.h b/src/corelib/arch/qatomic_avr32.h deleted file mode 100644 index 749cc0fd36..0000000000 --- a/src/corelib/arch/qatomic_avr32.h +++ /dev/null @@ -1,252 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 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$ -** 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_AVR32_H -#define QATOMIC_AVR32_H - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE - -inline bool QBasicAtomicInt::isReferenceCountingNative() -{ return true; } -inline bool QBasicAtomicInt::isReferenceCountingWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE - -inline bool QBasicAtomicInt::isTestAndSetNative() -{ return true; } -inline bool QBasicAtomicInt::isTestAndSetWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE -#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE - -inline bool QBasicAtomicInt::isFetchAndStoreNative() -{ return true; } -inline bool QBasicAtomicInt::isFetchAndStoreWaitFree() -{ return true; } - -#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE - -inline bool QBasicAtomicInt::isFetchAndAddNative() -{ return true; } -inline bool QBasicAtomicInt::isFetchAndAddWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE -#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree() -{ return true; } - -#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree() -{ return false; } - -inline bool QBasicAtomicInt::ref() -{ - return __sync_add_and_fetch(&_q_value, 1); -} - -inline bool QBasicAtomicInt::deref() -{ - return __sync_sub_and_fetch(&_q_value, 1); -} - -inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) -{ - return __sync_bool_compare_and_swap(&_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); -} - -inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) -{ - return __sync_lock_test_and_set(&_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); -} - -inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) -{ - return __sync_fetch_and_add(&_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); -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue) -{ - return __sync_bool_compare_and_swap(&_q_value, expectedValue, newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue) -{ - return __sync_lock_test_and_set(&_q_value, newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd) -{ - return __sync_fetch_and_add(&_q_value, valueToAdd * sizeof(T)); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QATOMIC_AVR32_H diff --git a/src/corelib/arch/qatomic_bfin.h b/src/corelib/arch/qatomic_bfin.h index 4784b634fc..530ac8d50f 100644 --- a/src/corelib/arch/qatomic_bfin.h +++ b/src/corelib/arch/qatomic_bfin.h @@ -1,8 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) +** Contact: http://www.qt-project.org/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** @@ -35,6 +34,7 @@ ** ** ** +** ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/corelib/arch/qatomic_bootstrap.h b/src/corelib/arch/qatomic_bootstrap.h index 86376062a2..10cdc888f6 100644 --- a/src/corelib/arch/qatomic_bootstrap.h +++ b/src/corelib/arch/qatomic_bootstrap.h @@ -1,8 +1,8 @@ /**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) +** Copyright (C) 2011 Thiago Macieira <thiago@kde.org> +** Contact: http://www.qt-project.org/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** @@ -35,6 +35,7 @@ ** ** ** +** ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -42,76 +43,54 @@ #ifndef QATOMIC_BOOTSTRAP_H #define QATOMIC_BOOTSTRAP_H +#include <QtCore/qgenericatomic.h> + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -inline bool QBasicAtomicInt::ref() -{ - return ++_q_value != 0; -} +#if 0 +#pragma qt_sync_stop_processing +#endif -inline bool QBasicAtomicInt::deref() +template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; }; +template <typename T> struct QAtomicOps: QGenericAtomicOps<QAtomicOps<T> > { - return --_q_value != 0; -} + typedef T Type; -inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) -{ - if (_q_value == expectedValue) { - _q_value = newValue; - return true; + static bool ref(T &_q_value) + { + return ++_q_value != 0; + } + static bool deref(T &_q_value) + { + return --_q_value != 0; } - return false; -} - -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 bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) -{ - int returnValue = _q_value; - _q_value += valueToAdd; - return returnValue; -} - -inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} + static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) + { + if (_q_value == expectedValue) { + _q_value = newValue; + return true; + } + return false; + } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue) -{ - if (_q_value == expectedValue) { + static T fetchAndStoreRelaxed(T &_q_value, T newValue) + { + T tmp = _q_value; _q_value = newValue; - return true; + return tmp; + } + + static + T fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) + { + T returnValue = _q_value; + _q_value += valueToAdd; + return returnValue; } - return false; -} +}; QT_END_NAMESPACE diff --git a/src/corelib/arch/qatomic_cxx11.h b/src/corelib/arch/qatomic_cxx11.h new file mode 100644 index 0000000000..c2df59fd54 --- /dev/null +++ b/src/corelib/arch/qatomic_cxx11.h @@ -0,0 +1,247 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Thiago Macieira <thiago@kde.org> +** 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_CXX11_H +#define QATOMIC_CXX11_H + +#include <QtCore/qgenericatomic.h> +#include <atomic> + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +#if 0 +#pragma qt_sync_stop_processing +#endif + +#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE +#define Q_ATOMIC_INT_TEST_AND_SET_IS_SOMETIMES_NATIVE +#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_SOMETIMES_NATIVE +#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_SOMETIMES_NATIVE + +#define Q_ATOMIC_INT32_IS_SUPPORTED +#define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE +#define Q_ATOMIC_INT32_TEST_AND_SET_IS_SOMETIMES_NATIVE +#define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_SOMETIMES_NATIVE +#define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_SOMETIMES_NATIVE + +#define Q_ATOMIC_POINTER_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE +#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_SOMETIMES_NATIVE +#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_SOMETIMES_NATIVE +#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_SOMETIMES_NATIVE + +template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned int> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<char> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<signed char> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned char> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<short> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned short> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<long> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned long> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<long long> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned long long> { enum { IsInteger = 1 }; }; + +#define Q_ATOMIC_INT8_IS_SUPPORTED +#define Q_ATOMIC_INT8_REFERENCE_COUNTING_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT8_TEST_AND_SET_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT8_FETCH_AND_STORE_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT8_FETCH_AND_ADD_IS_ALWAYS_NATIVE + +#define Q_ATOMIC_INT16_IS_SUPPORTED +#define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT16_TEST_AND_SET_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_ALWAYS_NATIVE + +#define Q_ATOMIC_INT64_IS_SUPPORTED +#define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT64_TEST_AND_SET_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT64_FETCH_AND_STORE_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_ALWAYS_NATIVE + +template <typename T> struct QAtomicOps +{ + typedef std::atomic<T> Type; + typedef typename QAtomicAdditiveType<T>::AdditiveT _AdditiveType; + static const int AddScale = QAtomicAdditiveType<T>::AddScale; + + static void acquireMemoryFence() { } + static void releaseMemoryFence() { } + static void orderedMemoryFence() { } + + static inline + T load(const Type &_q_value) + { + return _q_value.load(std::memory_order_relaxed); + } + + static inline + T load(const volatile Type &_q_value) + { + return _q_value.load(std::memory_order_relaxed); + } + + static inline + T loadAcquire(const Type &_q_value) + { + return _q_value.load(std::memory_order_acquire); + } + + static inline + T loadAcquire(const volatile Type &_q_value) + { + return _q_value.load(std::memory_order_acquire); + } + + static inline + void store(Type &_q_value, T newValue) + { + _q_value.store(newValue, std::memory_order_relaxed); + } + + static inline + void storeRelease(Type &_q_value, T newValue) + { + _q_value.store(newValue, std::memory_order_release); + } + + static inline bool isReferenceCountingNative() { return true; } + static inline bool isReferenceCountingWaitFree() { return false; } + static inline bool ref(Type &_q_value) + { + return ++_q_value != 0; + } + + static inline bool deref(Type &_q_value) + { + return --_q_value != 0; + } + + static inline bool isTestAndSetNative() { return false; } + static inline bool isTestAndSetWaitFree() { return false; } + + static + bool testAndSetRelaxed(Type &_q_value, T expectedValue, T newValue) + { + return _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_relaxed); + } + + static bool testAndSetAcquire(Type &_q_value, T expectedValue, T newValue) + { + return _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acquire); + } + + static bool testAndSetRelease(Type &_q_value, T expectedValue, T newValue) + { + return _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_release); + } + + static bool testAndSetOrdered(Type &_q_value, T expectedValue, T newValue) + { + return _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acq_rel); + } + + static inline bool isFetchAndStoreNative() { return false; } + static inline bool isFetchAndStoreWaitFree() { return false; } + + static T fetchAndStoreRelaxed(Type &_q_value, T newValue) + { + return _q_value.exchange(newValue, std::memory_order_relaxed); + } + + static T fetchAndStoreAcquire(Type &_q_value, T newValue) + { + return _q_value.exchange(newValue, std::memory_order_acquire); + } + + static T fetchAndStoreRelease(Type &_q_value, T newValue) + { + return _q_value.exchange(newValue, std::memory_order_release); + } + + static T fetchAndStoreOrdered(Type &_q_value, T newValue) + { + return _q_value.exchange(newValue, std::memory_order_acq_rel); + } + + static inline bool isFetchAndAddNative() { return false; } + static inline bool isFetchAndAddWaitFree() { return false; } + + static + T fetchAndAddRelaxed(Type &_q_value, _AdditiveType valueToAdd) + { + return _q_value.fetch_add(valueToAdd * AddScale, + std::memory_order_relaxed); + } + + static + T fetchAndAddAcquire(Type &_q_value, _AdditiveType valueToAdd) + { + return _q_value.fetch_add(valueToAdd * AddScale, + std::memory_order_acquire); + } + + static + T fetchAndAddRelease(Type &_q_value, _AdditiveType valueToAdd) + { + return _q_value.fetch_add(valueToAdd * AddScale, + std::memory_order_release); + } + + static + T fetchAndAddOrdered(Type &_q_value, _AdditiveType valueToAdd) + { + return _q_value.fetch_add(valueToAdd * AddScale, + std::memory_order_acq_rel); + } +}; + +#ifdef ATOMIC_VAR_INIT +# define Q_BASIC_ATOMIC_INITIALIZER(a) { ATOMIC_VAR_INIT(a) } +#else +# define Q_BASIC_ATOMIC_INITIALIZER(a) { {a} } +#endif + +QT_END_NAMESPACE +QT_END_HEADER + +#endif // QATOMIC_CXX0X_H diff --git a/src/corelib/arch/qatomic_gcc.h b/src/corelib/arch/qatomic_gcc.h new file mode 100644 index 0000000000..b5244429e6 --- /dev/null +++ b/src/corelib/arch/qatomic_gcc.h @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Thiago Macieira <thiago@kde.org> +** 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_GCC_H +#define QATOMIC_GCC_H + +#include <QtCore/qgenericatomic.h> + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE + +#if 0 +#pragma qt_sync_stop_processing +#endif + +template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned int> { enum { IsInteger = 1 }; }; + +#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE +#define Q_ATOMIC_INT_TEST_AND_SET_IS_SOMETIMES_NATIVE +#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_SOMETIMES_NATIVE +#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_SOMETIMES_NATIVE + +#define Q_ATOMIC_INT32_IS_SUPPORTED +#define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE +#define Q_ATOMIC_INT32_TEST_AND_SET_IS_SOMETIMES_NATIVE +#define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_SOMETIMES_NATIVE +#define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_SOMETIMES_NATIVE + +#define Q_ATOMIC_POINTER_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE +#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_SOMETIMES_NATIVE +#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_SOMETIMES_NATIVE +#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_SOMETIMES_NATIVE + +template <typename T> struct QAtomicOps: QGenericAtomicOps<QAtomicOps<T> > +{ + // The GCC intrinsics all have fully-ordered memory semantics, so we define + // only the xxxRelaxed functions. The exception is __sync_lock_and_test, + // which has acquire semantics, so we need to define the Release and + // Ordered versions too. + + typedef T Type; + +#ifndef __ia64__ + static T loadAcquire(T &_q_value) + { + T tmp = _q_value; + __sync_synchronize(); + return tmp; + } + + static void storeRelease(T &_q_value, T newValue) + { + __sync_synchronize(); + _q_value = newValue; + } +#endif + + static bool isTestAndSetNative() { return false; } + static bool isTestAndSetWaitFree() { return false; } + static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) + { + return __sync_bool_compare_and_swap(&_q_value, expectedValue, newValue); + } + + static T fetchAndStoreRelaxed(T &_q_value, T newValue) + { + return __sync_lock_test_and_set(&_q_value, newValue); + } + + static T fetchAndStoreRelease(T &_q_value, T newValue) + { + __sync_synchronize(); + return __sync_lock_test_and_set(&_q_value, newValue); + } + + static T fetchAndStoreOrdered(T &_q_value, T newValue) + { + return fetchAndStoreRelease(_q_value, newValue); + } + + static + T fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) + { + return __sync_fetch_and_add(&_q_value, valueToAdd * QAtomicAdditiveType<T>::AddScale); + } +}; + +QT_END_NAMESPACE +QT_END_HEADER + +#endif // QATOMIC_GCC_H diff --git a/src/corelib/arch/qatomic_generic.h b/src/corelib/arch/qatomic_generic.h index 0abc29cdb0..621a767dd6 100644 --- a/src/corelib/arch/qatomic_generic.h +++ b/src/corelib/arch/qatomic_generic.h @@ -1,8 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) +** Contact: http://www.qt-project.org/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** @@ -35,6 +34,7 @@ ** ** ** +** ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/corelib/arch/qatomic_i386.h b/src/corelib/arch/qatomic_i386.h index 53a81864bf..6fec561177 100644 --- a/src/corelib/arch/qatomic_i386.h +++ b/src/corelib/arch/qatomic_i386.h @@ -1,8 +1,8 @@ /**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) +** Copyright (C) 2011 Thiago Macieira <thiago@kde.org> +** Contact: http://www.qt-project.org/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** @@ -35,6 +35,7 @@ ** ** ** +** ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -42,318 +43,310 @@ #ifndef QATOMIC_I386_H #define QATOMIC_I386_H +#include <QtCore/qgenericatomic.h> + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE +#if 0 +#pragma qt_sync_stop_processing +#endif + +template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned int> { enum { IsInteger = 1 }; }; + #define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE #define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_WAIT_FREE -inline bool QBasicAtomicInt::isReferenceCountingNative() -{ return true; } -inline bool QBasicAtomicInt::isReferenceCountingWaitFree() -{ return true; } - #define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE #define Q_ATOMIC_INT_TEST_AND_SET_IS_WAIT_FREE -inline bool QBasicAtomicInt::isTestAndSetNative() -{ return true; } -inline bool QBasicAtomicInt::isTestAndSetWaitFree() -{ return true; } - #define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE #define Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE -inline bool QBasicAtomicInt::isFetchAndStoreNative() -{ return true; } -inline bool QBasicAtomicInt::isFetchAndStoreWaitFree() -{ return true; } - #define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE #define Q_ATOMIC_INT_FETCH_AND_ADD_IS_WAIT_FREE -inline bool QBasicAtomicInt::isFetchAndAddNative() -{ return true; } -inline bool QBasicAtomicInt::isFetchAndAddWaitFree() -{ return true; } +#define Q_ATOMIC_INT32_IS_SUPPORTED + +#define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_WAIT_FREE + +#define Q_ATOMIC_INT32_TEST_AND_SET_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT32_TEST_AND_SET_IS_WAIT_FREE + +#define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_WAIT_FREE + +#define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_WAIT_FREE #define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE #define Q_ATOMIC_POINTER_TEST_AND_SET_IS_WAIT_FREE -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree() -{ return true; } - #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree() -{ return true; } - #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_WAIT_FREE -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree() -{ return true; } +template <int size> struct QBasicAtomicOps: QGenericAtomicOps<QBasicAtomicOps<size> > +{ + static inline bool isReferenceCountingNative() { return true; } + static inline bool isReferenceCountingWaitFree() { return true; } + template <typename T> static bool ref(T &_q_value); + template <typename T> static bool deref(T &_q_value); + + static inline bool isTestAndSetNative() { return true; } + static inline bool isTestAndSetWaitFree() { return true; } + template <typename T> static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue); + + static inline bool isFetchAndStoreNative() { return true; } + static inline bool isFetchAndStoreWaitFree() { return true; } + template <typename T> static T fetchAndStoreRelaxed(T &_q_value, T newValue); + + static inline bool isFetchAndAddNative() { return true; } + static inline bool isFetchAndAddWaitFree() { return true; } + template <typename T> static + T fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd); +}; + +template <typename T> struct QAtomicOps : QBasicAtomicOps<sizeof(T)> +{ + typedef T Type; +}; #if defined(Q_CC_GNU) || defined(Q_CC_INTEL) -inline bool QBasicAtomicInt::ref() +template<> struct QAtomicIntegerTraits<char> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<signed char> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned char> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<short> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned short> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<long> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned long> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<long long> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned long long> { enum { IsInteger = 1 }; }; + +template<> template<typename T> inline +bool QBasicAtomicOps<1>::ref(T &_q_value) { unsigned char ret; asm volatile("lock\n" - "incl %0\n" + "incb %0\n" "setne %1" - : "=m" (_q_value), "=qm" (ret) - : "m" (_q_value) + : "+m" (_q_value), "=qm" (ret) + : : "memory"); return ret != 0; } -inline bool QBasicAtomicInt::deref() +template<> template<typename T> inline +bool QBasicAtomicOps<2>::ref(T &_q_value) { - unsigned char ret; + unsigned char ret; asm volatile("lock\n" - "decl %0\n" + "incw %0\n" "setne %1" - : "=m" (_q_value), "=qm" (ret) - : "m" (_q_value) + : "+m" (_q_value), "=qm" (ret) + : : "memory"); return ret != 0; } -inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) +template<> template<typename T> inline +bool QBasicAtomicOps<4>::ref(T &_q_value) { unsigned char ret; asm volatile("lock\n" - "cmpxchgl %3,%2\n" - "sete %1\n" - : "=a" (newValue), "=qm" (ret), "+m" (_q_value) - : "r" (newValue), "0" (expectedValue) + "incl %0\n" + "setne %1" + : "+m" (_q_value), "=qm" (ret) + : : "memory"); return ret != 0; } -inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) +template<> template <typename T> inline +bool QBasicAtomicOps<1>::deref(T &_q_value) { - asm volatile("xchgl %0,%1" - : "=r" (newValue), "+m" (_q_value) - : "0" (newValue) + unsigned char ret; + asm volatile("lock\n" + "decb %0\n" + "setne %1" + : "+m" (_q_value), "=qm" (ret) + : : "memory"); - return newValue; + return ret != 0; } -inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) +template<> template <typename T> inline +bool QBasicAtomicOps<2>::deref(T &_q_value) { + unsigned char ret; asm volatile("lock\n" - "xaddl %0,%1" - : "=r" (valueToAdd), "+m" (_q_value) - : "0" (valueToAdd) + "decw %0\n" + "setne %1" + : "+m" (_q_value), "=qm" (ret) + : : "memory"); - return valueToAdd; + return ret != 0; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue) +template<> template <typename T> inline +bool QBasicAtomicOps<4>::deref(T &_q_value) { unsigned char ret; asm volatile("lock\n" - "cmpxchgl %3,%2\n" - "sete %1\n" - : "=a" (newValue), "=qm" (ret), "+m" (_q_value) - : "r" (newValue), "0" (expectedValue) + "decl %0\n" + "setne %1" + : "+m" (_q_value), "=qm" (ret) + : : "memory"); return ret != 0; } -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue) +template<int size> template <typename T> inline +bool QBasicAtomicOps<size>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) { - asm volatile("xchgl %0,%1" - : "=r" (newValue), "+m" (_q_value) - : "0" (newValue) + unsigned char ret; + asm volatile("lock\n" + "cmpxchg %3,%2\n" + "sete %1\n" + : "=a" (newValue), "=qm" (ret), "+m" (_q_value) + : "r" (newValue), "0" (expectedValue) : "memory"); - return newValue; + return ret != 0; } -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd) +template<> template <typename T> inline +bool QBasicAtomicOps<1>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) { + unsigned char ret; asm volatile("lock\n" - "xaddl %0,%1" - : "=r" (valueToAdd), "+m" (_q_value) - : "0" (valueToAdd * sizeof(T)) + "cmpxchg %3,%2\n" + "sete %1\n" + : "=a" (newValue), "=qm" (ret), "+m" (_q_value) + : "q" (newValue), "0" (expectedValue) : "memory"); - return reinterpret_cast<T *>(valueToAdd); -} - -#else - -extern "C" { - Q_CORE_EXPORT int q_atomic_test_and_set_int(volatile int *ptr, int expected, int newval); - Q_CORE_EXPORT int q_atomic_test_and_set_ptr(volatile void *ptr, void *expected, void *newval); - Q_CORE_EXPORT int q_atomic_increment(volatile int *ptr); - Q_CORE_EXPORT int q_atomic_decrement(volatile int *ptr); - Q_CORE_EXPORT int q_atomic_set_int(volatile int *ptr, int newval); - Q_CORE_EXPORT void *q_atomic_set_ptr(volatile void *ptr, void *newval); - Q_CORE_EXPORT int q_atomic_fetch_and_add_int(volatile int *ptr, int value); - Q_CORE_EXPORT void *q_atomic_fetch_and_add_ptr(volatile void *ptr, int value); -} // extern "C" - -inline bool QBasicAtomicInt::ref() -{ - return q_atomic_increment(&_q_value) != 0; -} - -inline bool QBasicAtomicInt::deref() -{ - return q_atomic_decrement(&_q_value) != 0; -} - -inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) -{ - return q_atomic_test_and_set_int(&_q_value, expectedValue, newValue) != 0; -} - -inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) -{ - return q_atomic_set_int(&_q_value, newValue); -} - -inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) -{ - return q_atomic_fetch_and_add_int(&_q_value, valueToAdd); -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue) -{ - return q_atomic_test_and_set_ptr(&_q_value, expectedValue, newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue) -{ - return reinterpret_cast<T *>(q_atomic_set_ptr(&_q_value, newValue)); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd) -{ - return reinterpret_cast<T *>(q_atomic_fetch_and_add_ptr(&_q_value, valueToAdd * sizeof(T))); -} - -#endif - -inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); + return ret != 0; } -inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue) +template<int size> template <typename T> inline +T QBasicAtomicOps<size>::fetchAndStoreRelaxed(T &_q_value, T newValue) { - return testAndSetOrdered(expectedValue, newValue); + asm volatile("xchg %0,%1" + : "=r" (newValue), "+m" (_q_value) + : "0" (newValue) + : "memory"); + return newValue; } -inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue) +template<> template <typename T> inline +T QBasicAtomicOps<1>::fetchAndStoreRelaxed(T &_q_value, T newValue) { - return fetchAndStoreOrdered(newValue); + asm volatile("xchg %0,%1" + : "=q" (newValue), "+m" (_q_value) + : "0" (newValue) + : "memory"); + return newValue; } -inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue) +template<int size> template <typename T> inline +T QBasicAtomicOps<size>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) { - return fetchAndStoreOrdered(newValue); + T result; + asm volatile("lock\n" + "xadd %0,%1" + : "=r" (result), "+m" (_q_value) + : "0" (T(valueToAdd * QAtomicAdditiveType<T>::AddScale)) + : "memory"); + return result; } -inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue) +template<> template <typename T> inline +T QBasicAtomicOps<1>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) { - return fetchAndStoreOrdered(newValue); + T result; + asm volatile("lock\n" + "xadd %0,%1" + : "=q" (result), "+m" (_q_value) + : "0" (T(valueToAdd * QAtomicAdditiveType<T>::AddScale)) + : "memory"); + return result; } -inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} +#define Q_ATOMIC_INT8_IS_SUPPORTED -inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} +#define Q_ATOMIC_INT8_REFERENCE_COUNTING_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT8_REFERENCE_COUNTING_IS_WAIT_FREE -inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} +#define Q_ATOMIC_INT8_TEST_AND_SET_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT8_TEST_AND_SET_IS_WAIT_FREE -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} +#define Q_ATOMIC_INT8_FETCH_AND_STORE_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT8_FETCH_AND_STORE_IS_WAIT_FREE -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} +#define Q_ATOMIC_INT8_FETCH_AND_ADD_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT8_FETCH_AND_ADD_IS_WAIT_FREE -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} +#define Q_ATOMIC_INT16_IS_SUPPORTED -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} +#define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_WAIT_FREE -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} +#define Q_ATOMIC_INT16_TEST_AND_SET_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT16_TEST_AND_SET_IS_WAIT_FREE -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} +#define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_WAIT_FREE -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} +#define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_WAIT_FREE -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd) +template <> struct QBasicAtomicOps<8>: QGenericAtomicOps<QBasicAtomicOps<8> > { - return fetchAndAddOrdered(valueToAdd); -} + static inline bool isTestAndSetNative() { return true; } + static inline bool isTestAndSetWaitFree() { return true; } + template <typename T> static inline + bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) + { +#ifdef __PIC__ +# define EBX_reg "r" +# define EBX_load(reg) "xchg " reg ", %%ebx\n" +#else +# define EBX_reg "b" +# define EBX_load(reg) +#endif + unsigned char ret; + asm volatile(EBX_load("%3") + "lock\n" + "cmpxchg8b %0\n" + EBX_load("%3") + "sete %1\n" + : "+m" (_q_value), "=qm" (ret), + "+A" (expectedValue) + : EBX_reg (quint32(newValue & 0xffffffff)), "c" (quint32(newValue >> 32)) + : "memory"); + return ret != 0; +#undef EBX_reg +#undef EBX_load + } +}; +#define Q_ATOMIC_INT64_IS_SUPPORTED + +#define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_NOT_NATIVE + +#define Q_ATOMIC_INT64_TEST_AND_SET_IS_NOT_NATIVE +#define Q_ATOMIC_INT64_TEST_AND_SET_IS_WAIT_FREE + +#define Q_ATOMIC_INT64_FETCH_AND_STORE_IS_NATIVE + +#define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_NOT_NATIVE -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} +#else +# error "This compiler for i386 is not supported" +#endif QT_END_NAMESPACE QT_END_HEADER diff --git a/src/corelib/arch/qatomic_ia64.h b/src/corelib/arch/qatomic_ia64.h index 0782ab3f36..b5cd9f7545 100644 --- a/src/corelib/arch/qatomic_ia64.h +++ b/src/corelib/arch/qatomic_ia64.h @@ -1,8 +1,8 @@ /**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) +** Copyright (C) 2011 Thiago Macieira <thiago@kde.org> +** Contact: http://www.qt-project.org/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** @@ -35,6 +35,7 @@ ** ** ** +** ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -42,69 +43,147 @@ #ifndef QATOMIC_IA64_H #define QATOMIC_IA64_H +#include <QtCore/qgenericatomic.h> + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE +#if 0 +#pragma qt_sync_stop_processing +#endif + #define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE #define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_WAIT_FREE -inline bool QBasicAtomicInt::isReferenceCountingNative() -{ return true; } -inline bool QBasicAtomicInt::isReferenceCountingWaitFree() -{ return true; } - #define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE #define Q_ATOMIC_INT_TEST_AND_SET_IS_WAIT_FREE -inline bool QBasicAtomicInt::isTestAndSetNative() -{ return true; } -inline bool QBasicAtomicInt::isTestAndSetWaitFree() -{ return true; } - #define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE #define Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE -inline bool QBasicAtomicInt::isFetchAndStoreNative() -{ return true; } -inline bool QBasicAtomicInt::isFetchAndStoreWaitFree() -{ return true; } - #define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE -inline bool QBasicAtomicInt::isFetchAndAddNative() -{ return true; } -inline bool QBasicAtomicInt::isFetchAndAddWaitFree() -{ return false; } +#define Q_ATOMIC_INT32_IS_SUPPORTED + +#define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_WAIT_FREE + +#define Q_ATOMIC_INT32_TEST_AND_SET_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT32_TEST_AND_SET_IS_WAIT_FREE + +#define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_WAIT_FREE + +#define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_ALWAYS_NATIVE #define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE #define Q_ATOMIC_POINTER_TEST_AND_SET_IS_WAIT_FREE -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree() -{ return true; } - #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree() -{ return true; } - #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree() -{ return false; } +#define Q_ATOMIC_INT8_IS_SUPPORTED + +#define Q_ATOMIC_INT8_REFERENCE_COUNTING_IS_ALWAYS_NATIVE + +#define Q_ATOMIC_INT8_TEST_AND_SET_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT8_TEST_AND_SET_IS_WAIT_FREE + +#define Q_ATOMIC_INT8_FETCH_AND_STORE_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT8_FETCH_AND_STORE_IS_WAIT_FREE + +#define Q_ATOMIC_INT8_FETCH_AND_ADD_IS_ALWAYS_NATIVE + +#define Q_ATOMIC_INT16_IS_SUPPORTED + +#define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_ALWAYS_NATIVE + +#define Q_ATOMIC_INT16_TEST_AND_SET_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT16_TEST_AND_SET_IS_WAIT_FREE + +#define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_WAIT_FREE + +#define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_ALWAYS_NATIVE + +#define Q_ATOMIC_INT64_IS_SUPPORTED + +#define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_WAIT_FREE + +#define Q_ATOMIC_INT64_TEST_AND_SET_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT64_TEST_AND_SET_IS_WAIT_FREE + +#define Q_ATOMIC_INT64_FETCH_AND_STORE_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT64_FETCH_AND_STORE_IS_WAIT_FREE + +#define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_ALWAYS_NATIVE + +template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned int> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<char> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<signed char> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned char> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<short> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned short> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<long> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned long> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<long long> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned long long> { enum { IsInteger = 1 }; }; + +template <int size> struct QBasicAtomicOps: QGenericAtomicOps<QBasicAtomicOps<size> > +{ + static void orderedMemoryFence(); + + template <typename T> static inline + T loadAcquire(T &_q_value) + { + return *static_cast<volatile T *>(&_q_value); + } + + template <typename T> static inline + void storeRelease(T &_q_value, T newValue) + { + *static_cast<volatile T *>(&_q_value) = newValue; + } + static inline bool isReferenceCountingNative() { return true; } + static inline bool isReferenceCountingWaitFree() { return size == 4 || size == 8; } + template <typename T> static bool ref(T &_q_value); + template <typename T> static bool deref(T &_q_value); + + static inline bool isTestAndSetNative() { return true; } + static inline bool isTestAndSetWaitFree() { return true; } + template <typename T> static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue); + template <typename T> static bool testAndSetAcquire(T &_q_value, T expectedValue, T newValue); + template <typename T> static bool testAndSetRelease(T &_q_value, T expectedValue, T newValue); + template <typename T> static bool testAndSetOrdered(T &_q_value, T expectedValue, T newValue); + + static inline bool isFetchAndStoreNative() { return true; } + static inline bool isFetchAndStoreWaitFree() { return true; } + template <typename T> static T fetchAndStoreRelaxed(T &_q_value, T newValue); + template <typename T> static T fetchAndStoreAcquire(T &_q_value, T newValue); + template <typename T> static T fetchAndStoreRelease(T &_q_value, T newValue); + template <typename T> static T fetchAndStoreOrdered(T &_q_value, T newValue); + + static inline bool isFetchAndAddNative() { return true; } + static inline bool isFetchAndAddWaitFree() { return false; } + template <typename T> static + T fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd); + template <typename T> static + T fetchAndAddAcquire(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd); + template <typename T> static + T fetchAndAddRelease(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd); + template <typename T> static + T fetchAndAddOrdered(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd); +}; + +template <typename T> struct QAtomicOps : QBasicAtomicOps<sizeof(T)> +{ + typedef T Type; +}; inline bool _q_ia64_fetchadd_immediate(register int value) { @@ -119,14 +198,14 @@ inline bool _q_ia64_fetchadd_immediate(register int value) // intrinsics provided by the Intel C++ Compiler #include <ia64intrin.h> -inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue) +template<int size> inline +void QBasicAtomicOps<size>::orderedMemoryFence() { - return static_cast<int>(_InterlockedExchange(&_q_value, newValue)); + __memory_barrier(); } -inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue) +inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue) { - __memory_barrier(); return static_cast<int>(_InterlockedExchange(&_q_value, newValue)); } @@ -157,12 +236,6 @@ inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue) == expectedValue); } -inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) -{ - __memory_barrier(); - return testAndSetAcquire(expectedValue, newValue); -} - inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd) { if (__builtin_constant_p(valueToAdd)) { @@ -186,12 +259,6 @@ inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd) return _InterlockedExchangeAdd(&_q_value, valueToAdd); } -inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) -{ - __memory_barrier(); - return fetchAndAddAcquire(valueToAdd); -} - inline bool QBasicAtomicInt::ref() { return _InterlockedIncrement(&_q_value) != 0; @@ -209,13 +276,6 @@ Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue) } template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue) -{ - __memory_barrier(); - return fetchAndStoreAcquire(newValue); -} - -template <typename T> Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue) { register T *expectedValueCopy = expectedValue; @@ -252,13 +312,6 @@ Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValu } template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue) -{ - __memory_barrier(); - return testAndSetAcquire(expectedValue, newValue); -} - -template <typename T> Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd) { return (T *)_InterlockedExchangeAdd64((volatile long *)&_q_value, @@ -273,41 +326,114 @@ Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueTo valueToAdd * sizeof(T)); } -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd) +#elif defined(Q_CC_GNU) + +template<int size> inline +void QBasicAtomicOps<size>::orderedMemoryFence() { - __memory_barrier(); - return fetchAndAddAcquire(valueToAdd); + asm volatile("mf" ::: "memory"); } -#else // !Q_CC_INTEL +template<> template<typename T> inline +bool QBasicAtomicOps<4>::ref(T &_q_value) +{ + T ret; + asm volatile("fetchadd4.acq %0=%1,1\n" + : "=r" (ret), "+m" (_q_value) + : + : "memory"); + return ret != -1; +} -# if defined(Q_CC_GNU) +template<> template<typename T> inline +bool QBasicAtomicOps<4>::deref(T &_q_value) +{ + T ret; + asm volatile("fetchadd4.rel %0=%1,-1\n" + : "=r" (ret), "+m" (_q_value) + : + : "memory"); + return ret != 1; +} -inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue) +template<> template<typename T> inline +bool QBasicAtomicOps<8>::ref(T &_q_value) { - int ret; - asm volatile("xchg4 %0=%1,%2\n" + T ret; + asm volatile("fetchadd8.acq %0=%1,1\n" : "=r" (ret), "+m" (_q_value) - : "r" (newValue) + : : "memory"); - return ret; + return ret != -1; } -inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue) +template<> template<typename T> inline +bool QBasicAtomicOps<8>::deref(T &_q_value) { - int ret; - asm volatile("mf\n" - "xchg4 %0=%1,%2\n" + T ret; + asm volatile("fetchadd8.rel %0=%1,-1\n" : "=r" (ret), "+m" (_q_value) - : "r" (newValue) + : : "memory"); - return ret; + return ret != 1; } -inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue) +template<> template <typename T> inline +bool QBasicAtomicOps<1>::testAndSetAcquire(T &_q_value, T expectedValue, T newValue) +{ + T ret; + asm volatile("mov ar.ccv=%2\n" + ";;\n" + "cmpxchg1.acq %0=%1,%3,ar.ccv\n" + : "=r" (ret), "+m" (_q_value) + : "r" (expectedValue), "r" (newValue) + : "memory"); + return ret == expectedValue; +} + +template<> template <typename T> inline +bool QBasicAtomicOps<1>::testAndSetRelease(T &_q_value, T expectedValue, T newValue) +{ + T ret; + asm volatile("mov ar.ccv=%2\n" + ";;\n" + "cmpxchg1.rel %0=%1,%3,ar.ccv\n" + : "=r" (ret), "+m" (_q_value) + : "r" (expectedValue), "r" (newValue) + : "memory"); + return ret == expectedValue; +} + +template<> template <typename T> inline +bool QBasicAtomicOps<2>::testAndSetAcquire(T &_q_value, T expectedValue, T newValue) +{ + T ret; + asm volatile("mov ar.ccv=%2\n" + ";;\n" + "cmpxchg2.acq %0=%1,%3,ar.ccv\n" + : "=r" (ret), "+m" (_q_value) + : "r" (expectedValue), "r" (newValue) + : "memory"); + return ret == expectedValue; +} + +template<> template <typename T> inline +bool QBasicAtomicOps<2>::testAndSetRelease(T &_q_value, T expectedValue, T newValue) { - int ret; + T ret; + asm volatile("mov ar.ccv=%2\n" + ";;\n" + "cmpxchg2.rel %0=%1,%3,ar.ccv\n" + : "=r" (ret), "+m" (_q_value) + : "r" (expectedValue), "r" (newValue) + : "memory"); + return ret == expectedValue; +} + +template<> template <typename T> inline +bool QBasicAtomicOps<4>::testAndSetAcquire(T &_q_value, T expectedValue, T newValue) +{ + T ret; asm volatile("mov ar.ccv=%2\n" ";;\n" "cmpxchg4.acq %0=%1,%3,ar.ccv\n" @@ -317,9 +443,10 @@ inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue) return ret == expectedValue; } -inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue) +template<> template <typename T> inline +bool QBasicAtomicOps<4>::testAndSetRelease(T &_q_value, T expectedValue, T newValue) { - int ret; + T ret; asm volatile("mov ar.ccv=%2\n" ";;\n" "cmpxchg4.rel %0=%1,%3,ar.ccv\n" @@ -329,9 +456,173 @@ inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue) return ret == expectedValue; } -inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd) +template<> template <typename T> inline +bool QBasicAtomicOps<8>::testAndSetAcquire(T &_q_value, T expectedValue, T newValue) +{ + T ret; + asm volatile("mov ar.ccv=%2\n" + ";;\n" + "cmpxchg8.acq %0=%1,%3,ar.ccv\n" + : "=r" (ret), "+m" (_q_value) + : "r" (expectedValue), "r" (newValue) + : "memory"); + return ret == expectedValue; +} + +template<> template <typename T> inline +bool QBasicAtomicOps<8>::testAndSetRelease(T &_q_value, T expectedValue, T newValue) +{ + T ret; + asm volatile("mov ar.ccv=%2\n" + ";;\n" + "cmpxchg8.rel %0=%1,%3,ar.ccv\n" + : "=r" (ret), "+m" (_q_value) + : "r" (expectedValue), "r" (newValue) + : "memory"); + return ret == expectedValue; +} + +template<> template <typename T> inline +T QBasicAtomicOps<1>::fetchAndStoreAcquire(T &_q_value, T newValue) +{ + T ret; + asm volatile("xchg1 %0=%1,%2\n" + : "=r" (ret), "+m" (_q_value) + : "r" (newValue) + : "memory"); + return ret; +} + +template<> template <typename T> inline +T QBasicAtomicOps<2>::fetchAndStoreAcquire(T &_q_value, T newValue) +{ + T ret; + asm volatile("xchg2 %0=%1,%2\n" + : "=r" (ret), "+m" (_q_value) + : "r" (newValue) + : "memory"); + return ret; +} + +template<> template <typename T> inline +T QBasicAtomicOps<4>::fetchAndStoreAcquire(T &_q_value, T newValue) +{ + T ret; + asm volatile("xchg4 %0=%1,%2\n" + : "=r" (ret), "+m" (_q_value) + : "r" (newValue) + : "memory"); + return ret; +} + +template<> template <typename T> inline +T QBasicAtomicOps<8>::fetchAndStoreAcquire(T &_q_value, T newValue) +{ + T ret; + asm volatile("xchg8 %0=%1,%2\n" + : "=r" (ret), "+m" (_q_value) + : "r" (newValue) + : "memory"); + return ret; +} + +template<> template <typename T> inline +T QBasicAtomicOps<1>::fetchAndAddAcquire(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) +{ + T ret; + valueToAdd *= QAtomicAdditiveType<T>::AddScale; + + ret = _q_value; + asm volatile("0:\n" + " mov r9=%0\n" + " mov ar.ccv=%0\n" + " add %0=%0, %2\n" + " ;;\n" + " cmpxchg1.acq %0=%1,%0,ar.ccv\n" + " ;;\n" + " cmp.ne p6,p0 = %0, r9\n" + "(p6) br.dptk 0b\n" + "1:\n" + : "+r" (ret), "+m" (_q_value) + : "r" (valueToAdd) + : "r9", "p6", "memory"); + return ret; +} + +template<> template <typename T> inline +T QBasicAtomicOps<1>::fetchAndAddRelease(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) +{ + T ret; + valueToAdd *= QAtomicAdditiveType<T>::AddScale; + + ret = _q_value; + asm volatile("0:\n" + " mov r9=%0\n" + " mov ar.ccv=%0\n" + " add %0=%0, %2\n" + " ;;\n" + " cmpxchg1.rel %0=%1,%0,ar.ccv\n" + " ;;\n" + " cmp.ne p6,p0 = %0, r9\n" + "(p6) br.dptk 0b\n" + "1:\n" + : "+r" (ret), "+m" (_q_value) + : "r" (valueToAdd) + : "r9", "p6", "memory"); + return ret; +} + +template<> template <typename T> inline +T QBasicAtomicOps<2>::fetchAndAddAcquire(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) +{ + T ret; + valueToAdd *= QAtomicAdditiveType<T>::AddScale; + + ret = _q_value; + asm volatile("0:\n" + " mov r9=%0\n" + " mov ar.ccv=%0\n" + " add %0=%0, %2\n" + " ;;\n" + " cmpxchg2.acq %0=%1,%0,ar.ccv\n" + " ;;\n" + " cmp.ne p6,p0 = %0, r9\n" + "(p6) br.dptk 0b\n" + "1:\n" + : "+r" (ret), "+m" (_q_value) + : "r" (valueToAdd) + : "r9", "p6", "memory"); + return ret; +} + +template<> template <typename T> inline +T QBasicAtomicOps<2>::fetchAndAddRelease(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) +{ + T ret; + valueToAdd *= QAtomicAdditiveType<T>::AddScale; + + ret = _q_value; + asm volatile("0:\n" + " mov r9=%0\n" + " mov ar.ccv=%0\n" + " add %0=%0, %2\n" + " ;;\n" + " cmpxchg2.rel %0=%1,%0,ar.ccv\n" + " ;;\n" + " cmp.ne p6,p0 = %0, r9\n" + "(p6) br.dptk 0b\n" + "1:\n" + : "+r" (ret), "+m" (_q_value) + : "r" (valueToAdd) + : "r9", "p6", "memory"); + return ret; +} + +template<> template <typename T> inline +T QBasicAtomicOps<4>::fetchAndAddAcquire(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) { - int ret; + T ret; + valueToAdd *= QAtomicAdditiveType<T>::AddScale; #if (__GNUC__ >= 4) // We implement a fast fetch-and-add when we can @@ -362,9 +653,11 @@ inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd) return ret; } -inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd) +template<> template <typename T> inline +T QBasicAtomicOps<4>::fetchAndAddRelease(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) { - int ret; + T ret; + valueToAdd *= QAtomicAdditiveType<T>::AddScale; #if (__GNUC__ >= 4) // We implement a fast fetch-and-add when we can @@ -395,92 +688,18 @@ inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd) return ret; } -inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) -{ - asm volatile("mf" ::: "memory"); - return fetchAndAddRelease(valueToAdd); -} - -inline bool QBasicAtomicInt::ref() -{ - int ret; - asm volatile("fetchadd4.acq %0=%1,1\n" - : "=r" (ret), "+m" (_q_value) - : - : "memory"); - return ret != -1; -} - -inline bool QBasicAtomicInt::deref() -{ - int ret; - asm volatile("fetchadd4.rel %0=%1,-1\n" - : "=r" (ret), "+m" (_q_value) - : - : "memory"); - return ret != 1; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue) -{ - T *ret; - asm volatile("xchg8 %0=%1,%2\n" - : "=r" (ret), "+m" (_q_value) - : "r" (newValue) - : "memory"); - return ret; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue) +template<> template <typename T> inline +T QBasicAtomicOps<8>::fetchAndAddAcquire(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) { - T *ret; - asm volatile("mf\n" - "xchg8 %0=%1,%2\n" - : "=r" (ret), "+m" (_q_value) - : "r" (newValue) - : "memory"); - return ret; -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue) -{ - T *ret; - asm volatile("mov ar.ccv=%2\n" - ";;\n" - "cmpxchg8.acq %0=%1,%3,ar.ccv\n" - : "=r" (ret), "+m" (_q_value) - : "r" (expectedValue), "r" (newValue) - : "memory"); - return ret == expectedValue; -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue) -{ - T *ret; - asm volatile("mov ar.ccv=%2\n" - ";;\n" - "cmpxchg8.rel %0=%1,%3,ar.ccv\n" - : "=r" (ret), "+m" (_q_value) - : "r" (expectedValue), "r" (newValue) - : "memory"); - return ret == expectedValue; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd) -{ - T *ret; + T ret; + valueToAdd *= QAtomicAdditiveType<T>::AddScale; #if (__GNUC__ >= 4) // We implement a fast fetch-and-add when we can - if (__builtin_constant_p(valueToAdd) && _q_ia64_fetchadd_immediate(valueToAdd * sizeof(T))) { + if (__builtin_constant_p(valueToAdd) && _q_ia64_fetchadd_immediate(valueToAdd)) { asm volatile("fetchadd8.acq %0=%1,%2\n" : "=r" (ret), "+m" (_q_value) - : "i" (valueToAdd * sizeof(T)) + : "i" (valueToAdd) : "memory"); return ret; } @@ -499,22 +718,23 @@ Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueTo "(p6) br.dptk 0b\n" "1:\n" : "+r" (ret), "+m" (_q_value) - : "r" (valueToAdd * sizeof(T)) + : "r" (valueToAdd) : "r9", "p6", "memory"); return ret; } -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd) +template<> template <typename T> inline +T QBasicAtomicOps<8>::fetchAndAddRelease(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) { - T *ret; + T ret; + valueToAdd *= QAtomicAdditiveType<T>::AddScale; #if (__GNUC__ >= 4) // We implement a fast fetch-and-add when we can - if (__builtin_constant_p(valueToAdd) && _q_ia64_fetchadd_immediate(valueToAdd * sizeof(T))) { + if (__builtin_constant_p(valueToAdd) && _q_ia64_fetchadd_immediate(valueToAdd)) { asm volatile("fetchadd8.rel %0=%1,%2\n" : "=r" (ret), "+m" (_q_value) - : "i" (valueToAdd * sizeof(T)) + : "i" (valueToAdd) : "memory"); return ret; } @@ -533,18 +753,11 @@ Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueTo "(p6) br.dptk 0b\n" "1:\n" : "+r" (ret), "+m" (_q_value) - : "r" (valueToAdd * sizeof(T)) + : "r" (valueToAdd) : "r9", "p6", "memory"); return ret; } -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd) -{ - asm volatile("mf" ::: "memory"); - return fetchAndAddRelease(valueToAdd); -} - #elif defined Q_CC_HPACC QT_BEGIN_INCLUDE_NAMESPACE @@ -553,257 +766,315 @@ QT_END_INCLUDE_NAMESPACE #define FENCE (_Asm_fence)(_UP_CALL_FENCE | _UP_SYS_FENCE | _DOWN_CALL_FENCE | _DOWN_SYS_FENCE) -inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue) +template <int size> inline +void QBasicAtomicOps<size>::orderedMemoryFence() { - return _Asm_xchg((_Asm_sz)_SZ_W, &_q_value, (unsigned)newValue, - (_Asm_ldhint)_LDHINT_NONE, FENCE); + _Asm_mf(FENCE); } -inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue) +template<> template<typename T> inline +bool QBasicAtomicOps<4>::ref(T &_q_value) { - _Asm_mf(FENCE); - return _Asm_xchg((_Asm_sz)_SZ_W, &_q_value, (unsigned)newValue, - (_Asm_ldhint)_LDHINT_NONE, FENCE); + return (T)_Asm_fetchadd((_Asm_fasz)_FASZ_W, (_Asm_sem)_SEM_ACQ, + &_q_value, 1, (_Asm_ldhint)_LDHINT_NONE, FENCE) != -1; } -inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue) +template<> template<typename T> inline +bool QBasicAtomicOps<4>::deref(T &_q_value) { - _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (unsigned)expectedValue, FENCE); - int ret = _Asm_cmpxchg((_Asm_sz)_SZ_W, (_Asm_sem)_SEM_ACQ, - &_q_value, (unsigned)newValue, (_Asm_ldhint)_LDHINT_NONE); - return ret == expectedValue; + return (T)_Asm_fetchadd((_Asm_fasz)_FASZ_W, (_Asm_sem)_SEM_REL, + &_q_value, -1, (_Asm_ldhint)_LDHINT_NONE, FENCE) != 1; } -inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue) +template<> template<typename T> inline +bool QBasicAtomicOps<8>::ref(T &_q_value) { - _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (unsigned)expectedValue, FENCE); - int ret = _Asm_cmpxchg((_Asm_sz)_SZ_W, (_Asm_sem)_SEM_REL, - &_q_value, newValue, (_Asm_ldhint)_LDHINT_NONE); - return ret == expectedValue; + return (T)_Asm_fetchadd((_Asm_fasz)_FASZ_D, (_Asm_sem)_SEM_ACQ, + &_q_value, 1, (_Asm_ldhint)_LDHINT_NONE, FENCE) != -1; } -inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd) +template<> template<typename T> inline +bool QBasicAtomicOps<8>::deref(T &_q_value) { - if (valueToAdd == 1) - return _Asm_fetchadd((_Asm_fasz)_FASZ_W, (_Asm_sem)_SEM_ACQ, - &_q_value, 1, (_Asm_ldhint)_LDHINT_NONE, FENCE); - else if (valueToAdd == -1) - return _Asm_fetchadd((_Asm_fasz)_FASZ_W, (_Asm_sem)_SEM_ACQ, - &_q_value, -1, (_Asm_ldhint)_LDHINT_NONE, FENCE); - - // implement the test-and-set loop - register int old, ret; - do { - old = _q_value; - _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (unsigned)old, FENCE); - ret = _Asm_cmpxchg((_Asm_sz)_SZ_W, (_Asm_sem)_SEM_ACQ, - &_q_value, old + valueToAdd, (_Asm_ldhint)_LDHINT_NONE); - } while (ret != old); - return old; + return (T)_Asm_fetchadd((_Asm_fasz)_FASZ_D, (_Asm_sem)_SEM_REL, + &_q_value, -1, (_Asm_ldhint)_LDHINT_NONE, FENCE) != 1; } -inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd) +template<> template <typename T> inline +bool QBasicAtomicOps<1>::testAndSetAcquire(T &_q_value, T expectedValue, T newValue) { - if (valueToAdd == 1) - return _Asm_fetchadd((_Asm_fasz)_FASZ_W, (_Asm_sem)_SEM_REL, - &_q_value, 1, (_Asm_ldhint)_LDHINT_NONE, FENCE); - else if (valueToAdd == -1) - return _Asm_fetchadd((_Asm_fasz)_FASZ_W, (_Asm_sem)_SEM_REL, - &_q_value, -1, (_Asm_ldhint)_LDHINT_NONE, FENCE); - - // implement the test-and-set loop - register int old, ret; - do { - old = _q_value; - _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (unsigned)old, FENCE); - ret = _Asm_cmpxchg((_Asm_sz)_SZ_W, (_Asm_sem)_SEM_REL, - &_q_value, old + valueToAdd, (_Asm_ldhint)_LDHINT_NONE); - } while (ret != old); - return old; + _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint8)expectedValue, FENCE); + T ret = (T)_Asm_cmpxchg((_Asm_sz)_SZ_B, (_Asm_sem)_SEM_ACQ, + &_q_value, (quint8)newValue, (_Asm_ldhint)_LDHINT_NONE); + return ret == expectedValue; } -inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) +template<> template <typename T> inline +bool QBasicAtomicOps<1>::testAndSetRelease(T &_q_value, T expectedValue, T newValue) { - _Asm_mf(FENCE); - return fetchAndAddAcquire(valueToAdd); + _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint8)expectedValue, FENCE); + T ret = (T)_Asm_cmpxchg((_Asm_sz)_SZ_B, (_Asm_sem)_SEM_REL, + &_q_value, (quint8)newValue, (_Asm_ldhint)_LDHINT_NONE); + return ret == expectedValue; } -inline bool QBasicAtomicInt::ref() +template<> template <typename T> inline +bool QBasicAtomicOps<2>::testAndSetAcquire(T &_q_value, T expectedValue, T newValue) { - return (int)_Asm_fetchadd((_Asm_fasz)_FASZ_W, (_Asm_sem)_SEM_ACQ, - &_q_value, 1, (_Asm_ldhint)_LDHINT_NONE, FENCE) != -1; + _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint16)expectedValue, FENCE); + T ret = (T)_Asm_cmpxchg((_Asm_sz)_SZ_H, (_Asm_sem)_SEM_ACQ, + &_q_value, (quint16)newValue, (_Asm_ldhint)_LDHINT_NONE); + return ret == expectedValue; } -inline bool QBasicAtomicInt::deref() +template<> template <typename T> inline +bool QBasicAtomicOps<2>::testAndSetRelease(T &_q_value, T expectedValue, T newValue) { - return (int)_Asm_fetchadd((_Asm_fasz)_FASZ_W, (_Asm_sem)_SEM_REL, - &_q_value, -1, (_Asm_ldhint)_LDHINT_NONE, FENCE) != 1; + _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint16)expectedValue, FENCE); + T ret = (T)_Asm_cmpxchg((_Asm_sz)_SZ_H, (_Asm_sem)_SEM_REL, + &_q_value, (quint16)newValue, (_Asm_ldhint)_LDHINT_NONE); + return ret == expectedValue; } -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue) +template<> template <typename T> inline +bool QBasicAtomicOps<4>::testAndSetAcquire(T &_q_value, T expectedValue, T newValue) { -#ifdef __LP64__ - return (T *)_Asm_xchg((_Asm_sz)_SZ_D, &_q_value, (quint64)newValue, - (_Asm_ldhint)_LDHINT_NONE, FENCE); -#else - return (T *)_Asm_xchg((_Asm_sz)_SZ_W, &_q_value, (quint32)newValue, - (_Asm_ldhint)_LDHINT_NONE, FENCE); -#endif + _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (unsigned)expectedValue, FENCE); + T ret = (T)_Asm_cmpxchg((_Asm_sz)_SZ_W, (_Asm_sem)_SEM_ACQ, + &_q_value, (unsigned)newValue, (_Asm_ldhint)_LDHINT_NONE); + return ret == expectedValue; } -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue) +template<> template <typename T> inline +bool QBasicAtomicOps<4>::testAndSetRelease(T &_q_value, T expectedValue, T newValue) { - _Asm_mf(FENCE); - return fetchAndStoreAcquire(newValue); + _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (unsigned)expectedValue, FENCE); + T ret = (T)_Asm_cmpxchg((_Asm_sz)_SZ_W, (_Asm_sem)_SEM_REL, + &_q_value, newValue, (_Asm_ldhint)_LDHINT_NONE); + return ret == expectedValue; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue) +template<> template <typename T> inline +bool QBasicAtomicOps<8>::testAndSetAcquire(T &_q_value, T expectedValue, T newValue) { -#ifdef __LP64__ _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint64)expectedValue, FENCE); - T *ret = (T *)_Asm_cmpxchg((_Asm_sz)_SZ_D, (_Asm_sem)_SEM_ACQ, - &_q_value, (quint64)newValue, (_Asm_ldhint)_LDHINT_NONE); -#else - _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint32)expectedValue, FENCE); - T *ret = (T *)_Asm_cmpxchg((_Asm_sz)_SZ_W, (_Asm_sem)_SEM_ACQ, - &_q_value, (quint32)newValue, (_Asm_ldhint)_LDHINT_NONE); -#endif + T ret = (T)_Asm_cmpxchg((_Asm_sz)_SZ_D, (_Asm_sem)_SEM_ACQ, + &_q_value, (quint64)newValue, (_Asm_ldhint)_LDHINT_NONE); return ret == expectedValue; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue) +template<> template <typename T> inline +bool QBasicAtomicOps<8>::testAndSetRelease(T &_q_value, T expectedValue, T newValue) { -#ifdef __LP64__ _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint64)expectedValue, FENCE); - T *ret = (T *)_Asm_cmpxchg((_Asm_sz)_SZ_D, (_Asm_sem)_SEM_REL, - &_q_value, (quint64)newValue, (_Asm_ldhint)_LDHINT_NONE); -#else - _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint32)expectedValue, FENCE); - T *ret = (T *)_Asm_cmpxchg((_Asm_sz)_SZ_W, (_Asm_sem)_SEM_REL, - &_q_value, (quint32)newValue, (_Asm_ldhint)_LDHINT_NONE); -#endif + T ret = (T)_Asm_cmpxchg((_Asm_sz)_SZ_D, (_Asm_sem)_SEM_REL, + &_q_value, (quint64)newValue, (_Asm_ldhint)_LDHINT_NONE); return ret == expectedValue; } -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd) +template<> template <typename T> inline +T QBasicAtomicOps<1>::fetchAndStoreAcquire(T &_q_value, T newValue) +{ + return (T)_Asm_xchg((_Asm_sz)_SZ_B, &_q_value, (quint8)newValue, + (_Asm_ldhint)_LDHINT_NONE, FENCE); +} + +template<> template <typename T> inline +T QBasicAtomicOps<2>::fetchAndStoreAcquire(T &_q_value, T newValue) +{ + return (T)_Asm_xchg((_Asm_sz)_SZ_H, &_q_value, (quint16)newValue, + (_Asm_ldhint)_LDHINT_NONE, FENCE); +} + +template<> template <typename T> inline +T QBasicAtomicOps<4>::fetchAndStoreAcquire(T &_q_value, T newValue) +{ + return (T)_Asm_xchg((_Asm_sz)_SZ_W, &_q_value, (unsigned)newValue, + (_Asm_ldhint)_LDHINT_NONE, FENCE); +} + +template<> template <typename T> inline +T QBasicAtomicOps<8>::fetchAndStoreAcquire(T &_q_value, T newValue) +{ + return (T)_Asm_xchg((_Asm_sz)_SZ_D, &_q_value, (quint64)newValue, + (_Asm_ldhint)_LDHINT_NONE, FENCE); +} + +template<> template <typename T> inline +T QBasicAtomicOps<1>::fetchAndAddAcquire(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) { + valueToAdd *= QAtomicAdditiveType<T>::AddScale; // implement the test-and-set loop - register T *old, *ret; + register T old, ret; do { old = _q_value; -#ifdef __LP64__ - _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint64)old, FENCE); - ret = (T *)_Asm_cmpxchg((_Asm_sz)_SZ_D, (_Asm_sem)_SEM_ACQ, - &_q_value, (quint64)(old + valueToAdd), - (_Asm_ldhint)_LDHINT_NONE); -#else - _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint32)old, FENCE); - ret = (T *)_Asm_cmpxchg((_Asm_sz)_SZ_W, (_Asm_sem)_SEM_ACQ, - &_q_value, (quint32)(old + valueToAdd), - (_Asm_ldhint)_LDHINT_NONE); -#endif - } while (old != ret); + _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint8)old, FENCE); + ret = _Asm_cmpxchg((_Asm_sz)_SZ_B, (_Asm_sem)_SEM_ACQ, + &_q_value, old + valueToAdd, (_Asm_ldhint)_LDHINT_NONE); + } while (ret != old); return old; } -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd) +template<> template <typename T> inline +T QBasicAtomicOps<1>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) { // implement the test-and-set loop - register T *old, *ret; + register T old, ret; do { old = _q_value; -#ifdef __LP64__ - _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint64)old, FENCE); - ret = (T *)_Asm_cmpxchg((_Asm_sz)_SZ_D, (_Asm_sem)_SEM_REL, - &_q_value, (quint64)(old + valueToAdd), - (_Asm_ldhint)_LDHINT_NONE); -#else - _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint32)old, FENCE); - ret = (T *)_Asm_cmpxchg((_Asm_sz)_SZ_W, (_Asm_sem)_SEM_REL, - &_q_value, (quint32)(old + valueToAdd), - (_Asm_ldhint)_LDHINT_NONE); -#endif - } while (old != ret); + _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint8)old, FENCE); + ret = _Asm_cmpxchg((_Asm_sz)_SZ_B, (_Asm_sem)_SEM_REL, + &_q_value, old + valueToAdd, (_Asm_ldhint)_LDHINT_NONE); + } while (ret != old); return old; } -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd) +template<> template <typename T> inline +T QBasicAtomicOps<2>::fetchAndAddAcquire(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) { - _Asm_mf(FENCE); - return fetchAndAddAcquire(valueToAdd); + valueToAdd *= QAtomicAdditiveType<T>::AddScale; + // implement the test-and-set loop + register T old, ret; + do { + old = _q_value; + _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint16)old, FENCE); + ret = _Asm_cmpxchg((_Asm_sz)_SZ_H, (_Asm_sem)_SEM_ACQ, + &_q_value, old + valueToAdd, (_Asm_ldhint)_LDHINT_NONE); + } while (ret != old); + return old; } -#else +template<> template <typename T> inline +T QBasicAtomicOps<2>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) +{ + // implement the test-and-set loop + register T old, ret; + do { + old = _q_value; + _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint16)old, FENCE); + ret = _Asm_cmpxchg((_Asm_sz)_SZ_H, (_Asm_sem)_SEM_REL, + &_q_value, old + valueToAdd, (_Asm_ldhint)_LDHINT_NONE); + } while (ret != old); + return old; +} -extern "C" { - Q_CORE_EXPORT int q_atomic_test_and_set_int(volatile int *ptr, int expected, int newval); - Q_CORE_EXPORT int q_atomic_test_and_set_ptr(volatile void *ptr, void *expected, void *newval); -} // extern "C" +template<> template <typename T> inline +T QBasicAtomicOps<4>::fetchAndAddAcquire(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) +{ + valueToAdd *= QAtomicAdditiveType<T>::AddScale; + // implement the test-and-set loop + register T old, ret; + do { + old = _q_value; + _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (unsigned)old, FENCE); + ret = _Asm_cmpxchg((_Asm_sz)_SZ_W, (_Asm_sem)_SEM_ACQ, + &_q_value, old + valueToAdd, (_Asm_ldhint)_LDHINT_NONE); + } while (ret != old); + return old; +} -#endif +template<> template <typename T> inline +T QBasicAtomicOps<4>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) +{ + // implement the test-and-set loop + register T old, ret; + do { + old = _q_value; + _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (unsigned)old, FENCE); + ret = _Asm_cmpxchg((_Asm_sz)_SZ_W, (_Asm_sem)_SEM_REL, + &_q_value, old + valueToAdd, (_Asm_ldhint)_LDHINT_NONE); + } while (ret != old); + return old; +} -inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) +template<> template <typename T> inline +T QBasicAtomicOps<8>::fetchAndAddAcquire(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) { - return testAndSetAcquire(expectedValue, newValue); + valueToAdd *= QAtomicAdditiveType<T>::AddScale; + // implement the test-and-set loop + register T old, ret; + do { + old = _q_value; + _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint64)old, FENCE); + ret = _Asm_cmpxchg((_Asm_sz)_SZ_D, (_Asm_sem)_SEM_ACQ, + &_q_value, old + valueToAdd, (_Asm_ldhint)_LDHINT_NONE); + } while (ret != old); + return old; } -inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) +template<> template <typename T> inline +T QBasicAtomicOps<8>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) { - return testAndSetAcquire(expectedValue, newValue); + // implement the test-and-set loop + register T old, ret; + do { + old = _q_value; + _Asm_mov_to_ar((_Asm_app_reg)_AREG_CCV, (quint64)old, FENCE); + ret = _Asm_cmpxchg((_Asm_sz)_SZ_D, (_Asm_sem)_SEM_REL, + &_q_value, old + valueToAdd, (_Asm_ldhint)_LDHINT_NONE); + } while (ret != old); + return old; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue) +#endif + +template<int size> template<typename T> inline +bool QBasicAtomicOps<size>::ref(T &_q_value) { - return testAndSetAcquire(expectedValue, newValue); + // no fetchadd for 1 or 2 bytes + return fetchAndAddRelaxed(_q_value, 1) == -1; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue) +template<int size> template<typename T> inline +bool QBasicAtomicOps<size>::deref(T &_q_value) { - return testAndSetAcquire(expectedValue, newValue); + // no fetchadd for 1 or 2 bytes + return fetchAndAddRelaxed(_q_value, -1) == 1; } -#endif // Q_CC_INTEL +template<int size> template <typename T> inline +bool QBasicAtomicOps<size>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) +{ + return testAndSetAcquire(_q_value, expectedValue, newValue); +} -inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue) +template<int size> template <typename T> inline +bool QBasicAtomicOps<size>::testAndSetOrdered(T &_q_value, T expectedValue, T newValue) { - return fetchAndStoreAcquire(newValue); + orderedMemoryFence(); + return testAndSetAcquire(_q_value, expectedValue, newValue); } -inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) +template<int size> template <typename T> inline +T QBasicAtomicOps<size>::fetchAndStoreRelaxed(T &_q_value, T newValue) { - return fetchAndStoreRelease(newValue); + return fetchAndStoreAcquire(_q_value, newValue); } -inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd) +template<int size> template <typename T> inline +T QBasicAtomicOps<size>::fetchAndStoreRelease(T &_q_value, T newValue) { - return fetchAndAddAcquire(valueToAdd); + orderedMemoryFence(); + return fetchAndStoreAcquire(_q_value, newValue); } -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue) +template<int size> template <typename T> inline +T QBasicAtomicOps<size>::fetchAndStoreOrdered(T &_q_value, T newValue) { - return fetchAndStoreAcquire(newValue); + return fetchAndStoreRelease(_q_value, newValue); } -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue) +template<int size> template <typename T> inline +T QBasicAtomicOps<size>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) { - return fetchAndStoreRelaxed(newValue); + return fetchAndAddAcquire(_q_value, valueToAdd); } -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd) +template<int size> template <typename T> inline +T QBasicAtomicOps<size>::fetchAndAddOrdered(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) { - return fetchAndAddAcquire(valueToAdd); + orderedMemoryFence(); + return fetchAndAddRelease(_q_value, valueToAdd); } QT_END_NAMESPACE diff --git a/src/corelib/arch/qatomic_integrity.h b/src/corelib/arch/qatomic_integrity.h index e83124bf4e..e5d226ad7f 100644 --- a/src/corelib/arch/qatomic_integrity.h +++ b/src/corelib/arch/qatomic_integrity.h @@ -1,8 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) +** Contact: http://www.qt-project.org/ ** ** This file is part of the QtGui module of the Qt Toolkit. ** @@ -35,6 +34,7 @@ ** ** ** +** ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/corelib/arch/qatomic_macosx.h b/src/corelib/arch/qatomic_macosx.h deleted file mode 100644 index a973fe1b57..0000000000 --- a/src/corelib/arch/qatomic_macosx.h +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 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$ -** 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_MACOSX_H -#define QATOMIC_MACOSX_H - -QT_BEGIN_HEADER - -#if defined(__x86_64__) -# include <QtCore/qatomic_x86_64.h> -#elif defined(__i386__) -# include <QtCore/qatomic_i386.h> -#else // !__x86_64 && !__i386__ -# include <QtCore/qatomic_powerpc.h> -#endif // !__x86_64__ && !__i386__ - -QT_END_HEADER - -#endif // QATOMIC_MACOSX_H diff --git a/src/corelib/arch/qatomic_mips.h b/src/corelib/arch/qatomic_mips.h index 97cef3c457..04015c9d19 100644 --- a/src/corelib/arch/qatomic_mips.h +++ b/src/corelib/arch/qatomic_mips.h @@ -1,8 +1,8 @@ /**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) +** Copyright (C) 2011 Thiago Macieira <thiago@kde.org> +** Contact: http://www.qt-project.org/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** @@ -35,6 +35,7 @@ ** ** ** +** ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -42,107 +43,116 @@ #ifndef QATOMIC_MIPS_H #define QATOMIC_MIPS_H +#include <QtCore/qgenericatomic.h> + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE - -inline bool QBasicAtomicInt::isReferenceCountingNative() -{ return true; } -inline bool QBasicAtomicInt::isReferenceCountingWaitFree() -{ return false; } +#if 0 +#pragma qt_sync_stop_processing +#endif +#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE #define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE - -inline bool QBasicAtomicInt::isTestAndSetNative() -{ return true; } -inline bool QBasicAtomicInt::isTestAndSetWaitFree() -{ return false; } - #define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE - -inline bool QBasicAtomicInt::isFetchAndStoreNative() -{ return true; } -inline bool QBasicAtomicInt::isFetchAndStoreWaitFree() -{ return false; } - #define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE -inline bool QBasicAtomicInt::isFetchAndAddNative() -{ return true; } -inline bool QBasicAtomicInt::isFetchAndAddWaitFree() -{ return false; } +#define Q_ATOMIC_INT32_IS_SUPPORTED +#define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT32_TEST_AND_SET_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_ALWAYS_NATIVE #define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE +#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE +#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree() -{ return false; } +template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned int> { enum { IsInteger = 1 }; }; -#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE +template <int size> struct QBasicAtomicOps: QGenericAtomicOps<QBasicAtomicOps<size> > +{ + static void acquireMemoryFence(); + static void releaseMemoryFence(); + static void orderedMemoryFence(); -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree() -{ return false; } + static inline bool isReferenceCountingNative() { return true; } + template <typename T> static bool ref(T &_q_value); + template <typename T> static bool deref(T &_q_value); -#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE + static inline bool isTestAndSetNative() { return true; } + static inline bool isTestAndSetWaitFree() { return false; } + template <typename T> static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue); -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree() -{ return false; } + static inline bool isFetchAndStoreNative() { return true; } + template <typename T> static T fetchAndStoreRelaxed(T &_q_value, T newValue); -#if defined(Q_CC_GNU) && !defined(Q_OS_IRIX) + static inline bool isFetchAndAddNative() { return true; } + template <typename T> static + T fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd); +}; -#if _MIPS_SIM == _ABIO32 -#define SET_MIPS2 ".set mips2\n\t" -#else -#define SET_MIPS2 +template <typename T> struct QAtomicOps : QBasicAtomicOps<sizeof(T)> +{ + typedef T Type; +}; + +#if defined(Q_CC_GNU) + +#if defined(_MIPS_ARCH_MIPS1) || (defined(__mips) && __mips - 0 == 1) +# error "Sorry, the MIPS1 architecture is not supported" +# error "please set '-march=' to your architecture (e.g., -march=mips32)" #endif -inline bool QBasicAtomicInt::ref() +template <int size> inline +void QBasicAtomicOps<size>::acquireMemoryFence() { - register int originalValue; - register int newValue; - asm volatile(".set push\n" - SET_MIPS2 - "0:\n" + asm volatile ("sync 0x11" ::: "memory"); +} + +template <int size> inline +void QBasicAtomicOps<size>::releaseMemoryFence() +{ + asm volatile ("sync 0x12" ::: "memory"); +} + +template <int size> inline +void QBasicAtomicOps<size>::orderedMemoryFence() +{ + asm volatile ("sync 0" ::: "memory"); +} + +template<> template<typename T> inline +bool QBasicAtomicOps<4>::ref(T &_q_value) +{ + register T originalValue; + register T newValue; + asm volatile("0:\n" "ll %[originalValue], %[_q_value]\n" "addiu %[newValue], %[originalValue], %[one]\n" "sc %[newValue], %[_q_value]\n" "beqz %[newValue], 0b\n" "nop\n" - ".set pop\n" : [originalValue] "=&r" (originalValue), [_q_value] "+m" (_q_value), [newValue] "=&r" (newValue) : [one] "i" (1) : "cc", "memory"); - return originalValue != -1; + return originalValue != T(-1); } -inline bool QBasicAtomicInt::deref() +template<> template<typename T> inline +bool QBasicAtomicOps<4>::deref(T &_q_value) { - register int originalValue; - register int newValue; - asm volatile(".set push\n" - SET_MIPS2 - "0:\n" + register T originalValue; + register T newValue; + asm volatile("0:\n" "ll %[originalValue], %[_q_value]\n" "addiu %[newValue], %[originalValue], %[minusOne]\n" "sc %[newValue], %[_q_value]\n" "beqz %[newValue], 0b\n" "nop\n" - ".set pop\n" : [originalValue] "=&r" (originalValue), [_q_value] "+m" (_q_value), [newValue] "=&r" (newValue) @@ -151,39 +161,12 @@ inline bool QBasicAtomicInt::deref() return originalValue != 1; } -inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) -{ - register int result; - register int tempValue; - asm volatile(".set push\n" - SET_MIPS2 - "0:\n" - "ll %[result], %[_q_value]\n" - "xor %[result], %[result], %[expectedValue]\n" - "bnez %[result], 0f\n" - "nop\n" - "move %[tempValue], %[newValue]\n" - "sc %[tempValue], %[_q_value]\n" - "beqz %[tempValue], 0b\n" - "nop\n" - "0:\n" - ".set pop\n" - : [result] "=&r" (result), - [tempValue] "=&r" (tempValue), - [_q_value] "+m" (_q_value) - : [expectedValue] "r" (expectedValue), - [newValue] "r" (newValue) - : "cc", "memory"); - return result == 0; -} - -inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue) +template<> template <typename T> inline +bool QBasicAtomicOps<4>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) { - register int result; - register int tempValue; - asm volatile(".set push\n" - SET_MIPS2 - "0:\n" + register T result; + register T tempValue; + asm volatile("0:\n" "ll %[result], %[_q_value]\n" "xor %[result], %[result], %[expectedValue]\n" "bnez %[result], 0f\n" @@ -192,9 +175,7 @@ inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue) "sc %[tempValue], %[_q_value]\n" "beqz %[tempValue], 0b\n" "nop\n" - "sync\n" "0:\n" - ".set pop\n" : [result] "=&r" (result), [tempValue] "=&r" (tempValue), [_q_value] "+m" (_q_value) @@ -204,73 +185,17 @@ inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue) return result == 0; } -inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue) -{ - register int result; - register int tempValue; - asm volatile(".set push\n" - SET_MIPS2 - "sync\n" - "0:\n" - "ll %[result], %[_q_value]\n" - "xor %[result], %[result], %[expectedValue]\n" - "bnez %[result], 0f\n" - "nop\n" - "move %[tempValue], %[newValue]\n" - "sc %[tempValue], %[_q_value]\n" - "beqz %[tempValue], 0b\n" - "nop\n" - "0:\n" - ".set pop\n" - : [result] "=&r" (result), - [tempValue] "=&r" (tempValue), - [_q_value] "+m" (_q_value) - : [expectedValue] "r" (expectedValue), - [newValue] "r" (newValue) - : "cc", "memory"); - return result == 0; -} - -inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) -{ - return testAndSetAcquire(expectedValue, newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue) -{ - register int originalValue; - register int tempValue; - asm volatile(".set push\n" - SET_MIPS2 - "0:\n" - "ll %[originalValue], %[_q_value]\n" - "move %[tempValue], %[newValue]\n" - "sc %[tempValue], %[_q_value]\n" - "beqz %[tempValue], 0b\n" - "nop\n" - ".set pop\n" - : [originalValue] "=&r" (originalValue), - [tempValue] "=&r" (tempValue), - [_q_value] "+m" (_q_value) - : [newValue] "r" (newValue) - : "cc", "memory"); - return originalValue; -} - -inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue) +template<> template <typename T> inline +T QBasicAtomicOps<4>::fetchAndStoreRelaxed(T &_q_value, T newValue) { - register int originalValue; - register int tempValue; - asm volatile(".set push\n" - SET_MIPS2 - "0:\n" + register T originalValue; + register T tempValue; + asm volatile("0:\n" "ll %[originalValue], %[_q_value]\n" "move %[tempValue], %[newValue]\n" "sc %[tempValue], %[_q_value]\n" "beqz %[tempValue], 0b\n" "nop\n" - "sync\n" - ".set pop\n" : [originalValue] "=&r" (originalValue), [tempValue] "=&r" (tempValue), [_q_value] "+m" (_q_value) @@ -279,185 +204,89 @@ inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue) return originalValue; } -inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue) +template<> template <typename T> inline +T QBasicAtomicOps<4>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) { - register int originalValue; - register int tempValue; - asm volatile(".set push\n" - SET_MIPS2 - "sync\n" - "0:\n" - "ll %[originalValue], %[_q_value]\n" - "move %[tempValue], %[newValue]\n" - "sc %[tempValue], %[_q_value]\n" - "beqz %[tempValue], 0b\n" - "nop\n" - ".set pop\n" - : [originalValue] "=&r" (originalValue), - [tempValue] "=&r" (tempValue), - [_q_value] "+m" (_q_value) - : [newValue] "r" (newValue) - : "cc", "memory"); - return originalValue; -} - -inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) -{ - return fetchAndStoreAcquire(newValue); -} - -inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd) -{ - register int originalValue; - register int newValue; - asm volatile(".set push\n" - SET_MIPS2 - "0:\n" + register T originalValue; + register T newValue; + asm volatile("0:\n" "ll %[originalValue], %[_q_value]\n" "addu %[newValue], %[originalValue], %[valueToAdd]\n" "sc %[newValue], %[_q_value]\n" "beqz %[newValue], 0b\n" "nop\n" - ".set pop\n" : [originalValue] "=&r" (originalValue), [_q_value] "+m" (_q_value), [newValue] "=&r" (newValue) - : [valueToAdd] "r" (valueToAdd) + : [valueToAdd] "r" (valueToAdd * QAtomicAdditiveType<T>::AddScale) : "cc", "memory"); return originalValue; } -inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd) +#if defined(_MIPS_ARCH_MIPS64) || defined(__mips64) + +#define Q_ATOMIC_INT64_IS_SUPPORTED +#define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT64_TEST_AND_SET_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT64_FETCH_AND_STORE_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_ALWAYS_NATIVE + +template<> struct QAtomicIntegerTraits<long long> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned long long > { enum { IsInteger = 1 }; }; + +template<> template<typename T> inline +bool QBasicAtomicOps<8>::ref(T &_q_value) { - register int originalValue; - register int newValue; - asm volatile(".set push\n" - SET_MIPS2 - "0:\n" - "ll %[originalValue], %[_q_value]\n" - "addu %[newValue], %[originalValue], %[valueToAdd]\n" - "sc %[newValue], %[_q_value]\n" + register T originalValue; + register T newValue; + asm volatile("0:\n" + "lld %[originalValue], %[_q_value]\n" + "addiu %[newValue], %[originalValue], %[one]\n" + "scd %[newValue], %[_q_value]\n" "beqz %[newValue], 0b\n" "nop\n" - "sync\n" - ".set pop\n" : [originalValue] "=&r" (originalValue), [_q_value] "+m" (_q_value), [newValue] "=&r" (newValue) - : [valueToAdd] "r" (valueToAdd) + : [one] "i" (1) : "cc", "memory"); - return originalValue; + return originalValue != T(-1); } -inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd) +template<> template<typename T> inline +bool QBasicAtomicOps<8>::deref(T &_q_value) { - register int originalValue; - register int newValue; - asm volatile(".set push\n" - SET_MIPS2 - "sync\n" - "0:\n" - "ll %[originalValue], %[_q_value]\n" - "addu %[newValue], %[originalValue], %[valueToAdd]\n" - "sc %[newValue], %[_q_value]\n" + register T originalValue; + register T newValue; + asm volatile("0:\n" + "lld %[originalValue], %[_q_value]\n" + "addiu %[newValue], %[originalValue], %[minusOne]\n" + "scd %[newValue], %[_q_value]\n" "beqz %[newValue], 0b\n" "nop\n" - ".set pop\n" : [originalValue] "=&r" (originalValue), [_q_value] "+m" (_q_value), [newValue] "=&r" (newValue) - : [valueToAdd] "r" (valueToAdd) - : "cc", "memory"); - return originalValue; -} - -inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) -{ - return fetchAndAddAcquire(valueToAdd); -} - -#if defined(__LP64__) -# define LLP "lld" -# define SCP "scd" -#else -# define LLP "ll" -# define SCP "sc" -#endif - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue) -{ - register T *result; - register T *tempValue; - asm volatile(".set push\n" - SET_MIPS2 - "0:\n" - LLP" %[result], %[_q_value]\n" - "xor %[result], %[result], %[expectedValue]\n" - "bnez %[result], 0f\n" - "nop\n" - "move %[tempValue], %[newValue]\n" - SCP" %[tempValue], %[_q_value]\n" - "beqz %[tempValue], 0b\n" - "nop\n" - "0:\n" - ".set pop\n" - : [result] "=&r" (result), - [tempValue] "=&r" (tempValue), - [_q_value] "+m" (_q_value) - : [expectedValue] "r" (expectedValue), - [newValue] "r" (newValue) - : "cc", "memory"); - return result == 0; -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue) -{ - register T *result; - register T *tempValue; - asm volatile(".set push\n" - SET_MIPS2 - "0:\n" - LLP" %[result], %[_q_value]\n" - "xor %[result], %[result], %[expectedValue]\n" - "bnez %[result], 0f\n" - "nop\n" - "move %[tempValue], %[newValue]\n" - SCP" %[tempValue], %[_q_value]\n" - "beqz %[tempValue], 0b\n" - "nop\n" - "sync\n" - "0:\n" - ".set pop\n" - : [result] "=&r" (result), - [tempValue] "=&r" (tempValue), - [_q_value] "+m" (_q_value) - : [expectedValue] "r" (expectedValue), - [newValue] "r" (newValue) + : [minusOne] "i" (-1) : "cc", "memory"); - return result == 0; + return originalValue != 1; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue) +template<> template <typename T> inline +bool QBasicAtomicOps<8>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) { - register T *result; - register T *tempValue; - asm volatile(".set push\n" - SET_MIPS2 - "sync\n" - "0:\n" - LLP" %[result], %[_q_value]\n" + register T result; + register T tempValue; + asm volatile("0:\n" + "lld %[result], %[_q_value]\n" "xor %[result], %[result], %[expectedValue]\n" "bnez %[result], 0f\n" "nop\n" "move %[tempValue], %[newValue]\n" - SCP" %[tempValue], %[_q_value]\n" + "scd %[tempValue], %[_q_value]\n" "beqz %[tempValue], 0b\n" "nop\n" "0:\n" - ".set pop\n" : [result] "=&r" (result), [tempValue] "=&r" (tempValue), [_q_value] "+m" (_q_value) @@ -467,72 +296,17 @@ Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValu return result == 0; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue) -{ - return testAndSetAcquire(expectedValue, newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue) -{ - register T *originalValue; - register T *tempValue; - asm volatile(".set push\n" - SET_MIPS2 - "0:\n" - LLP" %[originalValue], %[_q_value]\n" - "move %[tempValue], %[newValue]\n" - SCP" %[tempValue], %[_q_value]\n" - "beqz %[tempValue], 0b\n" - "nop\n" - ".set pop\n" - : [originalValue] "=&r" (originalValue), - [tempValue] "=&r" (tempValue), - [_q_value] "+m" (_q_value) - : [newValue] "r" (newValue) - : "cc", "memory"); - return originalValue; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue) -{ - register T *originalValue; - register T *tempValue; - asm volatile(".set push\n" - SET_MIPS2 - "0:\n" - LLP" %[originalValue], %[_q_value]\n" - "move %[tempValue], %[newValue]\n" - SCP" %[tempValue], %[_q_value]\n" - "beqz %[tempValue], 0b\n" - "nop\n" - "sync\n" - ".set pop\n" - : [originalValue] "=&r" (originalValue), - [tempValue] "=&r" (tempValue), - [_q_value] "+m" (_q_value) - : [newValue] "r" (newValue) - : "cc", "memory"); - return originalValue; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue) +template<> template <typename T> inline +T QBasicAtomicOps<8>::fetchAndStoreRelaxed(T &_q_value, T newValue) { - register T *originalValue; - register T *tempValue; - asm volatile(".set push\n" - SET_MIPS2 - "sync\n" - "0:\n" - LLP" %[originalValue], %[_q_value]\n" + register T originalValue; + register T tempValue; + asm volatile("0:\n" + "lld %[originalValue], %[_q_value]\n" "move %[tempValue], %[newValue]\n" - SCP" %[tempValue], %[_q_value]\n" + "scd %[tempValue], %[_q_value]\n" "beqz %[tempValue], 0b\n" "nop\n" - ".set pop\n" : [originalValue] "=&r" (originalValue), [tempValue] "=&r" (tempValue), [_q_value] "+m" (_q_value) @@ -541,348 +315,29 @@ Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue) return originalValue; } -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue) +template<> template <typename T> inline +T QBasicAtomicOps<8>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) { - return fetchAndStoreAcquire(newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd) -{ - register T *originalValue; - register T *newValue; - asm volatile(".set push\n" - SET_MIPS2 - "0:\n" - LLP" %[originalValue], %[_q_value]\n" + register T originalValue; + register T newValue; + asm volatile("0:\n" + "lld %[originalValue], %[_q_value]\n" "addu %[newValue], %[originalValue], %[valueToAdd]\n" - SCP" %[newValue], %[_q_value]\n" + "scd %[newValue], %[_q_value]\n" "beqz %[newValue], 0b\n" "nop\n" - ".set pop\n" : [originalValue] "=&r" (originalValue), [_q_value] "+m" (_q_value), [newValue] "=&r" (newValue) - : [valueToAdd] "r" (valueToAdd * sizeof(T)) + : [valueToAdd] "r" (valueToAdd * QAtomicAdditiveType<T>::AddScale) : "cc", "memory"); return originalValue; } -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd) -{ - register T *originalValue; - register T *newValue; - asm volatile(".set push\n" - SET_MIPS2 - "0:\n" - LLP" %[originalValue], %[_q_value]\n" - "addu %[newValue], %[originalValue], %[valueToAdd]\n" - SCP" %[newValue], %[_q_value]\n" - "beqz %[newValue], 0b\n" - "nop\n" - "sync\n" - ".set pop\n" - : [originalValue] "=&r" (originalValue), - [_q_value] "+m" (_q_value), - [newValue] "=&r" (newValue) - : [valueToAdd] "r" (valueToAdd * sizeof(T)) - : "cc", "memory"); - return originalValue; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd) -{ - register T *originalValue; - register T *newValue; - asm volatile(".set push\n" - SET_MIPS2 - "sync\n" - "0:\n" - LLP" %[originalValue], %[_q_value]\n" - "addu %[newValue], %[originalValue], %[valueToAdd]\n" - SCP" %[newValue], %[_q_value]\n" - "beqz %[newValue], 0b\n" - "nop\n" - ".set pop\n" - : [originalValue] "=&r" (originalValue), - [_q_value] "+m" (_q_value), - [newValue] "=&r" (newValue) - : [valueToAdd] "r" (valueToAdd * sizeof(T)) - : "cc", "memory"); - return originalValue; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd) -{ - return fetchAndAddAcquire(valueToAdd); -} - -#else // !Q_CC_GNU - -extern "C" { - Q_CORE_EXPORT int q_atomic_test_and_set_int(volatile int *ptr, int expected, int newval); - Q_CORE_EXPORT int q_atomic_test_and_set_acquire_int(volatile int *ptr, int expected, int newval); - Q_CORE_EXPORT int q_atomic_test_and_set_release_int(volatile int *ptr, int expected, int newval); - Q_CORE_EXPORT int q_atomic_test_and_set_ptr(volatile void *ptr, void *expected, void *newval); - Q_CORE_EXPORT int q_atomic_test_and_set_acquire_ptr(volatile void *ptr, void *expected, void *newval); - Q_CORE_EXPORT int q_atomic_test_and_set_release_ptr(volatile void *ptr, void *expected, void *newval); -} // extern "C" - -inline bool QBasicAtomicInt::ref() -{ - register int expected; - for (;;) { - expected = _q_value; - if (q_atomic_test_and_set_int(&_q_value, expected, expected + 1)) - break; - } - return expected != -1; -} - -inline bool QBasicAtomicInt::deref() -{ - register int expected; - for (;;) { - expected = _q_value; - if (q_atomic_test_and_set_int(&_q_value, expected, expected - 1)) - break; - } - return expected != 1; -} - -inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) -{ - return q_atomic_test_and_set_int(&_q_value, expectedValue, newValue) != 0; -} - -inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue) -{ - return q_atomic_test_and_set_acquire_int(&_q_value, expectedValue, newValue) != 0; -} - -inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue) -{ - return q_atomic_test_and_set_release_int(&_q_value, expectedValue, newValue) != 0; -} - -inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) -{ - return q_atomic_test_and_set_acquire_int(&_q_value, expectedValue, newValue) != 0; -} - -inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue) -{ - int returnValue; - for (;;) { - returnValue = _q_value; - if (testAndSetRelaxed(returnValue, newValue)) - break; - } - return returnValue; -} - -inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue) -{ - int returnValue; - for (;;) { - returnValue = _q_value; - if (testAndSetAcquire(returnValue, newValue)) - break; - } - return returnValue; -} - -inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue) -{ - int returnValue; - for (;;) { - returnValue = _q_value; - if (testAndSetRelease(returnValue, newValue)) - break; - } - return returnValue; -} - -inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) -{ - int returnValue; - for (;;) { - returnValue = _q_value; - if (testAndSetOrdered(returnValue, newValue)) - break; - } - return returnValue; -} - -inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd) -{ - int returnValue; - for (;;) { - returnValue = _q_value; - if (testAndSetRelaxed(returnValue, returnValue + valueToAdd)) - break; - } - return returnValue; -} - -inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd) -{ - int returnValue; - for (;;) { - returnValue = _q_value; - if (testAndSetAcquire(returnValue, returnValue + valueToAdd)) - break; - } - return returnValue; -} - -inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd) -{ - int returnValue; - for (;;) { - returnValue = _q_value; - if (testAndSetRelease(returnValue, returnValue + valueToAdd)) - break; - } - return returnValue; -} - -inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) -{ - int returnValue; - for (;;) { - returnValue = _q_value; - if (testAndSetOrdered(returnValue, returnValue + valueToAdd)) - break; - } - return returnValue; -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue) -{ - return q_atomic_test_and_set_ptr(&_q_value, expectedValue, newValue) != 0; -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue) -{ - return q_atomic_test_and_set_acquire_ptr(&_q_value, expectedValue, newValue) != 0; -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue) -{ - return q_atomic_test_and_set_release_ptr(&_q_value, expectedValue, newValue) != 0; -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue) -{ - return q_atomic_test_and_set_acquire_ptr(&_q_value, expectedValue, newValue) != 0; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue) -{ - T *returnValue; - for (;;) { - returnValue = (_q_value); - if (testAndSetRelaxed(returnValue, newValue)) - break; - } - return returnValue; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue) -{ - T *returnValue; - for (;;) { - returnValue = (_q_value); - if (testAndSetAcquire(returnValue, newValue)) - break; - } - return returnValue; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue) -{ - T *returnValue; - for (;;) { - returnValue = (_q_value); - if (testAndSetRelease(returnValue, newValue)) - break; - } - return returnValue; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue) -{ - T *returnValue; - for (;;) { - returnValue = (_q_value); - if (testAndSetOrdered(returnValue, newValue)) - break; - } - return returnValue; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd) -{ - T *returnValue; - for (;;) { - returnValue = (_q_value); - if (testAndSetRelaxed(returnValue, returnValue + valueToAdd)) - break; - } - return returnValue; -} - -template <typename T> -Q_INLINE_TEMPLATE -T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd) -{ - T *returnValue; - for (;;) { - returnValue = (_q_value); - if (testAndSetAcquire(returnValue, returnValue + valueToAdd)) - break; - } - return returnValue; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd) -{ - T *returnValue; - for (;;) { - returnValue = (_q_value); - if (testAndSetRelease(returnValue, returnValue + valueToAdd)) - break; - } - return returnValue; -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd) -{ - T *returnValue; - for (;;) { - returnValue = (_q_value); - if (testAndSetOrdered(returnValue, returnValue + valueToAdd)) - break; - } - return returnValue; -} +#endif // MIPS64 +#else +# error "This compiler for MIPS is not supported" #endif // Q_CC_GNU QT_END_NAMESPACE diff --git a/src/corelib/arch/qatomic_windows.h b/src/corelib/arch/qatomic_msvc.h index 667e58124e..eeb37dba89 100644 --- a/src/corelib/arch/qatomic_windows.h +++ b/src/corelib/arch/qatomic_msvc.h @@ -1,8 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) +** Contact: http://www.qt-project.org/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** @@ -35,24 +34,22 @@ ** ** ** +** ** $QT_END_LICENSE$ ** ****************************************************************************/ -#ifndef QATOMIC_WINDOWS_H -#define QATOMIC_WINDOWS_H - -#ifndef Q_CC_MSVC +#ifndef QATOMIC_MSVC_H +#define QATOMIC_MSVC_H -// Mingw and other GCC platforms get inline assembly +#include <QtCore/qgenericatomic.h> -# ifdef __i386__ -# include "QtCore/qatomic_i386.h" -# else -# include "QtCore/qatomic_x86_64.h" -# endif +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE -#else // Q_CC_MSVC +#if 0 +#pragma qt_sync_stop_processing +#endif //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -74,7 +71,7 @@ # include <winbase.h> // It's safer to remove the volatile and let the compiler add it as needed. -# define QT_INTERLOCKED_NO_VOLATILE +# define QT_INTERLOCKED_VOLATILE # else // _WIN32_WCE >= 0x600 || !_X86_ @@ -87,7 +84,7 @@ # define QT_INTERLOCKED_INTRINSIC # endif # else -# define QT_INTERLOCKED_NO_VOLATILE +# define QT_INTERLOCKED_VOLATILE # endif # endif // _WIN32_WCE >= 0x600 || !_X86_ @@ -111,12 +108,8 @@ QT_INTERLOCKED_CONCAT( \ QT_INTERLOCKED_CONCAT(QT_INTERLOCKED_PREFIX, Interlocked), name) -#ifdef QT_INTERLOCKED_NO_VOLATILE -# define QT_INTERLOCKED_VOLATILE -# define QT_INTERLOCKED_REMOVE_VOLATILE(a) qt_interlocked_remove_volatile(a) -#else +#ifndef QT_INTERLOCKED_VOLATILE # define QT_INTERLOCKED_VOLATILE volatile -# define QT_INTERLOCKED_REMOVE_VOLATILE(a) a #endif #ifndef QT_INTERLOCKED_PREFIX @@ -173,297 +166,194 @@ extern "C" { // Interlocked* replacement macros #define QT_INTERLOCKED_INCREMENT(value) \ - QT_INTERLOCKED_FUNCTION( Increment )( \ - QT_INTERLOCKED_REMOVE_VOLATILE( value ) ) + QT_INTERLOCKED_FUNCTION(Increment)(value) #define QT_INTERLOCKED_DECREMENT(value) \ - QT_INTERLOCKED_FUNCTION( Decrement )( \ - QT_INTERLOCKED_REMOVE_VOLATILE( value ) ) + QT_INTERLOCKED_FUNCTION(Decrement)(value) #define QT_INTERLOCKED_COMPARE_EXCHANGE(value, newValue, expectedValue) \ - QT_INTERLOCKED_FUNCTION( CompareExchange )( \ - QT_INTERLOCKED_REMOVE_VOLATILE( value ), \ - newValue, \ - expectedValue ) + QT_INTERLOCKED_FUNCTION(CompareExchange)((value), (newValue), (expectedValue)) #define QT_INTERLOCKED_EXCHANGE(value, newValue) \ - QT_INTERLOCKED_FUNCTION( Exchange )( \ - QT_INTERLOCKED_REMOVE_VOLATILE( value ), \ - newValue ) + QT_INTERLOCKED_FUNCTION(Exchange)((value), (newValue)) #define QT_INTERLOCKED_EXCHANGE_ADD(value, valueToAdd) \ - QT_INTERLOCKED_FUNCTION( ExchangeAdd )( \ - QT_INTERLOCKED_REMOVE_VOLATILE( value ), \ - valueToAdd ) + QT_INTERLOCKED_FUNCTION(ExchangeAdd)((value), (valueToAdd)) #if defined(Q_OS_WINCE) || defined(__i386__) || defined(_M_IX86) # define QT_INTERLOCKED_COMPARE_EXCHANGE_POINTER(value, newValue, expectedValue) \ reinterpret_cast<void *>( \ - QT_INTERLOCKED_FUNCTION( CompareExchange )( \ - QT_INTERLOCKED_REMOVE_VOLATILE( value ## _integral ), \ - (long)( newValue ), \ - (long)( expectedValue ) )) + QT_INTERLOCKED_FUNCTION(CompareExchange)( \ + reinterpret_cast<long QT_INTERLOCKED_VOLATILE *>(value), \ + long(newValue), \ + long(expectedValue))) # define QT_INTERLOCKED_EXCHANGE_POINTER(value, newValue) \ - QT_INTERLOCKED_FUNCTION( Exchange )( \ - QT_INTERLOCKED_REMOVE_VOLATILE( value ## _integral ), \ - (quintptr)( newValue ) ) + QT_INTERLOCKED_FUNCTION(Exchange)( \ + reinterpret_cast<long QT_INTERLOCKED_VOLATILE *>(value), \ + long(newValue)) # define QT_INTERLOCKED_EXCHANGE_ADD_POINTER(value, valueToAdd) \ - QT_INTERLOCKED_FUNCTION( ExchangeAdd )( \ - QT_INTERLOCKED_REMOVE_VOLATILE( value ## _integral ), \ - valueToAdd ) + QT_INTERLOCKED_FUNCTION(ExchangeAdd)( \ + reinterpret_cast<long QT_INTERLOCKED_VOLATILE *>(value), \ + (valueToAdd)) #else // !defined(Q_OS_WINCE) && !defined(__i386__) && !defined(_M_IX86) # define QT_INTERLOCKED_COMPARE_EXCHANGE_POINTER(value, newValue, expectedValue) \ - QT_INTERLOCKED_FUNCTION( CompareExchangePointer )( \ - (void * QT_INTERLOCKED_VOLATILE *)( QT_INTERLOCKED_REMOVE_VOLATILE(value) ), \ - newValue, \ - expectedValue ) + QT_INTERLOCKED_FUNCTION(CompareExchangePointer)( \ + (void * QT_INTERLOCKED_VOLATILE *)(value), \ + (void *) (newValue), \ + (void *) (expectedValue)) # define QT_INTERLOCKED_EXCHANGE_POINTER(value, newValue) \ - QT_INTERLOCKED_FUNCTION( ExchangePointer )( \ - (void * QT_INTERLOCKED_VOLATILE *)( QT_INTERLOCKED_REMOVE_VOLATILE(value) ), \ - newValue ) + QT_INTERLOCKED_FUNCTION(ExchangePointer)( \ + (void * QT_INTERLOCKED_VOLATILE *)(value), \ + (void *) (newValue)) # define QT_INTERLOCKED_EXCHANGE_ADD_POINTER(value, valueToAdd) \ - QT_INTERLOCKED_FUNCTION( ExchangeAdd64 )( \ - QT_INTERLOCKED_REMOVE_VOLATILE( value ## _integral ), \ - valueToAdd ) + QT_INTERLOCKED_FUNCTION(ExchangeAdd64)( \ + reinterpret_cast<qint64 QT_INTERLOCKED_VOLATILE *>(value), \ + (valueToAdd)) #endif // !defined(Q_OS_WINCE) && !defined(__i386__) && !defined(_M_IX86) //////////////////////////////////////////////////////////////////////////////////////////////////// -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - #define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE #define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_WAIT_FREE -inline bool QBasicAtomicInt::isReferenceCountingNative() -{ return true; } -inline bool QBasicAtomicInt::isReferenceCountingWaitFree() -{ return true; } - #define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE #define Q_ATOMIC_INT_TEST_AND_SET_IS_WAIT_FREE -inline bool QBasicAtomicInt::isTestAndSetNative() -{ return true; } -inline bool QBasicAtomicInt::isTestAndSetWaitFree() -{ return true; } - #define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE #define Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE -inline bool QBasicAtomicInt::isFetchAndStoreNative() -{ return true; } -inline bool QBasicAtomicInt::isFetchAndStoreWaitFree() -{ return true; } - #define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE #define Q_ATOMIC_INT_FETCH_AND_ADD_IS_WAIT_FREE -inline bool QBasicAtomicInt::isFetchAndAddNative() -{ return true; } -inline bool QBasicAtomicInt::isFetchAndAddWaitFree() -{ return true; } +#define Q_ATOMIC_INT32_IS_SUPPORTED + +#define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_WAIT_FREE + +#define Q_ATOMIC_INT32_TEST_AND_SET_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT32_TEST_AND_SET_IS_WAIT_FREE + +#define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_WAIT_FREE + +#define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_WAIT_FREE #define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE #define Q_ATOMIC_POINTER_TEST_AND_SET_IS_WAIT_FREE -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree() -{ return true; } - #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree() -{ return true; } - #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_WAIT_FREE -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree() -{ return true; } //////////////////////////////////////////////////////////////////////////////////////////////////// -#ifdef QT_INTERLOCKED_NO_VOLATILE -template <class T> -Q_INLINE_TEMPLATE T *qt_interlocked_remove_volatile(T volatile *t) -{ - return const_cast<T *>(t); -} -#endif // !QT_INTERLOCKED_NO_VOLATILE +template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned int> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<long> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned long> { enum { IsInteger = 1 }; }; -//////////////////////////////////////////////////////////////////////////////////////////////////// +// No definition, needs specialization +template <int N> struct QAtomicOpsBySize; -inline bool QBasicAtomicInt::ref() +template <> +struct QAtomicOpsBySize<4> : QGenericAtomicOps<QAtomicOpsBySize<4> > { - return QT_INTERLOCKED_INCREMENT(&_q_value) != 0; -} + // The 32-bit Interlocked*() API takes paramters as longs. + typedef long Type; -inline bool QBasicAtomicInt::deref() -{ - return QT_INTERLOCKED_DECREMENT(&_q_value) != 0; -} + static inline bool isReferenceCountingNative() { return true; } + static inline bool isReferenceCountingWaitFree() { return true; } + static bool ref(long &_q_value); + static bool deref(long &_q_value); -inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) -{ - return QT_INTERLOCKED_COMPARE_EXCHANGE(&_q_value, newValue, expectedValue) - == expectedValue; -} + static inline bool isTestAndSetNative() { return true; } + static inline bool isTestAndSetWaitFree() { return true; } + static bool testAndSetRelaxed(long &_q_value, long expectedValue, long newValue); -inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) -{ - return QT_INTERLOCKED_EXCHANGE(&_q_value, newValue); -} + static inline bool isFetchAndStoreNative() { return true; } + static inline bool isFetchAndStoreWaitFree() { return true; } + static long fetchAndStoreRelaxed(long &_q_value, long newValue); -inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) -{ - return QT_INTERLOCKED_EXCHANGE_ADD(&_q_value, valueToAdd); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// + static inline bool isFetchAndAddNative() { return true; } + static inline bool isFetchAndAddWaitFree() { return true; } + static long fetchAndAddRelaxed(long &_q_value, QAtomicAdditiveType<long>::AdditiveT valueToAdd); +}; template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue) -{ - return QT_INTERLOCKED_COMPARE_EXCHANGE_POINTER(&_q_value, (void*)newValue, (void*)expectedValue) - == expectedValue; -} +struct QAtomicOps : QAtomicOpsBySize<sizeof(T)> +{ }; -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T* newValue) +inline bool QAtomicOpsBySize<4>::ref(long &_q_value) { - return reinterpret_cast<T *>( - QT_INTERLOCKED_EXCHANGE_POINTER(&_q_value, (void*)newValue)); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd) -{ - return reinterpret_cast<T *>( - QT_INTERLOCKED_EXCHANGE_ADD_POINTER(&_q_value, valueToAdd * sizeof(T))); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -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); + return QT_INTERLOCKED_INCREMENT(&_q_value) != 0; } -inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd) +inline bool QAtomicOpsBySize<4>::deref(long &_q_value) { - return fetchAndAddOrdered(valueToAdd); + return QT_INTERLOCKED_DECREMENT(&_q_value) != 0; } -inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd) +inline bool QAtomicOpsBySize<4>::testAndSetRelaxed(long &_q_value, long expectedValue, long newValue) { - return fetchAndAddOrdered(valueToAdd); + return QT_INTERLOCKED_COMPARE_EXCHANGE(&_q_value, newValue, expectedValue) == expectedValue; } -inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd) +inline long QAtomicOpsBySize<4>::fetchAndStoreRelaxed(long &_q_value, long newValue) { - return fetchAndAddOrdered(valueToAdd); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); + return QT_INTERLOCKED_EXCHANGE(&_q_value, newValue); } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue) +inline long QAtomicOpsBySize<4>::fetchAndAddRelaxed(long &_q_value, QAtomicAdditiveType<long>::AdditiveT valueToAdd) { - return testAndSetOrdered(expectedValue, newValue); + return QT_INTERLOCKED_EXCHANGE_ADD(&_q_value, valueToAdd * QAtomicAdditiveType<long>::AddScale); } +// Specialization for pointer types, since we have Interlocked*Pointer() variants in some configurations template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue) +struct QAtomicOps<T *> : QGenericAtomicOps<QAtomicOps<T *> > { - return testAndSetOrdered(expectedValue, newValue); -} + typedef T *Type; -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} + static inline bool isTestAndSetNative() { return true; } + static inline bool isTestAndSetWaitFree() { return true; } + static bool testAndSetRelaxed(T *&_q_value, T *expectedValue, T *newValue); -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} + static inline bool isFetchAndStoreNative() { return true; } + static inline bool isFetchAndStoreWaitFree() { return true; } + static T *fetchAndStoreRelaxed(T *&_q_value, T *newValue); -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} + static inline bool isFetchAndAddNative() { return true; } + static inline bool isFetchAndAddWaitFree() { return true; } + static T *fetchAndAddRelaxed(T *&_q_value, qptrdiff valueToAdd); +}; template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd) +inline bool QAtomicOps<T *>::testAndSetRelaxed(T *&_q_value, T *expectedValue, T *newValue) { - return fetchAndAddOrdered(valueToAdd); + return QT_INTERLOCKED_COMPARE_EXCHANGE_POINTER(&_q_value, newValue, expectedValue) == expectedValue; } template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd) +inline T *QAtomicOps<T *>::fetchAndStoreRelaxed(T *&_q_value, T *newValue) { - return fetchAndAddOrdered(valueToAdd); + return reinterpret_cast<T *>(QT_INTERLOCKED_EXCHANGE_POINTER(&_q_value, newValue)); } template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd) +inline T *QAtomicOps<T *>::fetchAndAddRelaxed(T *&_q_value, qptrdiff valueToAdd) { - return fetchAndAddOrdered(valueToAdd); + return reinterpret_cast<T *>(QT_INTERLOCKED_EXCHANGE_ADD_POINTER(&_q_value, valueToAdd * sizeof(T))); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -474,9 +364,7 @@ Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueTo #undef QT_INTERLOCKED_FUNCTION #undef QT_INTERLOCKED_PREFIX -#undef QT_INTERLOCKED_NO_VOLATILE #undef QT_INTERLOCKED_VOLATILE -#undef QT_INTERLOCKED_REMOVE_VOLATILE #undef QT_INTERLOCKED_INCREMENT #undef QT_INTERLOCKED_DECREMENT @@ -488,9 +376,6 @@ Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueTo #undef QT_INTERLOCKED_EXCHANGE_ADD_POINTER QT_END_NAMESPACE - QT_END_HEADER -#endif // Q_CC_MSVC - -#endif // QATOMIC_WINDOWS_H +#endif // QATOMIC_MSVC_H diff --git a/src/corelib/arch/qatomic_parisc.h b/src/corelib/arch/qatomic_parisc.h index 200ca14aee..221d0e36ff 100644 --- a/src/corelib/arch/qatomic_parisc.h +++ b/src/corelib/arch/qatomic_parisc.h @@ -1,8 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) +** Contact: http://www.qt-project.org/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** @@ -35,6 +34,7 @@ ** ** ** +** ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/corelib/arch/qatomic_powerpc.h b/src/corelib/arch/qatomic_powerpc.h index bb9afe38d7..949102748a 100644 --- a/src/corelib/arch/qatomic_powerpc.h +++ b/src/corelib/arch/qatomic_powerpc.h @@ -1,8 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) +** Contact: http://www.qt-project.org/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** @@ -35,6 +34,7 @@ ** ** ** +** ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/corelib/arch/qatomic_s390.h b/src/corelib/arch/qatomic_s390.h index e167c7c6e3..b6246e817f 100644 --- a/src/corelib/arch/qatomic_s390.h +++ b/src/corelib/arch/qatomic_s390.h @@ -1,8 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) +** Contact: http://www.qt-project.org/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** @@ -35,6 +34,7 @@ ** ** ** +** ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/corelib/arch/qatomic_sh.h b/src/corelib/arch/qatomic_sh.h index ca50eb1bf0..d16aaf26b1 100644 --- a/src/corelib/arch/qatomic_sh.h +++ b/src/corelib/arch/qatomic_sh.h @@ -1,8 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) +** Contact: http://www.qt-project.org/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** @@ -35,6 +34,7 @@ ** ** ** +** ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/corelib/arch/qatomic_sh4a.h b/src/corelib/arch/qatomic_sh4a.h index 14238a6f10..042a602c77 100644 --- a/src/corelib/arch/qatomic_sh4a.h +++ b/src/corelib/arch/qatomic_sh4a.h @@ -1,8 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) +** Contact: http://www.qt-project.org/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** @@ -35,6 +34,7 @@ ** ** ** +** ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/corelib/arch/qatomic_sparc.h b/src/corelib/arch/qatomic_sparc.h index feb172e68d..5fc640e01b 100644 --- a/src/corelib/arch/qatomic_sparc.h +++ b/src/corelib/arch/qatomic_sparc.h @@ -1,8 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) +** Contact: http://www.qt-project.org/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** @@ -35,6 +34,7 @@ ** ** ** +** ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/corelib/arch/qatomic_symbian.h b/src/corelib/arch/qatomic_symbian.h deleted file mode 100644 index 6cb91f0788..0000000000 --- a/src/corelib/arch/qatomic_symbian.h +++ /dev/null @@ -1,313 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 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$ -** 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_SYMBIAN_H -#define QATOMIC_SYMBIAN_H - -#include <QtCore/qglobal.h> -#include <e32std.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Core) - -#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE - -inline bool QBasicAtomicInt::isReferenceCountingWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_TEST_AND_SET_IS_SOMETIMES_NATIVE - -inline bool QBasicAtomicInt::isTestAndSetWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_SOMETIMES_NATIVE - -inline bool QBasicAtomicInt::isFetchAndStoreWaitFree() -{ return false; } - -#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_SOMETIMES_NATIVE - -inline bool QBasicAtomicInt::isFetchAndAddWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_SOMETIMES_NATIVE - -Q_CORE_EXPORT bool QBasicAtomicPointer_isTestAndSetNative(); -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative() -{ return QBasicAtomicPointer_isTestAndSetNative(); } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_SOMETIMES_NATIVE - -Q_CORE_EXPORT bool QBasicAtomicPointer_isFetchAndStoreNative(); -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative() -{ return QBasicAtomicPointer_isFetchAndStoreNative(); } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree() -{ return false; } - -#define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_SOMETIMES_NATIVE - -Q_CORE_EXPORT bool QBasicAtomicPointer_isFetchAndAddNative(); -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative() -{ return QBasicAtomicPointer_isFetchAndAddNative(); } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::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 QBasicAtomicInt_testAndSetRelaxed(volatile int *, int, int); -Q_CORE_EXPORT int QBasicAtomicInt_fetchAndStoreRelaxed(volatile int *, int); -Q_CORE_EXPORT int QBasicAtomicInt_fetchAndAddRelaxed(volatile int *, int); -Q_CORE_EXPORT bool QBasicAtomicInt_testAndSetAcquire(volatile int *, int, int); -Q_CORE_EXPORT int QBasicAtomicInt_fetchAndStoreAcquire(volatile int *, int); -Q_CORE_EXPORT int QBasicAtomicInt_fetchAndAddAcquire(volatile int *, int); -Q_CORE_EXPORT bool QBasicAtomicInt_testAndSetRelease(volatile int *, int, int); -Q_CORE_EXPORT int QBasicAtomicInt_fetchAndStoreRelease(volatile int *, int); -Q_CORE_EXPORT int QBasicAtomicInt_fetchAndAddRelease(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); -Q_CORE_EXPORT bool QBasicAtomicPointer_testAndSetRelaxed(void * volatile *, void *, void *); -Q_CORE_EXPORT void *QBasicAtomicPointer_fetchAndStoreRelaxed(void * volatile *, void *); -Q_CORE_EXPORT void *QBasicAtomicPointer_fetchAndAddRelaxed(void * volatile *, qptrdiff); -Q_CORE_EXPORT bool QBasicAtomicPointer_testAndSetAcquire(void * volatile *, void *, void *); -Q_CORE_EXPORT void *QBasicAtomicPointer_fetchAndStoreAcquire(void * volatile *, void *); -Q_CORE_EXPORT void *QBasicAtomicPointer_fetchAndAddAcquire(void * volatile *, qptrdiff); -Q_CORE_EXPORT bool QBasicAtomicPointer_testAndSetRelease(void * volatile *, void *, void *); -Q_CORE_EXPORT void *QBasicAtomicPointer_fetchAndStoreRelease(void * volatile *, void *); -Q_CORE_EXPORT void *QBasicAtomicPointer_fetchAndAddRelease(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 QBasicAtomicInt_testAndSetRelaxed(&_q_value, expectedValue, newValue); -} - -inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue) -{ - return QBasicAtomicInt_testAndSetAcquire(&_q_value, expectedValue, newValue); -} - -inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue) -{ - return QBasicAtomicInt_testAndSetRelease(&_q_value, 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 QBasicAtomicInt_fetchAndStoreRelaxed(&_q_value, newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue) -{ - return QBasicAtomicInt_fetchAndStoreAcquire(&_q_value, newValue); -} - -inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue) -{ - return QBasicAtomicInt_fetchAndStoreRelease(&_q_value, 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 QBasicAtomicInt_fetchAndAddRelaxed(&_q_value, valueToAdd); -} - -inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd) -{ - return QBasicAtomicInt_fetchAndAddAcquire(&_q_value, valueToAdd); -} - -inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd) -{ - return QBasicAtomicInt_fetchAndAddRelease(&_q_value, valueToAdd); -} - -// Test and set for pointers - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue) -{ - return QBasicAtomicPointer_testAndSetOrdered(reinterpret_cast<void * volatile *>(&_q_value), - expectedValue, newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue) -{ - return QBasicAtomicPointer_testAndSetRelaxed(reinterpret_cast<void * volatile *>(&_q_value), - expectedValue, newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue) -{ - return QBasicAtomicPointer_testAndSetAcquire(reinterpret_cast<void * volatile *>(&_q_value), - expectedValue, newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue) -{ - return QBasicAtomicPointer_testAndSetRelease(reinterpret_cast<void * volatile *>(&_q_value), - expectedValue, newValue); -} - -// Fetch and store for pointers - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue) -{ - return static_cast<T*>(QBasicAtomicPointer_fetchAndStoreOrdered( - reinterpret_cast<void * volatile *>(&_q_value) - , newValue)); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue) -{ - return static_cast<T*>(QBasicAtomicPointer_fetchAndStoreRelaxed( - reinterpret_cast<void * volatile *>(&_q_value) - , newValue)); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue) -{ - return static_cast<T*>(QBasicAtomicPointer_fetchAndStoreAcquire( - reinterpret_cast<void * volatile *>(&_q_value) - , newValue)); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue) -{ - return static_cast<T*>(QBasicAtomicPointer_fetchAndStoreRelease( - reinterpret_cast<void * volatile *>(&_q_value) - , newValue)); -} - -// Fetch and add for pointers - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd) -{ - return static_cast<T*>(QBasicAtomicPointer_fetchAndAddOrdered( - reinterpret_cast<void * volatile *>(&_q_value), - valueToAdd * sizeof(T))); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd) -{ - return static_cast<T*>(QBasicAtomicPointer_fetchAndAddRelaxed( - reinterpret_cast<void * volatile *>(&_q_value), - valueToAdd * sizeof(T))); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd) -{ - return static_cast<T*>(QBasicAtomicPointer_fetchAndAddAcquire( - reinterpret_cast<void * volatile *>(&_q_value), - valueToAdd * sizeof(T))); -} - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd) -{ - return static_cast<T*>(QBasicAtomicPointer_fetchAndAddRelease( - reinterpret_cast<void * volatile *>(&_q_value), - valueToAdd * sizeof(T))); -} - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QATOMIC_SYMBIAN_H diff --git a/src/corelib/arch/qatomic_vxworks.h b/src/corelib/arch/qatomic_vxworks.h index 13d6764d36..c18563ef3c 100644 --- a/src/corelib/arch/qatomic_vxworks.h +++ b/src/corelib/arch/qatomic_vxworks.h @@ -1,8 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) +** Contact: http://www.qt-project.org/ ** ** This file is part of the qmake spec of the Qt Toolkit. ** @@ -35,6 +34,7 @@ ** ** ** +** ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/corelib/arch/qatomic_windowsce.h b/src/corelib/arch/qatomic_windowsce.h deleted file mode 100644 index 3681655285..0000000000 --- a/src/corelib/arch/qatomic_windowsce.h +++ /dev/null @@ -1,56 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 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$ -** 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 WINDOWSCE_QATOMIC_H -#define WINDOWSCE_QATOMIC_H - -#include <QtCore/qglobal.h> -QT_BEGIN_HEADER - -#if defined(QT_ARCH_WINDOWSCE) -#include "QtCore/qatomic_windows.h" -#endif - -QT_END_HEADER - -#endif // QATOMIC_ARCH_H - - diff --git a/src/corelib/arch/qatomic_x86_64.h b/src/corelib/arch/qatomic_x86_64.h index c2627c825f..f2fa8ce5f4 100644 --- a/src/corelib/arch/qatomic_x86_64.h +++ b/src/corelib/arch/qatomic_x86_64.h @@ -1,8 +1,8 @@ /**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) +** Copyright (C) 2011 Thiago Macieira <thiago@kde.org> +** Contact: http://www.qt-project.org/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** @@ -35,6 +35,7 @@ ** ** ** +** ** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -42,79 +43,98 @@ #ifndef QATOMIC_X86_64_H #define QATOMIC_X86_64_H +#include <QtCore/qgenericatomic.h> + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE +#if 0 +#pragma qt_sync_stop_processing +#endif + #define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE #define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_WAIT_FREE -inline bool QBasicAtomicInt::isReferenceCountingNative() -{ return true; } -inline bool QBasicAtomicInt::isReferenceCountingWaitFree() -{ return true; } - #define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE #define Q_ATOMIC_INT_TEST_AND_SET_IS_WAIT_FREE -inline bool QBasicAtomicInt::isTestAndSetNative() -{ return true; } -inline bool QBasicAtomicInt::isTestAndSetWaitFree() -{ return true; } - #define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE #define Q_ATOMIC_INT_FETCH_AND_STORE_IS_WAIT_FREE -inline bool QBasicAtomicInt::isFetchAndStoreNative() -{ return true; } -inline bool QBasicAtomicInt::isFetchAndStoreWaitFree() -{ return true; } - #define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE #define Q_ATOMIC_INT_FETCH_AND_ADD_IS_WAIT_FREE -inline bool QBasicAtomicInt::isFetchAndAddNative() -{ return true; } -inline bool QBasicAtomicInt::isFetchAndAddWaitFree() -{ return true; } +#define Q_ATOMIC_INT32_IS_SUPPORTED + +#define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_WAIT_FREE + +#define Q_ATOMIC_INT32_TEST_AND_SET_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT32_TEST_AND_SET_IS_WAIT_FREE + +#define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_WAIT_FREE + +#define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_WAIT_FREE #define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE #define Q_ATOMIC_POINTER_TEST_AND_SET_IS_WAIT_FREE -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isTestAndSetWaitFree() -{ return true; } - #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE #define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_WAIT_FREE -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree() -{ return true; } - #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE #define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_WAIT_FREE -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddNative() -{ return true; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree() -{ return true; } +template<> struct QAtomicIntegerTraits<int> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned int> { enum { IsInteger = 1 }; }; + +template <int size> struct QBasicAtomicOps: QGenericAtomicOps<QBasicAtomicOps<size> > +{ + static inline bool isReferenceCountingNative() { return true; } + static inline bool isReferenceCountingWaitFree() { return true; } + template <typename T> static bool ref(T &_q_value); + template <typename T> static bool deref(T &_q_value); + + static inline bool isTestAndSetNative() { return true; } + static inline bool isTestAndSetWaitFree() { return true; } + template <typename T> static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue); + + static inline bool isFetchAndStoreNative() { return true; } + static inline bool isFetchAndStoreWaitFree() { return true; } + template <typename T> static T fetchAndStoreRelaxed(T &_q_value, T newValue); + + static inline bool isFetchAndAddNative() { return true; } + static inline bool isFetchAndAddWaitFree() { return true; } + template <typename T> static + T fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd); +}; + +template <typename T> struct QAtomicOps : QBasicAtomicOps<sizeof(T)> +{ + typedef T Type; +}; #if defined(Q_CC_GNU) || defined(Q_CC_INTEL) -inline bool QBasicAtomicInt::ref() +template<> struct QAtomicIntegerTraits<char> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<signed char> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned char> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<short> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned short> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<long> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned long> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<long long> { enum { IsInteger = 1 }; }; +template<> struct QAtomicIntegerTraits<unsigned long long> { enum { IsInteger = 1 }; }; + +template<> template<typename T> inline +bool QBasicAtomicOps<1>::ref(T &_q_value) { unsigned char ret; asm volatile("lock\n" - "incl %0\n" + "incb %0\n" "setne %1" : "=m" (_q_value), "=qm" (ret) : "m" (_q_value) @@ -122,11 +142,12 @@ inline bool QBasicAtomicInt::ref() return ret != 0; } -inline bool QBasicAtomicInt::deref() +template<> template<typename T> inline +bool QBasicAtomicOps<2>::ref(T &_q_value) { unsigned char ret; asm volatile("lock\n" - "decl %0\n" + "incw %0\n" "setne %1" : "=m" (_q_value), "=qm" (ret) : "m" (_q_value) @@ -134,227 +155,198 @@ inline bool QBasicAtomicInt::deref() return ret != 0; } -inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue) +template<> template<typename T> inline +bool QBasicAtomicOps<4>::ref(T &_q_value) { unsigned char ret; asm volatile("lock\n" - "cmpxchgl %3,%2\n" - "sete %1\n" - : "=a" (newValue), "=qm" (ret), "+m" (_q_value) - : "r" (newValue), "0" (expectedValue) + "incl %0\n" + "setne %1" + : "=m" (_q_value), "=qm" (ret) + : "m" (_q_value) : "memory"); return ret != 0; } -inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue) +template<> template<typename T> inline +bool QBasicAtomicOps<8>::ref(T &_q_value) { - asm volatile("xchgl %0,%1" - : "=r" (newValue), "+m" (_q_value) - : "0" (newValue) + unsigned char ret; + asm volatile("lock\n" + "incq %0\n" + "setne %1" + : "=m" (_q_value), "=qm" (ret) + : "m" (_q_value) : "memory"); - return newValue; + return ret != 0; } -inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd) +template<> template <typename T> inline +bool QBasicAtomicOps<1>::deref(T &_q_value) { + unsigned char ret; asm volatile("lock\n" - "xaddl %0,%1" - : "=r" (valueToAdd), "+m" (_q_value) - : "0" (valueToAdd) + "decb %0\n" + "setne %1" + : "=m" (_q_value), "=qm" (ret) + : "m" (_q_value) : "memory"); - return valueToAdd; + return ret != 0; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue) +template<> template <typename T> inline +bool QBasicAtomicOps<2>::deref(T &_q_value) { unsigned char ret; asm volatile("lock\n" - "cmpxchgq %3,%2\n" - "sete %1\n" - : "=a" (newValue), "=qm" (ret), "+m" (_q_value) - : "r" (newValue), "0" (expectedValue) + "decw %0\n" + "setne %1" + : "=m" (_q_value), "=qm" (ret) + : "m" (_q_value) : "memory"); return ret != 0; } - -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue) +template<> template <typename T> inline +bool QBasicAtomicOps<4>::deref(T &_q_value) { - asm volatile("xchgq %0,%1" - : "=r" (newValue), "+m" (_q_value) - : "0" (newValue) + unsigned char ret; + asm volatile("lock\n" + "decl %0\n" + "setne %1" + : "=m" (_q_value), "=qm" (ret) + : "m" (_q_value) : "memory"); - return newValue; + return ret != 0; } -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd) +template<> template <typename T> inline +bool QBasicAtomicOps<8>::deref(T &_q_value) { + unsigned char ret; asm volatile("lock\n" - "xaddq %0,%1" - : "=r" (valueToAdd), "+m" (_q_value) - : "0" (valueToAdd * sizeof(T)) + "decq %0\n" + "setne %1" + : "=m" (_q_value), "=qm" (ret) + : "m" (_q_value) : "memory"); - return reinterpret_cast<T *>(valueToAdd); -} - -#else // !Q_CC_INTEL && !Q_CC_GNU - -extern "C" { - Q_CORE_EXPORT int q_atomic_test_and_set_int(volatile int *ptr, int expected, int newval); - Q_CORE_EXPORT int q_atomic_test_and_set_ptr(volatile void *ptr, void *expected, void *newval); - Q_CORE_EXPORT int q_atomic_increment(volatile int *ptr); - Q_CORE_EXPORT int q_atomic_decrement(volatile int *ptr); - Q_CORE_EXPORT int q_atomic_set_int(volatile int *ptr, int newval); - Q_CORE_EXPORT void *q_atomic_set_ptr(volatile void *ptr, void *newval); - Q_CORE_EXPORT int q_atomic_fetch_and_add_int(volatile int *ptr, int value); - Q_CORE_EXPORT void *q_atomic_fetch_and_add_ptr(volatile void *ptr, qptrdiff value); -} // extern "C" - -inline bool QBasicAtomicInt::ref() -{ - return q_atomic_increment(&_q_value) != 0; -} - -inline bool QBasicAtomicInt::deref() -{ - return q_atomic_decrement(&_q_value) != 0; + return ret != 0; } -inline bool QBasicAtomicInt::testAndSetOrdered(int expected, int newval) +template<int size> template <typename T> inline +bool QBasicAtomicOps<size>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) { - return q_atomic_test_and_set_int(&_q_value, expected, newval) != 0; + unsigned char ret; + asm volatile("lock\n" + "cmpxchg %3,%2\n" + "sete %1\n" + : "=a" (newValue), "=qm" (ret), "+m" (_q_value) + : "r" (newValue), "0" (expectedValue) + : "memory"); + return ret != 0; } -inline int QBasicAtomicInt::fetchAndStoreOrdered(int newval) +template<> template <typename T> inline +bool QBasicAtomicOps<1>::testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) { - return q_atomic_set_int(&_q_value, newval); + unsigned char ret; + asm volatile("lock\n" + "cmpxchg %3,%2\n" + "sete %1\n" + : "=a" (newValue), "=qm" (ret), "+m" (_q_value) + : "q" (newValue), "0" (expectedValue) + : "memory"); + return ret != 0; } -inline int QBasicAtomicInt::fetchAndAddOrdered(int aValue) +template<int size> template <typename T> inline +T QBasicAtomicOps<size>::fetchAndStoreRelaxed(T &_q_value, T newValue) { - return q_atomic_fetch_and_add_int(&_q_value, aValue); + asm volatile("xchg %0,%1" + : "=r" (newValue), "+m" (_q_value) + : "0" (newValue) + : "memory"); + return newValue; } -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue) +template<> template <typename T> inline +T QBasicAtomicOps<1>::fetchAndStoreRelaxed(T &_q_value, T newValue) { - return q_atomic_test_and_set_ptr(&_q_value, expectedValue, newValue); + asm volatile("xchg %0,%1" + : "=q" (newValue), "+m" (_q_value) + : "0" (newValue) + : "memory"); + return newValue; } -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue) +template<int size> template <typename T> inline +T QBasicAtomicOps<size>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) { - return reinterpret_cast<T *>(q_atomic_set_ptr(&_q_value, newValue)); + T result; + asm volatile("lock\n" + "xadd %0,%1" + : "=r" (result), "+m" (_q_value) + : "0" (T(valueToAdd * QAtomicAdditiveType<T>::AddScale)) + : "memory"); + return result; } -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd) +template<> template <typename T> inline +T QBasicAtomicOps<1>::fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) { - return reinterpret_cast<T *>(q_atomic_fetch_and_add_ptr(&_q_value, valueToAdd * sizeof(T))); + T result; + asm volatile("lock\n" + "xadd %0,%1" + : "=q" (result), "+m" (_q_value) + : "0" (T(valueToAdd * QAtomicAdditiveType<T>::AddScale)) + : "memory"); + return result; } -#endif // Q_CC_GNU || Q_CC_INTEL +#define Q_ATOMIC_INT8_IS_SUPPORTED -inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} +#define Q_ATOMIC_INT8_REFERENCE_COUNTING_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT8_REFERENCE_COUNTING_IS_WAIT_FREE -inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} +#define Q_ATOMIC_INT8_TEST_AND_SET_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT8_TEST_AND_SET_IS_WAIT_FREE -inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} +#define Q_ATOMIC_INT8_FETCH_AND_STORE_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT8_FETCH_AND_STORE_IS_WAIT_FREE -inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue) -{ - return fetchAndStoreOrdered(newValue); -} +#define Q_ATOMIC_INT8_FETCH_AND_ADD_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT8_FETCH_AND_ADD_IS_WAIT_FREE -inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue) -{ - return fetchAndStoreOrdered(newValue); -} +#define Q_ATOMIC_INT16_IS_SUPPORTED -inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue) -{ - return fetchAndStoreOrdered(newValue); -} +#define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_WAIT_FREE -inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} +#define Q_ATOMIC_INT16_TEST_AND_SET_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT16_TEST_AND_SET_IS_WAIT_FREE -inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} - -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} +#define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_WAIT_FREE -template <typename T> -Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue) -{ - return testAndSetOrdered(expectedValue, newValue); -} +#define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_WAIT_FREE -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} +#define Q_ATOMIC_INT64_IS_SUPPORTED -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} +#define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_WAIT_FREE -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue) -{ - return fetchAndStoreOrdered(newValue); -} +#define Q_ATOMIC_INT64_TEST_AND_SET_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT64_TEST_AND_SET_IS_WAIT_FREE -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} +#define Q_ATOMIC_INT64_FETCH_AND_STORE_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT64_FETCH_AND_STORE_IS_WAIT_FREE -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} +#define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_ALWAYS_NATIVE +#define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_WAIT_FREE -template <typename T> -Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd) -{ - return fetchAndAddOrdered(valueToAdd); -} +#else // !Q_CC_INTEL && !Q_CC_GNU +# error "This compiler for x86_64 is not supported" +#endif // Q_CC_GNU || Q_CC_INTEL QT_END_NAMESPACE diff --git a/src/corelib/arch/s390/arch.pri b/src/corelib/arch/s390/arch.pri deleted file mode 100644 index 45cc57824b..0000000000 --- a/src/corelib/arch/s390/arch.pri +++ /dev/null @@ -1,3 +0,0 @@ -# -# S390 architecture -# diff --git a/src/corelib/arch/sh/qatomic_sh.cpp b/src/corelib/arch/sh/qatomic_sh.cpp index b552392b64..5cd1b593d8 100644 --- a/src/corelib/arch/sh/qatomic_sh.cpp +++ b/src/corelib/arch/sh/qatomic_sh.cpp @@ -1,8 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) +** Contact: http://www.qt-project.org/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** @@ -35,6 +34,7 @@ ** ** ** +** ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/corelib/arch/sh4a/arch.pri b/src/corelib/arch/sh4a/arch.pri deleted file mode 100644 index 19d5e040a9..0000000000 --- a/src/corelib/arch/sh4a/arch.pri +++ /dev/null @@ -1,3 +0,0 @@ -# -# SH-4A (Renesas SuperH) architecture -# diff --git a/src/corelib/arch/sparc/qatomic32.s b/src/corelib/arch/sparc/qatomic32.s index 5f695a9093..e4ea13262f 100644 --- a/src/corelib/arch/sparc/qatomic32.s +++ b/src/corelib/arch/sparc/qatomic32.s @@ -1,8 +1,7 @@ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! !! Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -!! All rights reserved. -!! Contact: Nokia Corporation (qt-info@nokia.com) +!! Contact: http://www.qt-project.org/ !! !! This file is part of the QtGui module of the Qt Toolkit. !! @@ -35,6 +34,7 @@ !! !! !! +!! !! $QT_END_LICENSE$ !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! diff --git a/src/corelib/arch/sparc/qatomic64.s b/src/corelib/arch/sparc/qatomic64.s index 448afbd34e..13c4fe3def 100644 --- a/src/corelib/arch/sparc/qatomic64.s +++ b/src/corelib/arch/sparc/qatomic64.s @@ -1,8 +1,7 @@ !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! !! Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -!! All rights reserved. -!! Contact: Nokia Corporation (qt-info@nokia.com) +!! Contact: http://www.qt-project.org/ !! !! This file is part of the QtGui module of the Qt Toolkit. !! @@ -35,6 +34,7 @@ !! !! !! +!! !! $QT_END_LICENSE$ !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! diff --git a/src/corelib/arch/sparc/qatomic_sparc.cpp b/src/corelib/arch/sparc/qatomic_sparc.cpp index 85848d04a0..638bc4a417 100644 --- a/src/corelib/arch/sparc/qatomic_sparc.cpp +++ b/src/corelib/arch/sparc/qatomic_sparc.cpp @@ -1,8 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) +** Contact: http://www.qt-project.org/ ** ** This file is part of the QtCore module of the Qt Toolkit. ** @@ -35,6 +34,7 @@ ** ** ** +** ** $QT_END_LICENSE$ ** ****************************************************************************/ diff --git a/src/corelib/arch/windows/arch.pri b/src/corelib/arch/windows/arch.pri deleted file mode 100644 index d42374b98f..0000000000 --- a/src/corelib/arch/windows/arch.pri +++ /dev/null @@ -1,3 +0,0 @@ -# -# Windows architecture -# diff --git a/src/corelib/arch/x86_64/arch.pri b/src/corelib/arch/x86_64/arch.pri deleted file mode 100644 index 4145b7b133..0000000000 --- a/src/corelib/arch/x86_64/arch.pri +++ /dev/null @@ -1,4 +0,0 @@ -# -# AMD64 architecture -# -solaris-cc*:SOURCES += $$QT_ARCH_CPP/qatomic_sun.s diff --git a/src/corelib/arch/x86_64/qatomic_sun.s b/src/corelib/arch/x86_64/qatomic_sun.s deleted file mode 100644 index 37969e61cb..0000000000 --- a/src/corelib/arch/x86_64/qatomic_sun.s +++ /dev/null @@ -1,91 +0,0 @@ - .code64 - - .globl q_atomic_increment - .type q_atomic_increment,@function - .section .text, "ax" - .align 16 -q_atomic_increment: - lock - incl (%rdi) - setne %al - ret - .size q_atomic_increment,.-q_atomic_increment - - .globl q_atomic_decrement - .type q_atomic_decrement,@function - .section .text, "ax" - .align 16 -q_atomic_decrement: - lock - decl (%rdi) - setne %al - ret - .size q_atomic_decrement,.-q_atomic_decrement - - .globl q_atomic_test_and_set_int - .type q_atomic_test_and_set_int, @function - .section .text, "ax" - .align 16 -q_atomic_test_and_set_int: - movl %esi,%eax - lock - cmpxchgl %edx,(%rdi) - movl $0,%eax - sete %al - ret - .size q_atomic_test_and_set_int, . - q_atomic_test_and_set_int - - .globl q_atomic_set_int - .type q_atomic_set_int,@function - .section .text, "ax" - .align 16 -q_atomic_set_int: - xchgl %esi,(%rdi) - movl %esi,%eax - ret - .size q_atomic_set_int,.-q_atomic_set_int - - .globl q_atomic_fetch_and_add_int - .type q_atomic_fetch_and_add_int,@function - .section .text, "ax" - .align 16 -q_atomic_fetch_and_add_int: - lock - xaddl %esi,(%rdi) - movl %esi, %eax - ret - .size q_atomic_fetch_and_add_int,.-q_atomic_fetch_and_add_int - - .globl q_atomic_test_and_set_ptr - .type q_atomic_test_and_set_ptr, @function - .section .text, "ax" - .align 16 -q_atomic_test_and_set_ptr: - movq %rsi,%rax - lock - cmpxchgq %rdx,(%rdi) - movq $0, %rax - sete %al - ret - .size q_atomic_test_and_set_ptr, . - q_atomic_test_and_set_ptr - - .globl q_atomic_set_ptr - .type q_atomic_set_ptr,@function - .section .text, "ax" - .align 16 -q_atomic_set_ptr: - xchgq %rsi,(%rdi) - movq %rsi,%rax - ret - .size q_atomic_set_ptr,.-q_atomic_set_ptr - - .globl q_atomic_fetch_and_add_ptr - .type q_atomic_fetch_and_add_ptr,@function - .section .text, "ax" - .align 16 -q_atomic_fetch_and_add_ptr: - lock - xaddq %rsi,(%rdi) - movq %rsi,%rax - ret - .size q_atomic_fetch_and_add_ptr,.-q_atomic_fetch_and_add_ptr |