summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorQt by Nokia <qt-info@nokia.com>2011-04-27 12:05:43 +0200
committeraxis <qt-info@nokia.com>2011-04-27 12:05:43 +0200
commit38be0d13830efd2d98281c645c3a60afe05ffece (patch)
tree6ea73f3ec77f7d153333779883e8120f82820abe /src/corelib
Initial import from the monolithic Qt.
This is the beginning of revision history for this module. If you want to look at revision history older than this, please refer to the Qt Git wiki for how to use Git history grafting. At the time of writing, this wiki is located here: http://qt.gitorious.org/qt/pages/GitIntroductionWithQt If you have already performed the grafting and you don't see any history beyond this commit, try running "git log" with the "--follow" argument. Branched from the monolithic repo, Qt master branch, at commit 896db169ea224deb96c59ce8af800d019de63f12
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/QtCore.dynlist10
-rw-r--r--src/corelib/animation/animation.pri25
-rw-r--r--src/corelib/animation/qabstractanimation.cpp1055
-rw-r--r--src/corelib/animation/qabstractanimation.h172
-rw-r--r--src/corelib/animation/qabstractanimation_p.h233
-rw-r--r--src/corelib/animation/qanimationgroup.cpp302
-rw-r--r--src/corelib/animation/qanimationgroup.h88
-rw-r--r--src/corelib/animation/qanimationgroup_p.h96
-rw-r--r--src/corelib/animation/qparallelanimationgroup.cpp347
-rw-r--r--src/corelib/animation/qparallelanimationgroup.h86
-rw-r--r--src/corelib/animation/qparallelanimationgroup_p.h93
-rw-r--r--src/corelib/animation/qpauseanimation.cpp155
-rw-r--r--src/corelib/animation/qpauseanimation.h84
-rw-r--r--src/corelib/animation/qpropertyanimation.cpp317
-rw-r--r--src/corelib/animation/qpropertyanimation.h89
-rw-r--r--src/corelib/animation/qpropertyanimation_p.h90
-rw-r--r--src/corelib/animation/qsequentialanimationgroup.cpp588
-rw-r--r--src/corelib/animation/qsequentialanimationgroup.h96
-rw-r--r--src/corelib/animation/qsequentialanimationgroup_p.h114
-rw-r--r--src/corelib/animation/qvariantanimation.cpp701
-rw-r--r--src/corelib/animation/qvariantanimation.h130
-rw-r--r--src/corelib/animation/qvariantanimation_p.h124
-rw-r--r--src/corelib/arch/alpha/arch.pri4
-rw-r--r--src/corelib/arch/alpha/qatomic_alpha.s239
-rw-r--r--src/corelib/arch/arch.pri38
-rw-r--r--src/corelib/arch/arm/arch.pri4
-rw-r--r--src/corelib/arch/arm/qatomic_arm.cpp72
-rw-r--r--src/corelib/arch/avr32/arch.pri3
-rw-r--r--src/corelib/arch/bfin/arch.pri3
-rw-r--r--src/corelib/arch/generic/arch.pri6
-rw-r--r--src/corelib/arch/generic/qatomic_generic_unix.cpp123
-rw-r--r--src/corelib/arch/generic/qatomic_generic_windows.cpp131
-rw-r--r--src/corelib/arch/i386/arch.pri4
-rw-r--r--src/corelib/arch/i386/qatomic_i386.s103
-rw-r--r--src/corelib/arch/ia64/arch.pri4
-rw-r--r--src/corelib/arch/ia64/qatomic_ia64.s74
-rw-r--r--src/corelib/arch/integrity/arch.pri3
-rw-r--r--src/corelib/arch/macosx/arch.pri6
-rw-r--r--src/corelib/arch/macosx/qatomic32_ppc.s169
-rw-r--r--src/corelib/arch/mips/arch.pri8
-rw-r--r--src/corelib/arch/mips/qatomic_mips32.s150
-rw-r--r--src/corelib/arch/mips/qatomic_mips64.s138
-rw-r--r--src/corelib/arch/parisc/arch.pri5
-rw-r--r--src/corelib/arch/parisc/q_ldcw.s62
-rw-r--r--src/corelib/arch/parisc/qatomic_parisc.cpp88
-rw-r--r--src/corelib/arch/powerpc/arch.pri10
-rw-r--r--src/corelib/arch/powerpc/qatomic32.s525
-rw-r--r--src/corelib/arch/powerpc/qatomic64.s533
-rw-r--r--src/corelib/arch/qatomic_alpha.h642
-rw-r--r--src/corelib/arch/qatomic_arch.h101
-rw-r--r--src/corelib/arch/qatomic_arm.h76
-rw-r--r--src/corelib/arch/qatomic_armv5.h431
-rw-r--r--src/corelib/arch/qatomic_armv6.h559
-rw-r--r--src/corelib/arch/qatomic_armv7.h61
-rw-r--r--src/corelib/arch/qatomic_avr32.h252
-rw-r--r--src/corelib/arch/qatomic_bfin.h343
-rw-r--r--src/corelib/arch/qatomic_bootstrap.h99
-rw-r--r--src/corelib/arch/qatomic_generic.h282
-rw-r--r--src/corelib/arch/qatomic_i386.h361
-rw-r--r--src/corelib/arch/qatomic_ia64.h813
-rw-r--r--src/corelib/arch/qatomic_integrity.h289
-rw-r--r--src/corelib/arch/qatomic_macosx.h57
-rw-r--r--src/corelib/arch/qatomic_mips.h892
-rw-r--r--src/corelib/arch/qatomic_parisc.h305
-rw-r--r--src/corelib/arch/qatomic_powerpc.h648
-rw-r--r--src/corelib/arch/qatomic_s390.h426
-rw-r--r--src/corelib/arch/qatomic_sh.h330
-rw-r--r--src/corelib/arch/qatomic_sh4a.h537
-rw-r--r--src/corelib/arch/qatomic_sparc.h525
-rw-r--r--src/corelib/arch/qatomic_symbian.h313
-rw-r--r--src/corelib/arch/qatomic_vxworks.h318
-rw-r--r--src/corelib/arch/qatomic_windows.h496
-rw-r--r--src/corelib/arch/qatomic_windowsce.h56
-rw-r--r--src/corelib/arch/qatomic_x86_64.h363
-rw-r--r--src/corelib/arch/s390/arch.pri3
-rw-r--r--src/corelib/arch/sh/arch.pri4
-rw-r--r--src/corelib/arch/sh/qatomic_sh.cpp72
-rw-r--r--src/corelib/arch/sh4a/arch.pri3
-rw-r--r--src/corelib/arch/sparc/arch.pri10
-rw-r--r--src/corelib/arch/sparc/qatomic32.s103
-rw-r--r--src/corelib/arch/sparc/qatomic64.s327
-rw-r--r--src/corelib/arch/sparc/qatomic_sparc.cpp92
-rw-r--r--src/corelib/arch/symbian/arch.pri18
-rw-r--r--src/corelib/arch/symbian/common_p.h106
-rw-r--r--src/corelib/arch/symbian/debugfunction.cpp1143
-rw-r--r--src/corelib/arch/symbian/dla_p.h969
-rw-r--r--src/corelib/arch/symbian/heap_hybrid.cpp3346
-rw-r--r--src/corelib/arch/symbian/heap_hybrid_p.h406
-rw-r--r--src/corelib/arch/symbian/page_alloc_p.h68
-rw-r--r--src/corelib/arch/symbian/qatomic_generic_armv6.cpp472
-rw-r--r--src/corelib/arch/symbian/qatomic_symbian.cpp527
-rw-r--r--src/corelib/arch/symbian/qt_heapsetup_symbian.cpp105
-rw-r--r--src/corelib/arch/symbian/qt_hybridheap_symbian_p.h178
-rw-r--r--src/corelib/arch/symbian/slab_p.h125
-rw-r--r--src/corelib/arch/vxworks/arch.pri6
-rw-r--r--src/corelib/arch/vxworks/qatomic_ppc.s415
-rw-r--r--src/corelib/arch/windows/arch.pri3
-rw-r--r--src/corelib/arch/x86_64/arch.pri4
-rw-r--r--src/corelib/arch/x86_64/qatomic_sun.s91
-rw-r--r--src/corelib/codecs/codecs.pri59
-rw-r--r--src/corelib/codecs/codecs.qdoc532
-rw-r--r--src/corelib/codecs/qfontlaocodec.cpp123
-rw-r--r--src/corelib/codecs/qfontlaocodec_p.h78
-rw-r--r--src/corelib/codecs/qiconvcodec.cpp548
-rw-r--r--src/corelib/codecs/qiconvcodec_p.h104
-rw-r--r--src/corelib/codecs/qisciicodec.cpp285
-rw-r--r--src/corelib/codecs/qisciicodec_p.h81
-rw-r--r--src/corelib/codecs/qlatincodec.cpp244
-rw-r--r--src/corelib/codecs/qlatincodec_p.h94
-rw-r--r--src/corelib/codecs/qsimplecodec.cpp735
-rw-r--r--src/corelib/codecs/qsimplecodec_p.h91
-rw-r--r--src/corelib/codecs/qtextcodec.cpp1878
-rw-r--r--src/corelib/codecs/qtextcodec.h198
-rw-r--r--src/corelib/codecs/qtextcodec_p.h111
-rw-r--r--src/corelib/codecs/qtextcodec_symbian.cpp689
-rw-r--r--src/corelib/codecs/qtextcodecplugin.cpp161
-rw-r--r--src/corelib/codecs/qtextcodecplugin.h96
-rw-r--r--src/corelib/codecs/qtsciicodec.cpp498
-rw-r--r--src/corelib/codecs/qtsciicodec_p.h106
-rw-r--r--src/corelib/codecs/qutfcodec.cpp670
-rw-r--r--src/corelib/codecs/qutfcodec_p.h170
-rw-r--r--src/corelib/concurrent/concurrent.pri42
-rw-r--r--src/corelib/concurrent/qfuture.cpp697
-rw-r--r--src/corelib/concurrent/qfuture.h278
-rw-r--r--src/corelib/concurrent/qfutureinterface.cpp565
-rw-r--r--src/corelib/concurrent/qfutureinterface.h313
-rw-r--r--src/corelib/concurrent/qfutureinterface_p.h167
-rw-r--r--src/corelib/concurrent/qfuturesynchronizer.cpp156
-rw-r--r--src/corelib/concurrent/qfuturesynchronizer.h121
-rw-r--r--src/corelib/concurrent/qfuturewatcher.cpp592
-rw-r--r--src/corelib/concurrent/qfuturewatcher.h222
-rw-r--r--src/corelib/concurrent/qfuturewatcher_p.h90
-rw-r--r--src/corelib/concurrent/qrunnable.cpp107
-rw-r--r--src/corelib/concurrent/qrunnable.h73
-rw-r--r--src/corelib/concurrent/qtconcurrentcompilertest.h65
-rw-r--r--src/corelib/concurrent/qtconcurrentexception.cpp223
-rw-r--r--src/corelib/concurrent/qtconcurrentexception.h128
-rw-r--r--src/corelib/concurrent/qtconcurrentfilter.cpp330
-rw-r--r--src/corelib/concurrent/qtconcurrentfilter.h736
-rw-r--r--src/corelib/concurrent/qtconcurrentfilterkernel.h351
-rw-r--r--src/corelib/concurrent/qtconcurrentfunctionwrappers.h173
-rw-r--r--src/corelib/concurrent/qtconcurrentiteratekernel.cpp199
-rw-r--r--src/corelib/concurrent/qtconcurrentiteratekernel.h340
-rw-r--r--src/corelib/concurrent/qtconcurrentmap.cpp402
-rw-r--r--src/corelib/concurrent/qtconcurrentmap.h780
-rw-r--r--src/corelib/concurrent/qtconcurrentmapkernel.h273
-rw-r--r--src/corelib/concurrent/qtconcurrentmedian.h130
-rw-r--r--src/corelib/concurrent/qtconcurrentreducekernel.h255
-rw-r--r--src/corelib/concurrent/qtconcurrentresultstore.cpp256
-rw-r--r--src/corelib/concurrent/qtconcurrentresultstore.h239
-rw-r--r--src/corelib/concurrent/qtconcurrentrun.cpp152
-rw-r--r--src/corelib/concurrent/qtconcurrentrun.h297
-rw-r--r--src/corelib/concurrent/qtconcurrentrunbase.h155
-rw-r--r--src/corelib/concurrent/qtconcurrentstoredfunctioncall.h1328
-rw-r--r--src/corelib/concurrent/qtconcurrentthreadengine.cpp299
-rw-r--r--src/corelib/concurrent/qtconcurrentthreadengine.h285
-rw-r--r--src/corelib/concurrent/qthreadpool.cpp651
-rw-r--r--src/corelib/concurrent/qthreadpool.h96
-rw-r--r--src/corelib/concurrent/qthreadpool_p.h107
-rw-r--r--src/corelib/corelib.pro48
-rw-r--r--src/corelib/eval.pri4
-rw-r--r--src/corelib/global/global.pri34
-rw-r--r--src/corelib/global/qconfig-dist.h50
-rw-r--r--src/corelib/global/qconfig-large.h173
-rw-r--r--src/corelib/global/qconfig-medium.h297
-rw-r--r--src/corelib/global/qconfig-minimal.h600
-rw-r--r--src/corelib/global/qconfig-nacl.h371
-rw-r--r--src/corelib/global/qconfig-small.h335
-rw-r--r--src/corelib/global/qendian.h370
-rw-r--r--src/corelib/global/qendian.qdoc154
-rw-r--r--src/corelib/global/qfeatures.h893
-rw-r--r--src/corelib/global/qfeatures.txt1487
-rw-r--r--src/corelib/global/qglobal.cpp3653
-rw-r--r--src/corelib/global/qglobal.h2767
-rw-r--r--src/corelib/global/qlibraryinfo.cpp555
-rw-r--r--src/corelib/global/qlibraryinfo.h94
-rw-r--r--src/corelib/global/qmalloc.cpp127
-rw-r--r--src/corelib/global/qnamespace.h1882
-rw-r--r--src/corelib/global/qnamespace.qdoc3008
-rw-r--r--src/corelib/global/qnumeric.cpp93
-rw-r--r--src/corelib/global/qnumeric.h71
-rw-r--r--src/corelib/global/qnumeric_p.h243
-rw-r--r--src/corelib/global/qt_pch.h67
-rw-r--r--src/corelib/global/qt_windows.h151
-rw-r--r--src/corelib/io/io.pri119
-rw-r--r--src/corelib/io/qabstractfileengine.cpp1233
-rw-r--r--src/corelib/io/qabstractfileengine.h248
-rw-r--r--src/corelib/io/qabstractfileengine_p.h81
-rw-r--r--src/corelib/io/qbuffer.cpp493
-rw-r--r--src/corelib/io/qbuffer.h112
-rw-r--r--src/corelib/io/qdatastream.cpp1325
-rw-r--r--src/corelib/io/qdatastream.h440
-rw-r--r--src/corelib/io/qdatastream_p.h72
-rw-r--r--src/corelib/io/qdataurl.cpp101
-rw-r--r--src/corelib/io/qdataurl_p.h67
-rw-r--r--src/corelib/io/qdebug.cpp307
-rw-r--r--src/corelib/io/qdebug.h300
-rw-r--r--src/corelib/io/qdir.cpp2386
-rw-r--r--src/corelib/io/qdir.h271
-rw-r--r--src/corelib/io/qdir_p.h98
-rw-r--r--src/corelib/io/qdiriterator.cpp561
-rw-r--r--src/corelib/io/qdiriterator.h97
-rw-r--r--src/corelib/io/qfile.cpp1884
-rw-r--r--src/corelib/io/qfile.h218
-rw-r--r--src/corelib/io/qfile_p.h99
-rw-r--r--src/corelib/io/qfileinfo.cpp1399
-rw-r--r--src/corelib/io/qfileinfo.h206
-rw-r--r--src/corelib/io/qfileinfo_p.h160
-rw-r--r--src/corelib/io/qfilesystemengine.cpp391
-rw-r--r--src/corelib/io/qfilesystemengine_mac.cpp48
-rw-r--r--src/corelib/io/qfilesystemengine_p.h133
-rw-r--r--src/corelib/io/qfilesystemengine_symbian.cpp408
-rw-r--r--src/corelib/io/qfilesystemengine_unix.cpp660
-rw-r--r--src/corelib/io/qfilesystemengine_win.cpp1218
-rw-r--r--src/corelib/io/qfilesystementry.cpp383
-rw-r--r--src/corelib/io/qfilesystementry_p.h126
-rw-r--r--src/corelib/io/qfilesystemiterator_p.h120
-rw-r--r--src/corelib/io/qfilesystemiterator_symbian.cpp127
-rw-r--r--src/corelib/io/qfilesystemiterator_unix.cpp117
-rw-r--r--src/corelib/io/qfilesystemiterator_win.cpp148
-rw-r--r--src/corelib/io/qfilesystemmetadata_p.h400
-rw-r--r--src/corelib/io/qfilesystemwatcher.cpp640
-rw-r--r--src/corelib/io/qfilesystemwatcher.h89
-rw-r--r--src/corelib/io/qfilesystemwatcher_dnotify.cpp461
-rw-r--r--src/corelib/io/qfilesystemwatcher_dnotify_p.h131
-rw-r--r--src/corelib/io/qfilesystemwatcher_fsevents.cpp492
-rw-r--r--src/corelib/io/qfilesystemwatcher_fsevents_p.h132
-rw-r--r--src/corelib/io/qfilesystemwatcher_inotify.cpp410
-rw-r--r--src/corelib/io/qfilesystemwatcher_inotify_p.h95
-rw-r--r--src/corelib/io/qfilesystemwatcher_kqueue.cpp334
-rw-r--r--src/corelib/io/qfilesystemwatcher_kqueue_p.h97
-rw-r--r--src/corelib/io/qfilesystemwatcher_p.h121
-rw-r--r--src/corelib/io/qfilesystemwatcher_symbian.cpp273
-rw-r--r--src/corelib/io/qfilesystemwatcher_symbian_p.h130
-rw-r--r--src/corelib/io/qfilesystemwatcher_win.cpp425
-rw-r--r--src/corelib/io/qfilesystemwatcher_win_p.h166
-rw-r--r--src/corelib/io/qfsfileengine.cpp965
-rw-r--r--src/corelib/io/qfsfileengine.h129
-rw-r--r--src/corelib/io/qfsfileengine_iterator.cpp106
-rw-r--r--src/corelib/io/qfsfileengine_iterator_p.h91
-rw-r--r--src/corelib/io/qfsfileengine_p.h202
-rw-r--r--src/corelib/io/qfsfileengine_unix.cpp1108
-rw-r--r--src/corelib/io/qfsfileengine_win.cpp1008
-rw-r--r--src/corelib/io/qiodevice.cpp1846
-rw-r--r--src/corelib/io/qiodevice.h254
-rw-r--r--src/corelib/io/qiodevice_p.h245
-rw-r--r--src/corelib/io/qnoncontiguousbytedevice.cpp545
-rw-r--r--src/corelib/io/qnoncontiguousbytedevice_p.h190
-rw-r--r--src/corelib/io/qprocess.cpp2371
-rw-r--r--src/corelib/io/qprocess.h245
-rw-r--r--src/corelib/io/qprocess_p.h260
-rw-r--r--src/corelib/io/qprocess_symbian.cpp1067
-rw-r--r--src/corelib/io/qprocess_unix.cpp1297
-rw-r--r--src/corelib/io/qprocess_win.cpp855
-rw-r--r--src/corelib/io/qresource.cpp1496
-rw-r--r--src/corelib/io/qresource.h104
-rw-r--r--src/corelib/io/qresource_iterator.cpp90
-rw-r--r--src/corelib/io/qresource_iterator_p.h80
-rw-r--r--src/corelib/io/qresource_p.h119
-rw-r--r--src/corelib/io/qsettings.cpp3843
-rw-r--r--src/corelib/io/qsettings.h313
-rw-r--r--src/corelib/io/qsettings_mac.cpp654
-rw-r--r--src/corelib/io/qsettings_p.h316
-rw-r--r--src/corelib/io/qsettings_win.cpp847
-rw-r--r--src/corelib/io/qtemporaryfile.cpp713
-rw-r--r--src/corelib/io/qtemporaryfile.h108
-rw-r--r--src/corelib/io/qtextstream.cpp3413
-rw-r--r--src/corelib/io/qtextstream.h377
-rw-r--r--src/corelib/io/qurl.cpp6544
-rw-r--r--src/corelib/io/qurl.h302
-rw-r--r--src/corelib/io/qwindowspipewriter.cpp171
-rw-r--r--src/corelib/io/qwindowspipewriter_p.h162
-rw-r--r--src/corelib/kernel/kernel.pri164
-rw-r--r--src/corelib/kernel/qabstracteventdispatcher.cpp556
-rw-r--r--src/corelib/kernel/qabstracteventdispatcher.h107
-rw-r--r--src/corelib/kernel/qabstracteventdispatcher_p.h79
-rw-r--r--src/corelib/kernel/qabstractitemmodel.cpp3454
-rw-r--r--src/corelib/kernel/qabstractitemmodel.h410
-rw-r--r--src/corelib/kernel/qabstractitemmodel_p.h176
-rw-r--r--src/corelib/kernel/qbasictimer.cpp138
-rw-r--r--src/corelib/kernel/qbasictimer.h74
-rw-r--r--src/corelib/kernel/qcore_mac.cpp82
-rw-r--r--src/corelib/kernel/qcore_mac_p.h163
-rw-r--r--src/corelib/kernel/qcore_symbian_p.cpp317
-rw-r--r--src/corelib/kernel/qcore_symbian_p.h282
-rw-r--r--src/corelib/kernel/qcore_unix.cpp106
-rw-r--r--src/corelib/kernel/qcore_unix_p.h333
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp2730
-rw-r--r--src/corelib/kernel/qcoreapplication.h297
-rw-r--r--src/corelib/kernel/qcoreapplication_mac.cpp66
-rw-r--r--src/corelib/kernel/qcoreapplication_p.h146
-rw-r--r--src/corelib/kernel/qcoreapplication_win.cpp1060
-rw-r--r--src/corelib/kernel/qcorecmdlineargs_p.h171
-rw-r--r--src/corelib/kernel/qcoreevent.cpp612
-rw-r--r--src/corelib/kernel/qcoreevent.h396
-rw-r--r--src/corelib/kernel/qcoreglobaldata.cpp53
-rw-r--r--src/corelib/kernel/qcoreglobaldata_p.h72
-rw-r--r--src/corelib/kernel/qcrashhandler.cpp423
-rw-r--r--src/corelib/kernel/qcrashhandler_p.h81
-rw-r--r--src/corelib/kernel/qeventdispatcher_glib.cpp601
-rw-r--r--src/corelib/kernel/qeventdispatcher_glib_p.h119
-rw-r--r--src/corelib/kernel/qeventdispatcher_symbian.cpp1310
-rw-r--r--src/corelib/kernel/qeventdispatcher_symbian_p.h327
-rw-r--r--src/corelib/kernel/qeventdispatcher_unix.cpp979
-rw-r--r--src/corelib/kernel/qeventdispatcher_unix_p.h208
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp1158
-rw-r--r--src/corelib/kernel/qeventdispatcher_win_p.h110
-rw-r--r--src/corelib/kernel/qeventloop.cpp329
-rw-r--r--src/corelib/kernel/qeventloop.h101
-rw-r--r--src/corelib/kernel/qfunctions_nacl.cpp156
-rw-r--r--src/corelib/kernel/qfunctions_nacl.h97
-rw-r--r--src/corelib/kernel/qfunctions_p.h79
-rw-r--r--src/corelib/kernel/qfunctions_vxworks.cpp202
-rw-r--r--src/corelib/kernel/qfunctions_vxworks.h153
-rw-r--r--src/corelib/kernel/qfunctions_wince.cpp451
-rw-r--r--src/corelib/kernel/qfunctions_wince.h397
-rw-r--r--src/corelib/kernel/qmath.cpp305
-rw-r--r--src/corelib/kernel/qmath.h288
-rw-r--r--src/corelib/kernel/qmath.qdoc155
-rw-r--r--src/corelib/kernel/qmetaobject.cpp2778
-rw-r--r--src/corelib/kernel/qmetaobject.h242
-rw-r--r--src/corelib/kernel/qmetaobject_p.h326
-rw-r--r--src/corelib/kernel/qmetatype.cpp1509
-rw-r--r--src/corelib/kernel/qmetatype.h416
-rw-r--r--src/corelib/kernel/qmimedata.cpp627
-rw-r--r--src/corelib/kernel/qmimedata.h104
-rw-r--r--src/corelib/kernel/qobject.cpp4310
-rw-r--r--src/corelib/kernel/qobject.h411
-rw-r--r--src/corelib/kernel/qobject_p.h305
-rw-r--r--src/corelib/kernel/qobjectcleanuphandler.cpp148
-rw-r--r--src/corelib/kernel/qobjectcleanuphandler.h78
-rw-r--r--src/corelib/kernel/qobjectdefs.h506
-rw-r--r--src/corelib/kernel/qpointer.cpp270
-rw-r--r--src/corelib/kernel/qpointer.h168
-rw-r--r--src/corelib/kernel/qsharedmemory.cpp612
-rw-r--r--src/corelib/kernel/qsharedmemory.h121
-rw-r--r--src/corelib/kernel/qsharedmemory_p.h179
-rw-r--r--src/corelib/kernel/qsharedmemory_symbian.cpp173
-rw-r--r--src/corelib/kernel/qsharedmemory_unix.cpp302
-rw-r--r--src/corelib/kernel/qsharedmemory_win.cpp195
-rw-r--r--src/corelib/kernel/qsignalmapper.cpp321
-rw-r--r--src/corelib/kernel/qsignalmapper.h100
-rw-r--r--src/corelib/kernel/qsocketnotifier.cpp323
-rw-r--r--src/corelib/kernel/qsocketnotifier.h93
-rw-r--r--src/corelib/kernel/qsystemerror.cpp220
-rw-r--r--src/corelib/kernel/qsystemerror_p.h107
-rw-r--r--src/corelib/kernel/qsystemsemaphore.cpp363
-rw-r--r--src/corelib/kernel/qsystemsemaphore.h103
-rw-r--r--src/corelib/kernel/qsystemsemaphore_p.h118
-rw-r--r--src/corelib/kernel/qsystemsemaphore_symbian.cpp138
-rw-r--r--src/corelib/kernel/qsystemsemaphore_unix.cpp238
-rw-r--r--src/corelib/kernel/qsystemsemaphore_win.cpp135
-rw-r--r--src/corelib/kernel/qtcore_eval.cpp571
-rw-r--r--src/corelib/kernel/qtimer.cpp394
-rw-r--r--src/corelib/kernel/qtimer.h116
-rw-r--r--src/corelib/kernel/qtranslator.cpp979
-rw-r--r--src/corelib/kernel/qtranslator.h104
-rw-r--r--src/corelib/kernel/qtranslator_p.h79
-rw-r--r--src/corelib/kernel/qvariant.cpp3237
-rw-r--r--src/corelib/kernel/qvariant.h618
-rw-r--r--src/corelib/kernel/qvariant_p.h153
-rw-r--r--src/corelib/kernel/qwineventnotifier_p.cpp134
-rw-r--r--src/corelib/kernel/qwineventnotifier_p.h94
-rw-r--r--src/corelib/plugin/plugin.pri35
-rw-r--r--src/corelib/plugin/qelfparser_p.cpp240
-rw-r--r--src/corelib/plugin/qelfparser_p.h108
-rw-r--r--src/corelib/plugin/qfactoryinterface.h67
-rw-r--r--src/corelib/plugin/qfactoryloader.cpp269
-rw-r--r--src/corelib/plugin/qfactoryloader_p.h93
-rw-r--r--src/corelib/plugin/qlibrary.cpp1295
-rw-r--r--src/corelib/plugin/qlibrary.h120
-rw-r--r--src/corelib/plugin/qlibrary_p.h124
-rw-r--r--src/corelib/plugin/qlibrary_unix.cpp305
-rw-r--r--src/corelib/plugin/qlibrary_win.cpp131
-rw-r--r--src/corelib/plugin/qplugin.h152
-rw-r--r--src/corelib/plugin/qplugin.qdoc121
-rw-r--r--src/corelib/plugin/qpluginloader.cpp434
-rw-r--r--src/corelib/plugin/qpluginloader.h100
-rw-r--r--src/corelib/plugin/qsystemlibrary.cpp141
-rw-r--r--src/corelib/plugin/qsystemlibrary_p.h110
-rw-r--r--src/corelib/plugin/quuid.cpp676
-rw-r--r--src/corelib/plugin/quuid.h190
-rw-r--r--src/corelib/statemachine/qabstractstate.cpp215
-rw-r--r--src/corelib/statemachine/qabstractstate.h97
-rw-r--r--src/corelib/statemachine/qabstractstate_p.h95
-rw-r--r--src/corelib/statemachine/qabstracttransition.cpp335
-rw-r--r--src/corelib/statemachine/qabstracttransition.h118
-rw-r--r--src/corelib/statemachine/qabstracttransition_p.h92
-rw-r--r--src/corelib/statemachine/qeventtransition.cpp260
-rw-r--r--src/corelib/statemachine/qeventtransition.h95
-rw-r--r--src/corelib/statemachine/qeventtransition_p.h79
-rw-r--r--src/corelib/statemachine/qfinalstate.cpp140
-rw-r--r--src/corelib/statemachine/qfinalstate.h80
-rw-r--r--src/corelib/statemachine/qhistorystate.cpp230
-rw-r--r--src/corelib/statemachine/qhistorystate.h95
-rw-r--r--src/corelib/statemachine/qhistorystate_p.h79
-rw-r--r--src/corelib/statemachine/qsignaleventgenerator_p.h78
-rw-r--r--src/corelib/statemachine/qsignaltransition.cpp264
-rw-r--r--src/corelib/statemachine/qsignaltransition.h90
-rw-r--r--src/corelib/statemachine/qsignaltransition_p.h82
-rw-r--r--src/corelib/statemachine/qstate.cpp526
-rw-r--r--src/corelib/statemachine/qstate.h122
-rw-r--r--src/corelib/statemachine/qstate_p.h112
-rw-r--r--src/corelib/statemachine/qstatemachine.cpp2401
-rw-r--r--src/corelib/statemachine/qstatemachine.h196
-rw-r--r--src/corelib/statemachine/qstatemachine_p.h250
-rw-r--r--src/corelib/statemachine/statemachine.pri28
-rw-r--r--src/corelib/thread/qatomic.cpp1125
-rw-r--r--src/corelib/thread/qatomic.h227
-rw-r--r--src/corelib/thread/qbasicatomic.h230
-rw-r--r--src/corelib/thread/qmutex.cpp515
-rw-r--r--src/corelib/thread/qmutex.h248
-rw-r--r--src/corelib/thread/qmutex_p.h107
-rw-r--r--src/corelib/thread/qmutex_symbian.cpp101
-rw-r--r--src/corelib/thread/qmutex_unix.cpp209
-rw-r--r--src/corelib/thread/qmutex_win.cpp75
-rw-r--r--src/corelib/thread/qmutexpool.cpp156
-rw-r--r--src/corelib/thread/qmutexpool_p.h93
-rw-r--r--src/corelib/thread/qorderedmutexlocker_p.h121
-rw-r--r--src/corelib/thread/qreadwritelock.cpp581
-rw-r--r--src/corelib/thread/qreadwritelock.h239
-rw-r--r--src/corelib/thread/qreadwritelock_p.h87
-rw-r--r--src/corelib/thread/qsemaphore.cpp240
-rw-r--r--src/corelib/thread/qsemaphore.h83
-rw-r--r--src/corelib/thread/qthread.cpp772
-rw-r--r--src/corelib/thread/qthread.h166
-rw-r--r--src/corelib/thread/qthread_p.h237
-rw-r--r--src/corelib/thread/qthread_symbian.cpp609
-rw-r--r--src/corelib/thread/qthread_unix.cpp716
-rw-r--r--src/corelib/thread/qthread_win.cpp637
-rw-r--r--src/corelib/thread/qthreadstorage.cpp329
-rw-r--r--src/corelib/thread/qthreadstorage.h164
-rw-r--r--src/corelib/thread/qwaitcondition.h105
-rw-r--r--src/corelib/thread/qwaitcondition.qdoc173
-rw-r--r--src/corelib/thread/qwaitcondition_symbian.cpp196
-rw-r--r--src/corelib/thread/qwaitcondition_unix.cpp192
-rw-r--r--src/corelib/thread/qwaitcondition_win.cpp233
-rw-r--r--src/corelib/thread/thread.pri41
-rw-r--r--src/corelib/tools/qalgorithms.h526
-rw-r--r--src/corelib/tools/qalgorithms.qdoc637
-rw-r--r--src/corelib/tools/qbitarray.cpp738
-rw-r--r--src/corelib/tools/qbitarray.h180
-rw-r--r--src/corelib/tools/qbytearray.cpp4394
-rw-r--r--src/corelib/tools/qbytearray.h622
-rw-r--r--src/corelib/tools/qbytearraymatcher.cpp324
-rw-r--r--src/corelib/tools/qbytearraymatcher.h103
-rw-r--r--src/corelib/tools/qbytedata_p.h220
-rw-r--r--src/corelib/tools/qcache.h217
-rw-r--r--src/corelib/tools/qcache.qdoc230
-rw-r--r--src/corelib/tools/qchar.cpp1654
-rw-r--r--src/corelib/tools/qchar.h404
-rw-r--r--src/corelib/tools/qcontainerfwd.h71
-rw-r--r--src/corelib/tools/qcontiguouscache.cpp474
-rw-r--r--src/corelib/tools/qcontiguouscache.h466
-rw-r--r--src/corelib/tools/qcryptographichash.cpp200
-rw-r--r--src/corelib/tools/qcryptographichash.h84
-rw-r--r--src/corelib/tools/qdatetime.cpp5881
-rw-r--r--src/corelib/tools/qdatetime.h340
-rw-r--r--src/corelib/tools/qdatetime_p.h289
-rw-r--r--src/corelib/tools/qeasingcurve.cpp937
-rw-r--r--src/corelib/tools/qeasingcurve.h125
-rw-r--r--src/corelib/tools/qelapsedtimer.cpp264
-rw-r--r--src/corelib/tools/qelapsedtimer.h95
-rw-r--r--src/corelib/tools/qelapsedtimer_generic.cpp194
-rw-r--r--src/corelib/tools/qelapsedtimer_mac.cpp132
-rw-r--r--src/corelib/tools/qelapsedtimer_symbian.cpp131
-rw-r--r--src/corelib/tools/qelapsedtimer_unix.cpp209
-rw-r--r--src/corelib/tools/qelapsedtimer_win.cpp183
-rw-r--r--src/corelib/tools/qharfbuzz.cpp140
-rw-r--r--src/corelib/tools/qharfbuzz_p.h77
-rw-r--r--src/corelib/tools/qhash.cpp1914
-rw-r--r--src/corelib/tools/qhash.h1043
-rw-r--r--src/corelib/tools/qiterator.h202
-rw-r--r--src/corelib/tools/qiterator.qdoc1417
-rw-r--r--src/corelib/tools/qline.cpp867
-rw-r--r--src/corelib/tools/qline.h424
-rw-r--r--src/corelib/tools/qlinkedlist.cpp1170
-rw-r--r--src/corelib/tools/qlinkedlist.h525
-rw-r--r--src/corelib/tools/qlist.cpp1919
-rw-r--r--src/corelib/tools/qlist.h900
-rw-r--r--src/corelib/tools/qlocale.cpp3281
-rw-r--r--src/corelib/tools/qlocale.h818
-rw-r--r--src/corelib/tools/qlocale.qdoc905
-rw-r--r--src/corelib/tools/qlocale_data_p.h6518
-rw-r--r--src/corelib/tools/qlocale_icu.cpp224
-rw-r--r--src/corelib/tools/qlocale_mac.mm463
-rw-r--r--src/corelib/tools/qlocale_p.h283
-rw-r--r--src/corelib/tools/qlocale_symbian.cpp929
-rw-r--r--src/corelib/tools/qlocale_tools.cpp2961
-rw-r--r--src/corelib/tools/qlocale_tools_p.h122
-rw-r--r--src/corelib/tools/qlocale_unix.cpp226
-rw-r--r--src/corelib/tools/qlocale_win.cpp988
-rw-r--r--src/corelib/tools/qmap.cpp1646
-rw-r--r--src/corelib/tools/qmap.h1090
-rw-r--r--src/corelib/tools/qmargins.cpp167
-rw-r--r--src/corelib/tools/qmargins.h147
-rw-r--r--src/corelib/tools/qpair.h127
-rw-r--r--src/corelib/tools/qpair.qdoc215
-rw-r--r--src/corelib/tools/qpodlist_p.h115
-rw-r--r--src/corelib/tools/qpoint.cpp741
-rw-r--r--src/corelib/tools/qpoint.h389
-rw-r--r--src/corelib/tools/qqueue.cpp137
-rw-r--r--src/corelib/tools/qqueue.h70
-rw-r--r--src/corelib/tools/qrect.cpp2465
-rw-r--r--src/corelib/tools/qrect.h858
-rw-r--r--src/corelib/tools/qregexp.cpp4503
-rw-r--r--src/corelib/tools/qregexp.h169
-rw-r--r--src/corelib/tools/qringbuffer_p.h451
-rw-r--r--src/corelib/tools/qscopedpointer.cpp283
-rw-r--r--src/corelib/tools/qscopedpointer.h245
-rw-r--r--src/corelib/tools/qscopedpointer_p.h151
-rw-r--r--src/corelib/tools/qscopedvaluerollback.cpp84
-rw-r--r--src/corelib/tools/qscopedvaluerollback.h81
-rw-r--r--src/corelib/tools/qset.h371
-rw-r--r--src/corelib/tools/qset.qdoc946
-rw-r--r--src/corelib/tools/qshareddata.cpp568
-rw-r--r--src/corelib/tools/qshareddata.h286
-rw-r--r--src/corelib/tools/qsharedpointer.cpp1501
-rw-r--r--src/corelib/tools/qsharedpointer.h152
-rw-r--r--src/corelib/tools/qsharedpointer_impl.h898
-rw-r--r--src/corelib/tools/qsimd.cpp413
-rw-r--r--src/corelib/tools/qsimd_p.h172
-rw-r--r--src/corelib/tools/qsize.cpp828
-rw-r--r--src/corelib/tools/qsize.h368
-rw-r--r--src/corelib/tools/qstack.cpp137
-rw-r--r--src/corelib/tools/qstack.h83
-rw-r--r--src/corelib/tools/qstring.cpp9129
-rw-r--r--src/corelib/tools/qstring.h1295
-rw-r--r--src/corelib/tools/qstringbuilder.cpp193
-rw-r--r--src/corelib/tools/qstringbuilder.h455
-rw-r--r--src/corelib/tools/qstringlist.cpp692
-rw-r--r--src/corelib/tools/qstringlist.h262
-rw-r--r--src/corelib/tools/qstringmatcher.cpp322
-rw-r--r--src/corelib/tools/qstringmatcher.h103
-rw-r--r--src/corelib/tools/qtextboundaryfinder.cpp479
-rw-r--r--src/corelib/tools/qtextboundaryfinder.h114
-rw-r--r--src/corelib/tools/qtimeline.cpp787
-rw-r--r--src/corelib/tools/qtimeline.h147
-rw-r--r--src/corelib/tools/qtools_p.h65
-rw-r--r--src/corelib/tools/qunicodetables.cpp9486
-rw-r--r--src/corelib/tools/qunicodetables_p.h232
-rw-r--r--src/corelib/tools/qvarlengtharray.h404
-rw-r--r--src/corelib/tools/qvarlengtharray.qdoc547
-rw-r--r--src/corelib/tools/qvector.cpp1017
-rw-r--r--src/corelib/tools/qvector.h829
-rw-r--r--src/corelib/tools/qvsnprintf.cpp133
-rw-r--r--src/corelib/tools/tools.pri124
-rw-r--r--src/corelib/xml/.gitignore1
-rwxr-xr-xsrc/corelib/xml/make-parser.sh53
-rw-r--r--src/corelib/xml/qxmlstream.cpp3954
-rw-r--r--src/corelib/xml/qxmlstream.g1847
-rw-r--r--src/corelib/xml/qxmlstream.h491
-rw-r--r--src/corelib/xml/qxmlstream_p.h1965
-rw-r--r--src/corelib/xml/qxmlutils.cpp390
-rw-r--r--src/corelib/xml/qxmlutils_p.h92
-rw-r--r--src/corelib/xml/xml.pri10
556 files changed, 282993 insertions, 0 deletions
diff --git a/src/corelib/QtCore.dynlist b/src/corelib/QtCore.dynlist
new file mode 100644
index 0000000000..51e4c5a34e
--- /dev/null
+++ b/src/corelib/QtCore.dynlist
@@ -0,0 +1,10 @@
+{
+ extern "C" {
+ "qt_startup_hook";
+ "qt_addObject";
+ "qt_removeObject";
+ };
+ extern "C++" {
+ "QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>)";
+ };
+};
diff --git a/src/corelib/animation/animation.pri b/src/corelib/animation/animation.pri
new file mode 100644
index 0000000000..cb7850c7d6
--- /dev/null
+++ b/src/corelib/animation/animation.pri
@@ -0,0 +1,25 @@
+# Qt core animation module
+
+HEADERS += \
+ animation/qabstractanimation.h \
+ animation/qabstractanimation_p.h \
+ animation/qvariantanimation.h \
+ animation/qvariantanimation_p.h \
+ animation/qpropertyanimation.h \
+ animation/qpropertyanimation_p.h \
+ animation/qanimationgroup.h \
+ animation/qanimationgroup_p.h \
+ animation/qsequentialanimationgroup.h \
+ animation/qsequentialanimationgroup_p.h \
+ animation/qparallelanimationgroup.h \
+ animation/qparallelanimationgroup_p.h \
+ animation/qpauseanimation.h
+
+SOURCES += \
+ animation/qabstractanimation.cpp \
+ animation/qvariantanimation.cpp \
+ animation/qpropertyanimation.cpp \
+ animation/qanimationgroup.cpp \
+ animation/qsequentialanimationgroup.cpp \
+ animation/qparallelanimationgroup.cpp \
+ animation/qpauseanimation.cpp
diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp
new file mode 100644
index 0000000000..602cf8a6fd
--- /dev/null
+++ b/src/corelib/animation/qabstractanimation.cpp
@@ -0,0 +1,1055 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QAbstractAnimation
+ \ingroup animation
+ \brief The QAbstractAnimation class is the base of all animations.
+ \since 4.6
+
+ The class defines the functions for the functionality shared by
+ all animations. By inheriting this class, you can create custom
+ animations that plug into the rest of the animation framework.
+
+ The progress of an animation is given by its current time
+ (currentLoopTime()), which is measured in milliseconds from the start
+ of the animation (0) to its end (duration()). The value is updated
+ automatically while the animation is running. It can also be set
+ directly with setCurrentTime().
+
+ At any point an animation is in one of three states:
+ \l{QAbstractAnimation::}{Running},
+ \l{QAbstractAnimation::}{Stopped}, or
+ \l{QAbstractAnimation::}{Paused}--as defined by the
+ \l{QAbstractAnimation::}{State} enum. The current state can be
+ changed by calling start(), stop(), pause(), or resume(). An
+ animation will always reset its \l{currentTime()}{current time}
+ when it is started. If paused, it will continue with the same
+ current time when resumed. When an animation is stopped, it cannot
+ be resumed, but will keep its current time (until started again).
+ QAbstractAnimation will emit stateChanged() whenever its state
+ changes.
+
+ An animation can loop any number of times by setting the loopCount
+ property. When an animation's current time reaches its duration(),
+ it will reset the current time and keep running. A loop count of 1
+ (the default value) means that the animation will run one time.
+ Note that a duration of -1 means that the animation will run until
+ stopped; the current time will increase indefinitely. When the
+ current time equals duration() and the animation is in its
+ final loop, the \l{QAbstractAnimation::}{Stopped} state is
+ entered, and the finished() signal is emitted.
+
+ QAbstractAnimation provides pure virtual functions used by
+ subclasses to track the progress of the animation: duration() and
+ updateCurrentTime(). The duration() function lets you report a
+ duration for the animation (as discussed above). The animation
+ framework calls updateCurrentTime() when current time has changed.
+ By reimplementing this function, you can track the animation
+ progress. Note that neither the interval between calls nor the
+ number of calls to this function are defined; though, it will
+ normally be 60 updates per second.
+
+ By reimplementing updateState(), you can track the animation's
+ state changes, which is particularly useful for animations that
+ are not driven by time.
+
+ \sa QVariantAnimation, QPropertyAnimation, QAnimationGroup, {The Animation Framework}
+*/
+
+/*!
+ \enum QAbstractAnimation::DeletionPolicy
+
+ \value KeepWhenStopped The animation will not be deleted when stopped.
+ \value DeleteWhenStopped The animation will be automatically deleted when
+ stopped.
+*/
+
+/*!
+ \fn QAbstractAnimation::finished()
+
+ QAbstractAnimation emits this signal after the animation has stopped and
+ has reached the end.
+
+ This signal is emitted after stateChanged().
+
+ \sa stateChanged()
+*/
+
+/*!
+ \fn QAbstractAnimation::stateChanged(QAbstractAnimation::State newState, QAbstractAnimation::State oldState)
+
+ QAbstractAnimation emits this signal whenever the state of the animation has
+ changed from \a oldState to \a newState. This signal is emitted after the virtual
+ updateState() function is called.
+
+ \sa updateState()
+*/
+
+/*!
+ \fn QAbstractAnimation::currentLoopChanged(int currentLoop)
+
+ QAbstractAnimation emits this signal whenever the current loop
+ changes. \a currentLoop is the current loop.
+
+ \sa currentLoop(), loopCount()
+*/
+
+/*!
+ \fn QAbstractAnimation::directionChanged(QAbstractAnimation::Direction newDirection);
+
+ QAbstractAnimation emits this signal whenever the direction has been
+ changed. \a newDirection is the new direction.
+
+ \sa direction
+*/
+
+#include "qabstractanimation.h"
+#include "qanimationgroup.h"
+
+#include <QtCore/qdebug.h>
+
+#include "qabstractanimation_p.h"
+
+#include <QtCore/qmath.h>
+#include <QtCore/qthreadstorage.h>
+#include <QtCore/qcoreevent.h>
+#include <QtCore/qpointer.h>
+
+#ifndef QT_NO_ANIMATION
+
+#define DEFAULT_TIMER_INTERVAL 16
+#define STARTSTOP_TIMER_DELAY 0
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_THREAD
+Q_GLOBAL_STATIC(QThreadStorage<QUnifiedTimer *>, unifiedTimer)
+#endif
+
+QUnifiedTimer::QUnifiedTimer() :
+ QObject(), defaultDriver(this), lastTick(0), timingInterval(DEFAULT_TIMER_INTERVAL),
+ currentAnimationIdx(0), insideTick(false), consistentTiming(false), slowMode(false),
+ slowdownFactor(5.0f), isPauseTimerActive(false), runningLeafAnimations(0)
+{
+ time.invalidate();
+ driver = &defaultDriver;
+}
+
+
+QUnifiedTimer *QUnifiedTimer::instance(bool create)
+{
+ QUnifiedTimer *inst;
+#ifndef QT_NO_THREAD
+ if (create && !unifiedTimer()->hasLocalData()) {
+ inst = new QUnifiedTimer;
+ unifiedTimer()->setLocalData(inst);
+ } else {
+ inst = unifiedTimer()->localData();
+ }
+#else
+ static QUnifiedTimer unifiedTimer;
+ inst = &unifiedTimer;
+#endif
+ return inst;
+}
+
+QUnifiedTimer *QUnifiedTimer::instance()
+{
+ return instance(true);
+}
+
+void QUnifiedTimer::ensureTimerUpdate()
+{
+ QUnifiedTimer *inst = QUnifiedTimer::instance(false);
+ if (inst && inst->isPauseTimerActive)
+ inst->updateAnimationsTime();
+}
+
+void QUnifiedTimer::updateAnimationsTime()
+{
+ //setCurrentTime can get this called again while we're the for loop. At least with pauseAnimations
+ if(insideTick)
+ return;
+
+ qint64 totalElapsed = time.elapsed();
+ // ignore consistentTiming in case the pause timer is active
+ int delta = (consistentTiming && !isPauseTimerActive) ?
+ timingInterval : totalElapsed - lastTick;
+ if (slowMode) {
+ if (slowdownFactor > 0)
+ delta = qRound(delta / slowdownFactor);
+ else
+ delta = 0;
+ }
+
+ lastTick = totalElapsed;
+
+ //we make sure we only call update time if the time has actually changed
+ //it might happen in some cases that the time doesn't change because events are delayed
+ //when the CPU load is high
+ if (delta) {
+ insideTick = true;
+ for (currentAnimationIdx = 0; currentAnimationIdx < animations.count(); ++currentAnimationIdx) {
+ QAbstractAnimation *animation = animations.at(currentAnimationIdx);
+ int elapsed = QAbstractAnimationPrivate::get(animation)->totalCurrentTime
+ + (animation->direction() == QAbstractAnimation::Forward ? delta : -delta);
+ animation->setCurrentTime(elapsed);
+ }
+ insideTick = false;
+ currentAnimationIdx = 0;
+ }
+}
+
+void QUnifiedTimer::updateAnimationTimer()
+{
+ QUnifiedTimer *inst = QUnifiedTimer::instance(false);
+ if (inst)
+ inst->restartAnimationTimer();
+}
+
+void QUnifiedTimer::restartAnimationTimer()
+{
+ if (runningLeafAnimations == 0 && !runningPauseAnimations.isEmpty()) {
+ int closestTimeToFinish = closestPauseAnimationTimeToFinish();
+ if (closestTimeToFinish < 0) {
+ qDebug() << runningPauseAnimations;
+ qDebug() << closestPauseAnimationTimeToFinish();
+ }
+ driver->stop();
+ animationTimer.start(closestTimeToFinish, this);
+ isPauseTimerActive = true;
+ } else if (!driver->isRunning() || isPauseTimerActive) {
+ driver->start();
+ isPauseTimerActive = false;
+ }
+}
+
+void QUnifiedTimer::setTimingInterval(int interval)
+{
+ timingInterval = interval;
+
+ if (driver->isRunning() && !isPauseTimerActive) {
+ //we changed the timing interval
+ driver->stop();
+ driver->start();
+ }
+}
+
+
+void QUnifiedTimer::timerEvent(QTimerEvent *event)
+{
+ //in the case of consistent timing we make sure the orders in which events come is always the same
+ //for that purpose we do as if the startstoptimer would always fire before the animation timer
+ if ((consistentTiming && startStopAnimationTimer.isActive()) ||
+ event->timerId() == startStopAnimationTimer.timerId()) {
+ startStopAnimationTimer.stop();
+
+ //we transfer the waiting animations into the "really running" state
+ animations += animationsToStart;
+ animationsToStart.clear();
+ if (animations.isEmpty()) {
+ animationTimer.stop();
+ isPauseTimerActive = false;
+ // invalidate the start reference time
+ time.invalidate();
+ } else {
+ restartAnimationTimer();
+ if (!time.isValid()) {
+ lastTick = 0;
+ time.start();
+ }
+ }
+ }
+
+ if (event->timerId() == animationTimer.timerId()) {
+ // update current time on all top level animations
+ updateAnimationsTime();
+ restartAnimationTimer();
+ }
+}
+
+void QUnifiedTimer::registerAnimation(QAbstractAnimation *animation, bool isTopLevel)
+{
+ QUnifiedTimer *inst = instance(true); //we create the instance if needed
+ inst->registerRunningAnimation(animation);
+ if (isTopLevel) {
+ Q_ASSERT(!QAbstractAnimationPrivate::get(animation)->hasRegisteredTimer);
+ QAbstractAnimationPrivate::get(animation)->hasRegisteredTimer = true;
+ inst->animationsToStart << animation;
+ if (!inst->startStopAnimationTimer.isActive())
+ inst->startStopAnimationTimer.start(STARTSTOP_TIMER_DELAY, inst);
+ }
+}
+
+void QUnifiedTimer::unregisterAnimation(QAbstractAnimation *animation)
+{
+ QUnifiedTimer *inst = QUnifiedTimer::instance(false);
+ if (inst) {
+ //at this point the unified timer should have been created
+ //but it might also have been already destroyed in case the application is shutting down
+
+ inst->unregisterRunningAnimation(animation);
+
+ if (!QAbstractAnimationPrivate::get(animation)->hasRegisteredTimer)
+ return;
+
+ int idx = inst->animations.indexOf(animation);
+ if (idx != -1) {
+ inst->animations.removeAt(idx);
+ // this is needed if we unregister an animation while its running
+ if (idx <= inst->currentAnimationIdx)
+ --inst->currentAnimationIdx;
+
+ if (inst->animations.isEmpty() && !inst->startStopAnimationTimer.isActive())
+ inst->startStopAnimationTimer.start(STARTSTOP_TIMER_DELAY, inst);
+ } else {
+ inst->animationsToStart.removeOne(animation);
+ }
+ }
+ QAbstractAnimationPrivate::get(animation)->hasRegisteredTimer = false;
+}
+
+void QUnifiedTimer::registerRunningAnimation(QAbstractAnimation *animation)
+{
+ if (QAbstractAnimationPrivate::get(animation)->isGroup)
+ return;
+
+ if (QAbstractAnimationPrivate::get(animation)->isPause) {
+ runningPauseAnimations << animation;
+ } else
+ runningLeafAnimations++;
+}
+
+void QUnifiedTimer::unregisterRunningAnimation(QAbstractAnimation *animation)
+{
+ if (QAbstractAnimationPrivate::get(animation)->isGroup)
+ return;
+
+ if (QAbstractAnimationPrivate::get(animation)->isPause)
+ runningPauseAnimations.removeOne(animation);
+ else
+ runningLeafAnimations--;
+ Q_ASSERT(runningLeafAnimations >= 0);
+}
+
+int QUnifiedTimer::closestPauseAnimationTimeToFinish()
+{
+ int closestTimeToFinish = INT_MAX;
+ for (int i = 0; i < runningPauseAnimations.size(); ++i) {
+ QAbstractAnimation *animation = runningPauseAnimations.at(i);
+ int timeToFinish;
+
+ if (animation->direction() == QAbstractAnimation::Forward)
+ timeToFinish = animation->duration() - animation->currentLoopTime();
+ else
+ timeToFinish = animation->currentLoopTime();
+
+ if (timeToFinish < closestTimeToFinish)
+ closestTimeToFinish = timeToFinish;
+ }
+ return closestTimeToFinish;
+}
+
+void QUnifiedTimer::installAnimationDriver(QAnimationDriver *d)
+{
+ if (driver->isRunning()) {
+ qWarning("QUnifiedTimer: Cannot change animation driver while animations are running");
+ return;
+ }
+
+ if (driver && driver != &defaultDriver)
+ delete driver;
+
+ driver = d;
+}
+
+/*!
+ \class QAnimationDriver
+
+ \brief The QAnimationDriver class is used to exchange the mechanism that drives animations.
+
+ The default animation system is driven by a timer that fires at regular intervals.
+ In some scenarios, it is better to drive the animation based on other synchronization
+ mechanisms, such as the vertical refresh rate of the screen.
+
+ \internal
+ */
+
+QAnimationDriver::QAnimationDriver(QObject *parent)
+ : QObject(*(new QAnimationDriverPrivate), parent)
+{
+}
+
+QAnimationDriver::QAnimationDriver(QAnimationDriverPrivate &dd, QObject *parent)
+ : QObject(dd, parent)
+{
+}
+
+
+/*!
+ Advances the animation based on the current time. This function should
+ be continuously called by the driver while the animation is running.
+
+ \internal
+ */
+void QAnimationDriver::advance()
+{
+ QUnifiedTimer *instance = QUnifiedTimer::instance();
+
+ // update current time on all top level animations
+ instance->updateAnimationsTime();
+ instance->restartAnimationTimer();
+}
+
+
+/*!
+ Installs this animation driver. The animation driver is thread local and
+ will only apply for the thread its installed in.
+
+ \internal
+ */
+void QAnimationDriver::install()
+{
+ QUnifiedTimer *timer = QUnifiedTimer::instance(true);
+ timer->installAnimationDriver(this);
+}
+
+bool QAnimationDriver::isRunning() const
+{
+ return d_func()->running;
+}
+
+
+void QAnimationDriver::start()
+{
+ Q_D(QAnimationDriver);
+ if (!d->running) {
+ started();
+ d->running = true;
+ }
+}
+
+
+void QAnimationDriver::stop()
+{
+ Q_D(QAnimationDriver);
+ if (d->running) {
+ stopped();
+ d->running = false;
+ }
+}
+
+/*!
+ \fn QAnimationDriver::started()
+
+ This function is called by the animation framework to notify the driver
+ that it should start running.
+
+ \internal
+ */
+
+/*!
+ \fn QAnimationDriver::stopped()
+
+ This function is called by the animation framework to notify the driver
+ that it should stop running.
+
+ \internal
+ */
+
+/*!
+ The default animation driver just spins the timer...
+ */
+QDefaultAnimationDriver::QDefaultAnimationDriver(QUnifiedTimer *timer)
+ : QAnimationDriver(0), m_unified_timer(timer)
+{
+}
+
+void QDefaultAnimationDriver::timerEvent(QTimerEvent *e)
+{
+ Q_ASSERT(e->timerId() == m_timer.timerId());
+ Q_UNUSED(e); // if the assertions are disabled
+ advance();
+}
+
+void QDefaultAnimationDriver::started()
+{
+ m_timer.start(m_unified_timer->timingInterval, this);
+}
+
+void QDefaultAnimationDriver::stopped()
+{
+ m_timer.stop();
+}
+
+
+
+void QAbstractAnimationPrivate::setState(QAbstractAnimation::State newState)
+{
+ Q_Q(QAbstractAnimation);
+ if (state == newState)
+ return;
+
+ if (loopCount == 0)
+ return;
+
+ QAbstractAnimation::State oldState = state;
+ int oldCurrentTime = currentTime;
+ int oldCurrentLoop = currentLoop;
+ QAbstractAnimation::Direction oldDirection = direction;
+
+ // check if we should Rewind
+ if ((newState == QAbstractAnimation::Paused || newState == QAbstractAnimation::Running)
+ && oldState == QAbstractAnimation::Stopped) {
+ //here we reset the time if needed
+ //we don't call setCurrentTime because this might change the way the animation
+ //behaves: changing the state or changing the current value
+ totalCurrentTime = currentTime = (direction == QAbstractAnimation::Forward) ?
+ 0 : (loopCount == -1 ? q->duration() : q->totalDuration());
+ }
+
+ state = newState;
+ QWeakPointer<QAbstractAnimation> guard(q);
+
+ //(un)registration of the animation must always happen before calls to
+ //virtual function (updateState) to ensure a correct state of the timer
+ bool isTopLevel = !group || group->state() == QAbstractAnimation::Stopped;
+ if (oldState == QAbstractAnimation::Running) {
+ if (newState == QAbstractAnimation::Paused && hasRegisteredTimer)
+ QUnifiedTimer::ensureTimerUpdate();
+ //the animation, is not running any more
+ QUnifiedTimer::unregisterAnimation(q);
+ } else if (newState == QAbstractAnimation::Running) {
+ QUnifiedTimer::registerAnimation(q, isTopLevel);
+ }
+
+ q->updateState(newState, oldState);
+ if (!guard || newState != state) //this is to be safe if updateState changes the state
+ return;
+
+ // Notify state change
+ emit q->stateChanged(newState, oldState);
+ if (!guard || newState != state) //this is to be safe if updateState changes the state
+ return;
+
+ switch (state) {
+ case QAbstractAnimation::Paused:
+ break;
+ case QAbstractAnimation::Running:
+ {
+
+ // this ensures that the value is updated now that the animation is running
+ if (oldState == QAbstractAnimation::Stopped) {
+ if (isTopLevel) {
+ // currentTime needs to be updated if pauseTimer is active
+ QUnifiedTimer::ensureTimerUpdate();
+ q->setCurrentTime(totalCurrentTime);
+ }
+ }
+ }
+ break;
+ case QAbstractAnimation::Stopped:
+ // Leave running state.
+ int dura = q->duration();
+
+ if (deleteWhenStopped)
+ q->deleteLater();
+
+ if (dura == -1 || loopCount < 0
+ || (oldDirection == QAbstractAnimation::Forward && (oldCurrentTime * (oldCurrentLoop + 1)) == (dura * loopCount))
+ || (oldDirection == QAbstractAnimation::Backward && oldCurrentTime == 0)) {
+ emit q->finished();
+ }
+ break;
+ }
+}
+
+/*!
+ Constructs the QAbstractAnimation base class, and passes \a parent to
+ QObject's constructor.
+
+ \sa QVariantAnimation, QAnimationGroup
+*/
+QAbstractAnimation::QAbstractAnimation(QObject *parent)
+ : QObject(*new QAbstractAnimationPrivate, 0)
+{
+ // Allow auto-add on reparent
+ setParent(parent);
+}
+
+/*!
+ \internal
+*/
+QAbstractAnimation::QAbstractAnimation(QAbstractAnimationPrivate &dd, QObject *parent)
+ : QObject(dd, 0)
+{
+ // Allow auto-add on reparent
+ setParent(parent);
+}
+
+/*!
+ Stops the animation if it's running, then destroys the
+ QAbstractAnimation. If the animation is part of a QAnimationGroup, it is
+ automatically removed before it's destroyed.
+*/
+QAbstractAnimation::~QAbstractAnimation()
+{
+ Q_D(QAbstractAnimation);
+ //we can't call stop here. Otherwise we get pure virtual calls
+ if (d->state != Stopped) {
+ QAbstractAnimation::State oldState = d->state;
+ d->state = Stopped;
+ emit stateChanged(oldState, d->state);
+ if (oldState == QAbstractAnimation::Running)
+ QUnifiedTimer::unregisterAnimation(this);
+ }
+}
+
+/*!
+ \property QAbstractAnimation::state
+ \brief state of the animation.
+
+ This property describes the current state of the animation. When the
+ animation state changes, QAbstractAnimation emits the stateChanged()
+ signal.
+*/
+QAbstractAnimation::State QAbstractAnimation::state() const
+{
+ Q_D(const QAbstractAnimation);
+ return d->state;
+}
+
+/*!
+ If this animation is part of a QAnimationGroup, this function returns a
+ pointer to the group; otherwise, it returns 0.
+
+ \sa QAnimationGroup::addAnimation()
+*/
+QAnimationGroup *QAbstractAnimation::group() const
+{
+ Q_D(const QAbstractAnimation);
+ return d->group;
+}
+
+/*!
+ \enum QAbstractAnimation::State
+
+ This enum describes the state of the animation.
+
+ \value Stopped The animation is not running. This is the initial state
+ of QAbstractAnimation, and the state QAbstractAnimation reenters when finished. The current
+ time remain unchanged until either setCurrentTime() is
+ called, or the animation is started by calling start().
+
+ \value Paused The animation is paused (i.e., temporarily
+ suspended). Calling resume() will resume animation activity.
+
+ \value Running The animation is running. While control is in the event
+ loop, QAbstractAnimation will update its current time at regular intervals,
+ calling updateCurrentTime() when appropriate.
+
+ \sa state(), stateChanged()
+*/
+
+/*!
+ \enum QAbstractAnimation::Direction
+
+ This enum describes the direction of the animation when in \l Running state.
+
+ \value Forward The current time of the animation increases with time (i.e.,
+ moves from 0 and towards the end / duration).
+
+ \value Backward The current time of the animation decreases with time (i.e.,
+ moves from the end / duration and towards 0).
+
+ \sa direction
+*/
+
+/*!
+ \property QAbstractAnimation::direction
+ \brief the direction of the animation when it is in \l Running
+ state.
+
+ This direction indicates whether the time moves from 0 towards the
+ animation duration, or from the value of the duration and towards 0 after
+ start() has been called.
+
+ By default, this property is set to \l Forward.
+*/
+QAbstractAnimation::Direction QAbstractAnimation::direction() const
+{
+ Q_D(const QAbstractAnimation);
+ return d->direction;
+}
+void QAbstractAnimation::setDirection(Direction direction)
+{
+ Q_D(QAbstractAnimation);
+ if (d->direction == direction)
+ return;
+
+ if (state() == Stopped) {
+ if (direction == Backward) {
+ d->currentTime = duration();
+ d->currentLoop = d->loopCount - 1;
+ } else {
+ d->currentTime = 0;
+ d->currentLoop = 0;
+ }
+ }
+
+ // the commands order below is important: first we need to setCurrentTime with the old direction,
+ // then update the direction on this and all children and finally restart the pauseTimer if needed
+ if (d->hasRegisteredTimer)
+ QUnifiedTimer::ensureTimerUpdate();
+
+ d->direction = direction;
+ updateDirection(direction);
+
+ if (d->hasRegisteredTimer)
+ // needed to update the timer interval in case of a pause animation
+ QUnifiedTimer::updateAnimationTimer();
+
+ emit directionChanged(direction);
+}
+
+/*!
+ \property QAbstractAnimation::duration
+ \brief the duration of the animation.
+
+ If the duration is -1, it means that the duration is undefined.
+ In this case, loopCount is ignored.
+*/
+
+/*!
+ \property QAbstractAnimation::loopCount
+ \brief the loop count of the animation
+
+ This property describes the loop count of the animation as an integer.
+ By default this value is 1, indicating that the animation
+ should run once only, and then stop. By changing it you can let the
+ animation loop several times. With a value of 0, the animation will not
+ run at all, and with a value of -1, the animation will loop forever
+ until stopped.
+ It is not supported to have loop on an animation that has an undefined
+ duration. It will only run once.
+*/
+int QAbstractAnimation::loopCount() const
+{
+ Q_D(const QAbstractAnimation);
+ return d->loopCount;
+}
+void QAbstractAnimation::setLoopCount(int loopCount)
+{
+ Q_D(QAbstractAnimation);
+ d->loopCount = loopCount;
+}
+
+/*!
+ \property QAbstractAnimation::currentLoop
+ \brief the current loop of the animation
+
+ This property describes the current loop of the animation. By default,
+ the animation's loop count is 1, and so the current loop will
+ always be 0. If the loop count is 2 and the animation runs past its
+ duration, it will automatically rewind and restart at current time 0, and
+ current loop 1, and so on.
+
+ When the current loop changes, QAbstractAnimation emits the
+ currentLoopChanged() signal.
+*/
+int QAbstractAnimation::currentLoop() const
+{
+ Q_D(const QAbstractAnimation);
+ return d->currentLoop;
+}
+
+/*!
+ \fn virtual int QAbstractAnimation::duration() const = 0
+
+ This pure virtual function returns the duration of the animation, and
+ defines for how long QAbstractAnimation should update the current
+ time. This duration is local, and does not include the loop count.
+
+ A return value of -1 indicates that the animation has no defined duration;
+ the animation should run forever until stopped. This is useful for
+ animations that are not time driven, or where you cannot easily predict
+ its duration (e.g., event driven audio playback in a game).
+
+ If the animation is a parallel QAnimationGroup, the duration will be the longest
+ duration of all its animations. If the animation is a sequential QAnimationGroup,
+ the duration will be the sum of the duration of all its animations.
+ \sa loopCount
+*/
+
+/*!
+ Returns the total and effective duration of the animation, including the
+ loop count.
+
+ \sa duration(), currentTime
+*/
+int QAbstractAnimation::totalDuration() const
+{
+ int dura = duration();
+ if (dura <= 0)
+ return dura;
+ int loopcount = loopCount();
+ if (loopcount < 0)
+ return -1;
+ return dura * loopcount;
+}
+
+/*!
+ Returns the current time inside the current loop. It can go from 0 to duration().
+
+ \sa duration(), currentTime
+*/
+
+int QAbstractAnimation::currentLoopTime() const
+{
+ Q_D(const QAbstractAnimation);
+ return d->currentTime;
+}
+
+/*!
+ \property QAbstractAnimation::currentTime
+ \brief the current time and progress of the animation
+
+ This property describes the animation's current time. You can change the
+ current time by calling setCurrentTime, or you can call start() and let
+ the animation run, setting the current time automatically as the animation
+ progresses.
+
+ The animation's current time starts at 0, and ends at totalDuration().
+
+ \sa loopCount, currentLoopTime()
+ */
+int QAbstractAnimation::currentTime() const
+{
+ Q_D(const QAbstractAnimation);
+ return d->totalCurrentTime;
+}
+void QAbstractAnimation::setCurrentTime(int msecs)
+{
+ Q_D(QAbstractAnimation);
+ msecs = qMax(msecs, 0);
+
+ // Calculate new time and loop.
+ int dura = duration();
+ int totalDura = dura <= 0 ? dura : ((d->loopCount < 0) ? -1 : dura * d->loopCount);
+ if (totalDura != -1)
+ msecs = qMin(totalDura, msecs);
+ d->totalCurrentTime = msecs;
+
+ // Update new values.
+ int oldLoop = d->currentLoop;
+ d->currentLoop = ((dura <= 0) ? 0 : (msecs / dura));
+ if (d->currentLoop == d->loopCount) {
+ //we're at the end
+ d->currentTime = qMax(0, dura);
+ d->currentLoop = qMax(0, d->loopCount - 1);
+ } else {
+ if (d->direction == Forward) {
+ d->currentTime = (dura <= 0) ? msecs : (msecs % dura);
+ } else {
+ d->currentTime = (dura <= 0) ? msecs : ((msecs - 1) % dura) + 1;
+ if (d->currentTime == dura)
+ --d->currentLoop;
+ }
+ }
+
+ updateCurrentTime(d->currentTime);
+ if (d->currentLoop != oldLoop)
+ emit currentLoopChanged(d->currentLoop);
+
+ // All animations are responsible for stopping the animation when their
+ // own end state is reached; in this case the animation is time driven,
+ // and has reached the end.
+ if ((d->direction == Forward && d->totalCurrentTime == totalDura)
+ || (d->direction == Backward && d->totalCurrentTime == 0)) {
+ stop();
+ }
+}
+
+/*!
+ Starts the animation. The \a policy argument says whether or not the
+ animation should be deleted when it's done. When the animation starts, the
+ stateChanged() signal is emitted, and state() returns Running. When control
+ reaches the event loop, the animation will run by itself, periodically
+ calling updateCurrentTime() as the animation progresses.
+
+ If the animation is currently stopped or has already reached the end,
+ calling start() will rewind the animation and start again from the beginning.
+ When the animation reaches the end, the animation will either stop, or
+ if the loop level is more than 1, it will rewind and continue from the beginning.
+
+ If the animation is already running, this function does nothing.
+
+ \sa stop(), state()
+*/
+void QAbstractAnimation::start(DeletionPolicy policy)
+{
+ Q_D(QAbstractAnimation);
+ if (d->state == Running)
+ return;
+ d->deleteWhenStopped = policy;
+ d->setState(Running);
+}
+
+/*!
+ Stops the animation. When the animation is stopped, it emits the stateChanged()
+ signal, and state() returns Stopped. The current time is not changed.
+
+ If the animation stops by itself after reaching the end (i.e.,
+ currentLoopTime() == duration() and currentLoop() > loopCount() - 1), the
+ finished() signal is emitted.
+
+ \sa start(), state()
+ */
+void QAbstractAnimation::stop()
+{
+ Q_D(QAbstractAnimation);
+
+ if (d->state == Stopped)
+ return;
+
+ d->setState(Stopped);
+}
+
+/*!
+ Pauses the animation. When the animation is paused, state() returns Paused.
+ The value of currentTime will remain unchanged until resume() or start()
+ is called. If you want to continue from the current time, call resume().
+
+ \sa start(), state(), resume()
+ */
+void QAbstractAnimation::pause()
+{
+ Q_D(QAbstractAnimation);
+ if (d->state == Stopped) {
+ qWarning("QAbstractAnimation::pause: Cannot pause a stopped animation");
+ return;
+ }
+
+ d->setState(Paused);
+}
+
+/*!
+ Resumes the animation after it was paused. When the animation is resumed,
+ it emits the resumed() and stateChanged() signals. The currenttime is not
+ changed.
+
+ \sa start(), pause(), state()
+ */
+void QAbstractAnimation::resume()
+{
+ Q_D(QAbstractAnimation);
+ if (d->state != Paused) {
+ qWarning("QAbstractAnimation::resume: "
+ "Cannot resume an animation that is not paused");
+ return;
+ }
+
+ d->setState(Running);
+}
+
+/*!
+ If \a paused is true, the animation is paused.
+ If \a paused is false, the animation is resumed.
+
+ \sa state(), pause(), resume()
+*/
+void QAbstractAnimation::setPaused(bool paused)
+{
+ if (paused)
+ pause();
+ else
+ resume();
+}
+
+
+/*!
+ \reimp
+*/
+bool QAbstractAnimation::event(QEvent *event)
+{
+ return QObject::event(event);
+}
+
+/*!
+ \fn virtual void QAbstractAnimation::updateCurrentTime(int currentTime) = 0;
+
+ This pure virtual function is called every time the animation's
+ \a currentTime changes.
+
+ \sa updateState()
+*/
+
+/*!
+ This virtual function is called by QAbstractAnimation when the state
+ of the animation is changed from \a oldState to \a newState.
+
+ \sa start(), stop(), pause(), resume()
+*/
+void QAbstractAnimation::updateState(QAbstractAnimation::State newState,
+ QAbstractAnimation::State oldState)
+{
+ Q_UNUSED(oldState);
+ Q_UNUSED(newState);
+}
+
+/*!
+ This virtual function is called by QAbstractAnimation when the direction
+ of the animation is changed. The \a direction argument is the new direction.
+
+ \sa setDirection(), direction()
+*/
+void QAbstractAnimation::updateDirection(QAbstractAnimation::Direction direction)
+{
+ Q_UNUSED(direction);
+}
+
+
+QT_END_NAMESPACE
+
+#include "moc_qabstractanimation.cpp"
+
+#endif //QT_NO_ANIMATION
diff --git a/src/corelib/animation/qabstractanimation.h b/src/corelib/animation/qabstractanimation.h
new file mode 100644
index 0000000000..0900870ce2
--- /dev/null
+++ b/src/corelib/animation/qabstractanimation.h
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTANIMATION_H
+#define QABSTRACTANIMATION_H
+
+#include <QtCore/qobject.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+#ifndef QT_NO_ANIMATION
+
+class QAnimationGroup;
+class QSequentialAnimationGroup;
+class QAnimationDriver;
+
+class QAbstractAnimationPrivate;
+class Q_CORE_EXPORT QAbstractAnimation : public QObject
+{
+ Q_OBJECT
+ Q_ENUMS(State)
+ Q_ENUMS(Direction)
+ Q_PROPERTY(State state READ state NOTIFY stateChanged)
+ Q_PROPERTY(int loopCount READ loopCount WRITE setLoopCount)
+ Q_PROPERTY(int currentTime READ currentTime WRITE setCurrentTime)
+ Q_PROPERTY(int currentLoop READ currentLoop NOTIFY currentLoopChanged)
+ Q_PROPERTY(Direction direction READ direction WRITE setDirection NOTIFY directionChanged)
+ Q_PROPERTY(int duration READ duration)
+
+public:
+ enum Direction {
+ Forward,
+ Backward
+ };
+
+ enum State {
+ Stopped,
+ Paused,
+ Running
+ };
+
+ enum DeletionPolicy {
+ KeepWhenStopped = 0,
+ DeleteWhenStopped
+ };
+
+ QAbstractAnimation(QObject *parent = 0);
+ virtual ~QAbstractAnimation();
+
+ State state() const;
+
+ QAnimationGroup *group() const;
+
+ Direction direction() const;
+ void setDirection(Direction direction);
+
+ int currentTime() const;
+ int currentLoopTime() const;
+
+ int loopCount() const;
+ void setLoopCount(int loopCount);
+ int currentLoop() const;
+
+ virtual int duration() const = 0;
+ int totalDuration() const;
+
+Q_SIGNALS:
+ void finished();
+ void stateChanged(QAbstractAnimation::State newState, QAbstractAnimation::State oldState);
+ void currentLoopChanged(int currentLoop);
+ void directionChanged(QAbstractAnimation::Direction);
+
+public Q_SLOTS:
+ void start(QAbstractAnimation::DeletionPolicy policy = KeepWhenStopped);
+ void pause();
+ void resume();
+ void setPaused(bool);
+ void stop();
+ void setCurrentTime(int msecs);
+
+protected:
+ QAbstractAnimation(QAbstractAnimationPrivate &dd, QObject *parent = 0);
+ bool event(QEvent *event);
+
+ virtual void updateCurrentTime(int currentTime) = 0;
+ virtual void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState);
+ virtual void updateDirection(QAbstractAnimation::Direction direction);
+
+private:
+ Q_DISABLE_COPY(QAbstractAnimation)
+ Q_DECLARE_PRIVATE(QAbstractAnimation)
+};
+
+class QAnimationDriverPrivate;
+class Q_CORE_EXPORT QAnimationDriver : public QObject
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QAnimationDriver)
+
+public:
+ QAnimationDriver(QObject *parent = 0);
+
+ void advance();
+ void install();
+
+ bool isRunning() const;
+
+protected:
+ virtual void started() {};
+ virtual void stopped() {};
+
+ QAnimationDriver(QAnimationDriverPrivate &dd, QObject *parent = 0);
+
+private:
+ friend class QUnifiedTimer;
+
+ void start();
+ void stop();
+};
+
+
+
+
+#endif //QT_NO_ANIMATION
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QABSTRACTANIMATION_H
diff --git a/src/corelib/animation/qabstractanimation_p.h b/src/corelib/animation/qabstractanimation_p.h
new file mode 100644
index 0000000000..ba92960f6b
--- /dev/null
+++ b/src/corelib/animation/qabstractanimation_p.h
@@ -0,0 +1,233 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QABSTRACTANIMATION_P_H
+#define QABSTRACTANIMATION_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of QIODevice. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qbasictimer.h>
+#include <QtCore/qdatetime.h>
+#include <QtCore/qtimer.h>
+#include <QtCore/qelapsedtimer.h>
+#include <private/qobject_p.h>
+#include <qabstractanimation.h>
+
+#ifdef Q_OS_WIN
+#include <qt_windows.h>
+#endif
+
+#ifndef QT_NO_ANIMATION
+
+QT_BEGIN_NAMESPACE
+
+class QAnimationGroup;
+class QAbstractAnimation;
+class QAbstractAnimationPrivate : public QObjectPrivate
+{
+public:
+ QAbstractAnimationPrivate()
+ : state(QAbstractAnimation::Stopped),
+ direction(QAbstractAnimation::Forward),
+ totalCurrentTime(0),
+ currentTime(0),
+ loopCount(1),
+ currentLoop(0),
+ deleteWhenStopped(false),
+ hasRegisteredTimer(false),
+ isPause(false),
+ isGroup(false),
+ group(0)
+ {
+ }
+
+ virtual ~QAbstractAnimationPrivate() {}
+
+ static QAbstractAnimationPrivate *get(QAbstractAnimation *q)
+ {
+ return q->d_func();
+ }
+
+ QAbstractAnimation::State state;
+ QAbstractAnimation::Direction direction;
+ void setState(QAbstractAnimation::State state);
+
+ int totalCurrentTime;
+ int currentTime;
+ int loopCount;
+ int currentLoop;
+
+ bool deleteWhenStopped;
+ bool hasRegisteredTimer;
+ bool isPause;
+ bool isGroup;
+
+ QAnimationGroup *group;
+
+private:
+ Q_DECLARE_PUBLIC(QAbstractAnimation)
+};
+
+
+class QUnifiedTimer;
+class QDefaultAnimationDriver : public QAnimationDriver
+{
+ Q_OBJECT
+public:
+ QDefaultAnimationDriver(QUnifiedTimer *timer);
+ void timerEvent(QTimerEvent *e);
+
+ void started();
+ void stopped();
+
+private:
+ QBasicTimer m_timer;
+ QUnifiedTimer *m_unified_timer;
+};
+
+class Q_CORE_EXPORT QAnimationDriverPrivate : public QObjectPrivate
+{
+public:
+ QAnimationDriverPrivate() : running(false) {}
+ bool running;
+};
+
+typedef QElapsedTimer ElapsedTimer;
+
+class Q_CORE_EXPORT QUnifiedTimer : public QObject
+{
+private:
+ QUnifiedTimer();
+
+public:
+ //XXX this is needed by dui
+ static QUnifiedTimer *instance();
+ static QUnifiedTimer *instance(bool create);
+
+ static void registerAnimation(QAbstractAnimation *animation, bool isTopLevel);
+ static void unregisterAnimation(QAbstractAnimation *animation);
+
+ //defines the timing interval. Default is DEFAULT_TIMER_INTERVAL
+ void setTimingInterval(int interval);
+
+ /*
+ this allows to have a consistent timer interval at each tick from the timer
+ not taking the real time that passed into account.
+ */
+ void setConsistentTiming(bool consistent) { consistentTiming = consistent; }
+
+ //these facilitate fine-tuning of complex animations
+ void setSlowModeEnabled(bool enabled) { slowMode = enabled; }
+ void setSlowdownFactor(qreal factor) { slowdownFactor = factor; }
+
+ /*
+ this is used for updating the currentTime of all animations in case the pause
+ timer is active or, otherwise, only of the animation passed as parameter.
+ */
+ static void ensureTimerUpdate();
+
+ /*
+ this will evaluate the need of restarting the pause timer in case there is still
+ some pause animations running.
+ */
+ static void updateAnimationTimer();
+
+ void installAnimationDriver(QAnimationDriver *driver);
+
+ void restartAnimationTimer();
+ void updateAnimationsTime();
+
+protected:
+ void timerEvent(QTimerEvent *);
+
+private:
+ friend class QDefaultAnimationDriver;
+
+ QAnimationDriver *driver;
+ QDefaultAnimationDriver defaultDriver;
+
+ QBasicTimer animationTimer;
+ // timer used to delay the check if we should start/stop the animation timer
+ QBasicTimer startStopAnimationTimer;
+
+ ElapsedTimer time;
+
+ qint64 lastTick;
+ int timingInterval;
+ int currentAnimationIdx;
+ bool insideTick;
+ bool consistentTiming;
+ bool slowMode;
+
+ // This factor will be used to divide the DEFAULT_TIMER_INTERVAL at each tick
+ // when slowMode is enabled. Setting it to 0 or higher than DEFAULT_TIMER_INTERVAL (16)
+ // stops all animations.
+ qreal slowdownFactor;
+
+ // bool to indicate that only pause animations are active
+ bool isPauseTimerActive;
+
+ QList<QAbstractAnimation*> animations, animationsToStart;
+
+ // this is the count of running animations that are not a group neither a pause animation
+ int runningLeafAnimations;
+ QList<QAbstractAnimation*> runningPauseAnimations;
+
+ void registerRunningAnimation(QAbstractAnimation *animation);
+ void unregisterRunningAnimation(QAbstractAnimation *animation);
+
+ int closestPauseAnimationTimeToFinish();
+};
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_ANIMATION
+
+#endif //QABSTRACTANIMATION_P_H
diff --git a/src/corelib/animation/qanimationgroup.cpp b/src/corelib/animation/qanimationgroup.cpp
new file mode 100644
index 0000000000..f3b4f9576e
--- /dev/null
+++ b/src/corelib/animation/qanimationgroup.cpp
@@ -0,0 +1,302 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QAnimationGroup
+ \brief The QAnimationGroup class is an abstract base class for groups of animations.
+ \since 4.6
+ \ingroup animation
+
+ An animation group is a container for animations (subclasses of
+ QAbstractAnimation). A group is usually responsible for managing
+ the \l{QAbstractAnimation::State}{state} of its animations, i.e.,
+ it decides when to start, stop, resume, and pause them. Currently,
+ Qt provides two such groups: QParallelAnimationGroup and
+ QSequentialAnimationGroup. Look up their class descriptions for
+ details.
+
+ Since QAnimationGroup inherits from QAbstractAnimation, you can
+ combine groups, and easily construct complex animation graphs.
+ You can query QAbstractAnimation for the group it belongs to
+ (using the \l{QAbstractAnimation::}{group()} function).
+
+ To start a top-level animation group, you simply use the
+ \l{QAbstractAnimation::}{start()} function from
+ QAbstractAnimation. By a top-level animation group, we think of a
+ group that itself is not contained within another group. Starting
+ sub groups directly is not supported, and may lead to unexpected
+ behavior.
+
+ \omit OK, we'll put in a snippet on this here \endomit
+
+ QAnimationGroup provides methods for adding and retrieving
+ animations. Besides that, you can remove animations by calling
+ remove(), and clear the animation group by calling
+ clear(). You may keep track of changes in the group's
+ animations by listening to QEvent::ChildAdded and
+ QEvent::ChildRemoved events.
+
+ \omit OK, let's find a snippet here as well. \endomit
+
+ QAnimationGroup takes ownership of the animations it manages, and
+ ensures that they are deleted when the animation group is deleted.
+
+ \sa QAbstractAnimation, QVariantAnimation, {The Animation Framework}
+*/
+
+#include "qanimationgroup.h"
+#include <QtCore/qdebug.h>
+#include <QtCore/qcoreevent.h>
+#include "qanimationgroup_p.h"
+
+#ifndef QT_NO_ANIMATION
+
+QT_BEGIN_NAMESPACE
+
+
+/*!
+ Constructs a QAnimationGroup.
+ \a parent is passed to QObject's constructor.
+*/
+QAnimationGroup::QAnimationGroup(QObject *parent)
+ : QAbstractAnimation(*new QAnimationGroupPrivate, parent)
+{
+}
+
+/*!
+ \internal
+*/
+QAnimationGroup::QAnimationGroup(QAnimationGroupPrivate &dd, QObject *parent)
+ : QAbstractAnimation(dd, parent)
+{
+}
+
+/*!
+ Destroys the animation group. It will also destroy all its animations.
+*/
+QAnimationGroup::~QAnimationGroup()
+{
+}
+
+/*!
+ Returns a pointer to the animation at \a index in this group. This
+ function is useful when you need access to a particular animation. \a
+ index is between 0 and animationCount() - 1.
+
+ \sa animationCount(), indexOfAnimation()
+*/
+QAbstractAnimation *QAnimationGroup::animationAt(int index) const
+{
+ Q_D(const QAnimationGroup);
+
+ if (index < 0 || index >= d->animations.size()) {
+ qWarning("QAnimationGroup::animationAt: index is out of bounds");
+ return 0;
+ }
+
+ return d->animations.at(index);
+}
+
+
+/*!
+ Returns the number of animations managed by this group.
+
+ \sa indexOfAnimation(), addAnimation(), animationAt()
+*/
+int QAnimationGroup::animationCount() const
+{
+ Q_D(const QAnimationGroup);
+ return d->animations.size();
+}
+
+/*!
+ Returns the index of \a animation. The returned index can be passed
+ to the other functions that take an index as an argument.
+
+ \sa insertAnimation(), animationAt(), takeAnimation()
+*/
+int QAnimationGroup::indexOfAnimation(QAbstractAnimation *animation) const
+{
+ Q_D(const QAnimationGroup);
+ return d->animations.indexOf(animation);
+}
+
+/*!
+ Adds \a animation to this group. This will call insertAnimation with
+ index equals to animationCount().
+
+ \note The group takes ownership of the animation.
+
+ \sa removeAnimation()
+*/
+void QAnimationGroup::addAnimation(QAbstractAnimation *animation)
+{
+ Q_D(QAnimationGroup);
+ insertAnimation(d->animations.count(), animation);
+}
+
+/*!
+ Inserts \a animation into this animation group at \a index.
+ If \a index is 0 the animation is inserted at the beginning.
+ If \a index is animationCount(), the animation is inserted at the end.
+
+ \note The group takes ownership of the animation.
+
+ \sa takeAnimation(), addAnimation(), indexOfAnimation(), removeAnimation()
+*/
+void QAnimationGroup::insertAnimation(int index, QAbstractAnimation *animation)
+{
+ Q_D(QAnimationGroup);
+
+ if (index < 0 || index > d->animations.size()) {
+ qWarning("QAnimationGroup::insertAnimation: index is out of bounds");
+ return;
+ }
+
+ if (QAnimationGroup *oldGroup = animation->group())
+ oldGroup->removeAnimation(animation);
+
+ d->animations.insert(index, animation);
+ QAbstractAnimationPrivate::get(animation)->group = this;
+ // this will make sure that ChildAdded event is sent to 'this'
+ animation->setParent(this);
+ d->animationInsertedAt(index);
+}
+
+/*!
+ Removes \a animation from this group. The ownership of \a animation is
+ transferred to the caller.
+
+ \sa takeAnimation(), insertAnimation(), addAnimation()
+*/
+void QAnimationGroup::removeAnimation(QAbstractAnimation *animation)
+{
+ Q_D(QAnimationGroup);
+
+ if (!animation) {
+ qWarning("QAnimationGroup::remove: cannot remove null animation");
+ return;
+ }
+ int index = d->animations.indexOf(animation);
+ if (index == -1) {
+ qWarning("QAnimationGroup::remove: animation is not part of this group");
+ return;
+ }
+
+ takeAnimation(index);
+}
+
+/*!
+ Returns the animation at \a index and removes it from the animation group.
+
+ \note The ownership of the animation is transferred to the caller.
+
+ \sa removeAnimation(), addAnimation(), insertAnimation(), indexOfAnimation()
+*/
+QAbstractAnimation *QAnimationGroup::takeAnimation(int index)
+{
+ Q_D(QAnimationGroup);
+ if (index < 0 || index >= d->animations.size()) {
+ qWarning("QAnimationGroup::takeAnimation: no animation at index %d", index);
+ return 0;
+ }
+ QAbstractAnimation *animation = d->animations.at(index);
+ QAbstractAnimationPrivate::get(animation)->group = 0;
+ // ### removing from list before doing setParent to avoid inifinite recursion
+ // in ChildRemoved event
+ d->animations.removeAt(index);
+ animation->setParent(0);
+ d->animationRemoved(index, animation);
+ return animation;
+}
+
+/*!
+ Removes and deletes all animations in this animation group, and resets the current
+ time to 0.
+
+ \sa addAnimation(), removeAnimation()
+*/
+void QAnimationGroup::clear()
+{
+ Q_D(QAnimationGroup);
+ qDeleteAll(d->animations);
+}
+
+/*!
+ \reimp
+*/
+bool QAnimationGroup::event(QEvent *event)
+{
+ Q_D(QAnimationGroup);
+ if (event->type() == QEvent::ChildAdded) {
+ QChildEvent *childEvent = static_cast<QChildEvent *>(event);
+ if (QAbstractAnimation *a = qobject_cast<QAbstractAnimation *>(childEvent->child())) {
+ if (a->group() != this)
+ addAnimation(a);
+ }
+ } else if (event->type() == QEvent::ChildRemoved) {
+ QChildEvent *childEvent = static_cast<QChildEvent *>(event);
+ QAbstractAnimation *a = static_cast<QAbstractAnimation *>(childEvent->child());
+ // You can only rely on the child being a QObject because in the QEvent::ChildRemoved
+ // case it might be called from the destructor.
+ int index = d->animations.indexOf(a);
+ if (index != -1)
+ takeAnimation(index);
+ }
+ return QAbstractAnimation::event(event);
+}
+
+
+void QAnimationGroupPrivate::animationRemoved(int index, QAbstractAnimation *)
+{
+ Q_Q(QAnimationGroup);
+ Q_UNUSED(index);
+ if (animations.isEmpty()) {
+ currentTime = 0;
+ q->stop();
+ }
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qanimationgroup.cpp"
+
+#endif //QT_NO_ANIMATION
diff --git a/src/corelib/animation/qanimationgroup.h b/src/corelib/animation/qanimationgroup.h
new file mode 100644
index 0000000000..b3cc10579e
--- /dev/null
+++ b/src/corelib/animation/qanimationgroup.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANIMATIONGROUP_H
+#define QANIMATIONGROUP_H
+
+#include <QtCore/qabstractanimation.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+#ifndef QT_NO_ANIMATION
+
+class QAnimationGroupPrivate;
+class Q_CORE_EXPORT QAnimationGroup : public QAbstractAnimation
+{
+ Q_OBJECT
+
+public:
+ QAnimationGroup(QObject *parent = 0);
+ ~QAnimationGroup();
+
+ QAbstractAnimation *animationAt(int index) const;
+ int animationCount() const;
+ int indexOfAnimation(QAbstractAnimation *animation) const;
+ void addAnimation(QAbstractAnimation *animation);
+ void insertAnimation(int index, QAbstractAnimation *animation);
+ void removeAnimation(QAbstractAnimation *animation);
+ QAbstractAnimation *takeAnimation(int index);
+ void clear();
+
+protected:
+ QAnimationGroup(QAnimationGroupPrivate &dd, QObject *parent);
+ bool event(QEvent *event);
+
+private:
+ Q_DISABLE_COPY(QAnimationGroup)
+ Q_DECLARE_PRIVATE(QAnimationGroup)
+};
+
+#endif //QT_NO_ANIMATION
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif //QANIMATIONGROUP_H
diff --git a/src/corelib/animation/qanimationgroup_p.h b/src/corelib/animation/qanimationgroup_p.h
new file mode 100644
index 0000000000..278019abb0
--- /dev/null
+++ b/src/corelib/animation/qanimationgroup_p.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANIMATIONGROUP_P_H
+#define QANIMATIONGROUP_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of QIODevice. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qanimationgroup.h"
+
+#include <QtCore/qlist.h>
+
+#include "private/qabstractanimation_p.h"
+
+#ifndef QT_NO_ANIMATION
+
+QT_BEGIN_NAMESPACE
+
+class QAnimationGroupPrivate : public QAbstractAnimationPrivate
+{
+ Q_DECLARE_PUBLIC(QAnimationGroup)
+public:
+ QAnimationGroupPrivate()
+ {
+ isGroup = true;
+ }
+
+ virtual void animationInsertedAt(int) { }
+ virtual void animationRemoved(int, QAbstractAnimation *);
+
+ void disconnectUncontrolledAnimation(QAbstractAnimation *anim)
+ {
+ //0 for the signal here because we might be called from the animation destructor
+ QObject::disconnect(anim, 0, q_func(), SLOT(_q_uncontrolledAnimationFinished()));
+ }
+
+ void connectUncontrolledAnimation(QAbstractAnimation *anim)
+ {
+ QObject::connect(anim, SIGNAL(finished()), q_func(), SLOT(_q_uncontrolledAnimationFinished()));
+ }
+
+ QList<QAbstractAnimation *> animations;
+};
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_ANIMATION
+
+#endif //QANIMATIONGROUP_P_H
diff --git a/src/corelib/animation/qparallelanimationgroup.cpp b/src/corelib/animation/qparallelanimationgroup.cpp
new file mode 100644
index 0000000000..414cdde23e
--- /dev/null
+++ b/src/corelib/animation/qparallelanimationgroup.cpp
@@ -0,0 +1,347 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QParallelAnimationGroup
+ \brief The QParallelAnimationGroup class provides a parallel group of animations.
+ \since 4.6
+ \ingroup animation
+
+ QParallelAnimationGroup--a \l{QAnimationGroup}{container for
+ animations}--starts all its animations when it is
+ \l{QAbstractAnimation::start()}{started} itself, i.e., runs all
+ animations in parallel. The animation group finishes when the
+ longest lasting animation has finished.
+
+ You can treat QParallelAnimation as any other QAbstractAnimation,
+ e.g., pause, resume, or add it to other animation groups.
+
+ \code
+ QParallelAnimationGroup *group = new QParallelAnimationGroup;
+ group->addAnimation(anim1);
+ group->addAnimation(anim2);
+
+ group->start();
+ \endcode
+
+ In this example, \c anim1 and \c anim2 are two
+ \l{QPropertyAnimation}s that have already been set up.
+
+ \sa QAnimationGroup, QPropertyAnimation, {The Animation Framework}
+*/
+
+
+#include "qparallelanimationgroup.h"
+#include "qparallelanimationgroup_p.h"
+//#define QANIMATION_DEBUG
+
+#ifndef QT_NO_ANIMATION
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ Constructs a QParallelAnimationGroup.
+ \a parent is passed to QObject's constructor.
+*/
+QParallelAnimationGroup::QParallelAnimationGroup(QObject *parent)
+ : QAnimationGroup(*new QParallelAnimationGroupPrivate, parent)
+{
+}
+
+/*!
+ \internal
+*/
+QParallelAnimationGroup::QParallelAnimationGroup(QParallelAnimationGroupPrivate &dd,
+ QObject *parent)
+ : QAnimationGroup(dd, parent)
+{
+}
+
+/*!
+ Destroys the animation group. It will also destroy all its animations.
+*/
+QParallelAnimationGroup::~QParallelAnimationGroup()
+{
+}
+
+/*!
+ \reimp
+*/
+int QParallelAnimationGroup::duration() const
+{
+ Q_D(const QParallelAnimationGroup);
+ int ret = 0;
+
+ for (int i = 0; i < d->animations.size(); ++i) {
+ QAbstractAnimation *animation = d->animations.at(i);
+ const int currentDuration = animation->totalDuration();
+ if (currentDuration == -1)
+ return -1; // Undetermined length
+
+ ret = qMax(ret, currentDuration);
+ }
+
+ return ret;
+}
+
+/*!
+ \reimp
+*/
+void QParallelAnimationGroup::updateCurrentTime(int currentTime)
+{
+ Q_D(QParallelAnimationGroup);
+ if (d->animations.isEmpty())
+ return;
+
+ if (d->currentLoop > d->lastLoop) {
+ // simulate completion of the loop
+ int dura = duration();
+ if (dura > 0) {
+ for (int i = 0; i < d->animations.size(); ++i) {
+ QAbstractAnimation *animation = d->animations.at(i);
+ if (animation->state() != QAbstractAnimation::Stopped)
+ d->animations.at(i)->setCurrentTime(dura); // will stop
+ }
+ }
+ } else if (d->currentLoop < d->lastLoop) {
+ // simulate completion of the loop seeking backwards
+ for (int i = 0; i < d->animations.size(); ++i) {
+ QAbstractAnimation *animation = d->animations.at(i);
+ //we need to make sure the animation is in the right state
+ //and then rewind it
+ d->applyGroupState(animation);
+ animation->setCurrentTime(0);
+ animation->stop();
+ }
+ }
+
+#ifdef QANIMATION_DEBUG
+ qDebug("QParallellAnimationGroup %5d: setCurrentTime(%d), loop:%d, last:%d, timeFwd:%d, lastcurrent:%d, %d",
+ __LINE__, d->currentTime, d->currentLoop, d->lastLoop, timeFwd, d->lastCurrentTime, state());
+#endif
+ // finally move into the actual time of the current loop
+ for (int i = 0; i < d->animations.size(); ++i) {
+ QAbstractAnimation *animation = d->animations.at(i);
+ const int dura = animation->totalDuration();
+ //if the loopcount is bigger we should always start all animations
+ if (d->currentLoop > d->lastLoop
+ //if we're at the end of the animation, we need to start it if it wasn't already started in this loop
+ //this happens in Backward direction where not all animations are started at the same time
+ || d->shouldAnimationStart(animation, d->lastCurrentTime > dura /*startIfAtEnd*/)) {
+ d->applyGroupState(animation);
+ }
+
+ if (animation->state() == state()) {
+ animation->setCurrentTime(currentTime);
+ if (dura > 0 && currentTime > dura)
+ animation->stop();
+ }
+ }
+ d->lastLoop = d->currentLoop;
+ d->lastCurrentTime = currentTime;
+}
+
+/*!
+ \reimp
+*/
+void QParallelAnimationGroup::updateState(QAbstractAnimation::State newState,
+ QAbstractAnimation::State oldState)
+{
+ Q_D(QParallelAnimationGroup);
+ QAnimationGroup::updateState(newState, oldState);
+
+ switch (newState) {
+ case Stopped:
+ for (int i = 0; i < d->animations.size(); ++i)
+ d->animations.at(i)->stop();
+ d->disconnectUncontrolledAnimations();
+ break;
+ case Paused:
+ for (int i = 0; i < d->animations.size(); ++i)
+ if (d->animations.at(i)->state() == Running)
+ d->animations.at(i)->pause();
+ break;
+ case Running:
+ d->connectUncontrolledAnimations();
+ for (int i = 0; i < d->animations.size(); ++i) {
+ QAbstractAnimation *animation = d->animations.at(i);
+ if (oldState == Stopped)
+ animation->stop();
+ animation->setDirection(d->direction);
+ if (d->shouldAnimationStart(animation, oldState == Stopped))
+ animation->start();
+ }
+ break;
+ }
+}
+
+void QParallelAnimationGroupPrivate::_q_uncontrolledAnimationFinished()
+{
+ Q_Q(QParallelAnimationGroup);
+
+ QAbstractAnimation *animation = qobject_cast<QAbstractAnimation *>(q->sender());
+ Q_ASSERT(animation);
+
+ int uncontrolledRunningCount = 0;
+ if (animation->duration() == -1 || animation->loopCount() < 0) {
+ QHash<QAbstractAnimation *, int>::iterator it = uncontrolledFinishTime.begin();
+ while (it != uncontrolledFinishTime.end()) {
+ if (it.key() == animation) {
+ *it = animation->currentTime();
+ }
+ if (it.value() == -1)
+ ++uncontrolledRunningCount;
+ ++it;
+ }
+ }
+
+ if (uncontrolledRunningCount > 0)
+ return;
+
+ int maxDuration = 0;
+ for (int i = 0; i < animations.size(); ++i)
+ maxDuration = qMax(maxDuration, animations.at(i)->totalDuration());
+
+ if (currentTime >= maxDuration)
+ q->stop();
+}
+
+void QParallelAnimationGroupPrivate::disconnectUncontrolledAnimations()
+{
+ QHash<QAbstractAnimation *, int>::iterator it = uncontrolledFinishTime.begin();
+ while (it != uncontrolledFinishTime.end()) {
+ disconnectUncontrolledAnimation(it.key());
+ ++it;
+ }
+
+ uncontrolledFinishTime.clear();
+}
+
+void QParallelAnimationGroupPrivate::connectUncontrolledAnimations()
+{
+ for (int i = 0; i < animations.size(); ++i) {
+ QAbstractAnimation *animation = animations.at(i);
+ if (animation->duration() == -1 || animation->loopCount() < 0) {
+ uncontrolledFinishTime[animation] = -1;
+ connectUncontrolledAnimation(animation);
+ }
+ }
+}
+
+bool QParallelAnimationGroupPrivate::shouldAnimationStart(QAbstractAnimation *animation, bool startIfAtEnd) const
+{
+ const int dura = animation->totalDuration();
+ if (dura == -1)
+ return !isUncontrolledAnimationFinished(animation);
+ if (startIfAtEnd)
+ return currentTime <= dura;
+ if (direction == QAbstractAnimation::Forward)
+ return currentTime < dura;
+ else //direction == QAbstractAnimation::Backward
+ return currentTime && currentTime <= dura;
+}
+
+void QParallelAnimationGroupPrivate::applyGroupState(QAbstractAnimation *animation)
+{
+ switch (state)
+ {
+ case QAbstractAnimation::Running:
+ animation->start();
+ break;
+ case QAbstractAnimation::Paused:
+ animation->pause();
+ break;
+ case QAbstractAnimation::Stopped:
+ default:
+ break;
+ }
+}
+
+
+bool QParallelAnimationGroupPrivate::isUncontrolledAnimationFinished(QAbstractAnimation *anim) const
+{
+ return uncontrolledFinishTime.value(anim, -1) >= 0;
+}
+
+void QParallelAnimationGroupPrivate::animationRemoved(int index, QAbstractAnimation *anim)
+{
+ QAnimationGroupPrivate::animationRemoved(index, anim);
+ disconnectUncontrolledAnimation(anim);
+ uncontrolledFinishTime.remove(anim);
+}
+
+/*!
+ \reimp
+*/
+void QParallelAnimationGroup::updateDirection(QAbstractAnimation::Direction direction)
+{
+ Q_D(QParallelAnimationGroup);
+ //we need to update the direction of the current animation
+ if (state() != Stopped) {
+ for (int i = 0; i < d->animations.size(); ++i) {
+ QAbstractAnimation *animation = d->animations.at(i);
+ animation->setDirection(direction);
+ }
+ } else {
+ if (direction == Forward) {
+ d->lastLoop = 0;
+ d->lastCurrentTime = 0;
+ } else {
+ // Looping backwards with loopCount == -1 does not really work well...
+ d->lastLoop = (d->loopCount == -1 ? 0 : d->loopCount - 1);
+ d->lastCurrentTime = duration();
+ }
+ }
+}
+
+/*!
+ \reimp
+*/
+bool QParallelAnimationGroup::event(QEvent *event)
+{
+ return QAnimationGroup::event(event);
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qparallelanimationgroup.cpp"
+
+#endif //QT_NO_ANIMATION
diff --git a/src/corelib/animation/qparallelanimationgroup.h b/src/corelib/animation/qparallelanimationgroup.h
new file mode 100644
index 0000000000..5e0fb71799
--- /dev/null
+++ b/src/corelib/animation/qparallelanimationgroup.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPARALLELANIMATIONGROUP_H
+#define QPARALLELANIMATIONGROUP_H
+
+#include <QtCore/qanimationgroup.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+#ifndef QT_NO_ANIMATION
+
+class QParallelAnimationGroupPrivate;
+class Q_CORE_EXPORT QParallelAnimationGroup : public QAnimationGroup
+{
+ Q_OBJECT
+
+public:
+ QParallelAnimationGroup(QObject *parent = 0);
+ ~QParallelAnimationGroup();
+
+ int duration() const;
+
+protected:
+ QParallelAnimationGroup(QParallelAnimationGroupPrivate &dd, QObject *parent);
+ bool event(QEvent *event);
+
+ void updateCurrentTime(int currentTime);
+ void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState);
+ void updateDirection(QAbstractAnimation::Direction direction);
+
+private:
+ Q_DISABLE_COPY(QParallelAnimationGroup)
+ Q_DECLARE_PRIVATE(QParallelAnimationGroup)
+ Q_PRIVATE_SLOT(d_func(), void _q_uncontrolledAnimationFinished())
+};
+
+#endif //QT_NO_ANIMATION
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QPARALLELANIMATIONGROUP
diff --git a/src/corelib/animation/qparallelanimationgroup_p.h b/src/corelib/animation/qparallelanimationgroup_p.h
new file mode 100644
index 0000000000..680d41ea21
--- /dev/null
+++ b/src/corelib/animation/qparallelanimationgroup_p.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPARALLELANIMATIONGROUP_P_H
+#define QPARALLELANIMATIONGROUP_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of QIODevice. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qparallelanimationgroup.h"
+#include "private/qanimationgroup_p.h"
+#include <QtCore/qhash.h>
+
+#ifndef QT_NO_ANIMATION
+
+QT_BEGIN_NAMESPACE
+
+class QParallelAnimationGroupPrivate : public QAnimationGroupPrivate
+{
+ Q_DECLARE_PUBLIC(QParallelAnimationGroup)
+public:
+ QParallelAnimationGroupPrivate()
+ : lastLoop(0), lastCurrentTime(0)
+ {
+ }
+
+ QHash<QAbstractAnimation*, int> uncontrolledFinishTime;
+ int lastLoop;
+ int lastCurrentTime;
+
+ bool shouldAnimationStart(QAbstractAnimation *animation, bool startIfAtEnd) const;
+ void applyGroupState(QAbstractAnimation *animation);
+ bool isUncontrolledAnimationFinished(QAbstractAnimation *anim) const;
+ void connectUncontrolledAnimations();
+ void disconnectUncontrolledAnimations();
+
+ void animationRemoved(int index, QAbstractAnimation *);
+
+ // private slot
+ void _q_uncontrolledAnimationFinished();
+};
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_ANIMATION
+
+#endif //QPARALLELANIMATIONGROUP_P_H
diff --git a/src/corelib/animation/qpauseanimation.cpp b/src/corelib/animation/qpauseanimation.cpp
new file mode 100644
index 0000000000..418cb5321d
--- /dev/null
+++ b/src/corelib/animation/qpauseanimation.cpp
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QPauseAnimation
+ \brief The QPauseAnimation class provides a pause for QSequentialAnimationGroup.
+ \since 4.6
+ \ingroup animation
+
+ If you wish to introduce a delay between animations in a
+ QSequentialAnimationGroup, you can insert a QPauseAnimation. This
+ class does not animate anything, but does not
+ \l{QAbstractAnimation::finished()}{finish} before a specified
+ number of milliseconds have elapsed from when it was started. You
+ specify the duration of the pause in the constructor. It can also
+ be set directly with setDuration().
+
+ It is not necessary to construct a QPauseAnimation yourself.
+ QSequentialAnimationGroup provides the convenience functions
+ \l{QSequentialAnimationGroup::}{addPause()} and
+ \l{QSequentialAnimationGroup::}{insertPause()}. These functions
+ simply take the number of milliseconds the pause should last.
+
+ \sa QSequentialAnimationGroup
+*/
+
+#include "qpauseanimation.h"
+#include "qabstractanimation_p.h"
+
+
+#ifndef QT_NO_ANIMATION
+
+QT_BEGIN_NAMESPACE
+
+class QPauseAnimationPrivate : public QAbstractAnimationPrivate
+{
+public:
+ QPauseAnimationPrivate() : QAbstractAnimationPrivate(), duration(250)
+ {
+ isPause = true;
+ }
+
+ int duration;
+};
+
+/*!
+ Constructs a QPauseAnimation.
+ \a parent is passed to QObject's constructor.
+ The default duration is 0.
+*/
+
+QPauseAnimation::QPauseAnimation(QObject *parent) : QAbstractAnimation(*new QPauseAnimationPrivate, parent)
+{
+}
+
+/*!
+ Constructs a QPauseAnimation.
+ \a msecs is the duration of the pause.
+ \a parent is passed to QObject's constructor.
+*/
+
+QPauseAnimation::QPauseAnimation(int msecs, QObject *parent) : QAbstractAnimation(*new QPauseAnimationPrivate, parent)
+{
+ setDuration(msecs);
+}
+
+/*!
+ Destroys the pause animation.
+*/
+QPauseAnimation::~QPauseAnimation()
+{
+}
+
+/*!
+ \property QPauseAnimation::duration
+ \brief the duration of the pause.
+
+ The duration of the pause. The duration should not be negative.
+ The default duration is 250 milliseconds.
+*/
+int QPauseAnimation::duration() const
+{
+ Q_D(const QPauseAnimation);
+ return d->duration;
+}
+
+void QPauseAnimation::setDuration(int msecs)
+{
+ if (msecs < 0) {
+ qWarning("QPauseAnimation::setDuration: cannot set a negative duration");
+ return;
+ }
+ Q_D(QPauseAnimation);
+ d->duration = msecs;
+}
+
+/*!
+ \reimp
+ */
+bool QPauseAnimation::event(QEvent *e)
+{
+ return QAbstractAnimation::event(e);
+}
+
+/*!
+ \reimp
+ */
+void QPauseAnimation::updateCurrentTime(int)
+{
+}
+
+
+QT_END_NAMESPACE
+
+#include "moc_qpauseanimation.cpp"
+
+#endif //QT_NO_ANIMATION
diff --git a/src/corelib/animation/qpauseanimation.h b/src/corelib/animation/qpauseanimation.h
new file mode 100644
index 0000000000..1da7865256
--- /dev/null
+++ b/src/corelib/animation/qpauseanimation.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPAUSEANIMATION_P_H
+#define QPAUSEANIMATION_P_H
+
+#include <QtCore/qanimationgroup.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+#ifndef QT_NO_ANIMATION
+
+class QPauseAnimationPrivate;
+
+class Q_CORE_EXPORT QPauseAnimation : public QAbstractAnimation
+{
+ Q_OBJECT
+ Q_PROPERTY(int duration READ duration WRITE setDuration)
+public:
+ QPauseAnimation(QObject *parent = 0);
+ QPauseAnimation(int msecs, QObject *parent = 0);
+ ~QPauseAnimation();
+
+ int duration() const;
+ void setDuration(int msecs);
+
+protected:
+ bool event(QEvent *e);
+ void updateCurrentTime(int);
+
+private:
+ Q_DISABLE_COPY(QPauseAnimation)
+ Q_DECLARE_PRIVATE(QPauseAnimation)
+};
+
+#endif //QT_NO_ANIMATION
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QPAUSEANIMATION_P_H
diff --git a/src/corelib/animation/qpropertyanimation.cpp b/src/corelib/animation/qpropertyanimation.cpp
new file mode 100644
index 0000000000..cc642358f0
--- /dev/null
+++ b/src/corelib/animation/qpropertyanimation.cpp
@@ -0,0 +1,317 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QPropertyAnimation
+ \brief The QPropertyAnimation class animates Qt properties
+ \since 4.6
+
+ \ingroup animation
+
+ QPropertyAnimation interpolates over \l{Qt's Property System}{Qt
+ properties}. As property values are stored in \l{QVariant}s, the
+ class inherits QVariantAnimation, and supports animation of the
+ same \l{QVariant::Type}{variant types} as its super class.
+
+ A class declaring properties must be a QObject. To make it
+ possible to animate a property, it must provide a setter (so that
+ QPropertyAnimation can set the property's value). Note that this
+ makes it possible to animate many of Qt's widgets. Let's look at
+ an example:
+
+ \code
+ QPropertyAnimation *animation = new QPropertyAnimation(myWidget, "geometry");
+ animation->setDuration(10000);
+ animation->setStartValue(QRect(0, 0, 100, 30));
+ animation->setEndValue(QRect(250, 250, 100, 30));
+
+ animation->start();
+ \endcode
+
+ The property name and the QObject instance of which property
+ should be animated are passed to the constructor. You can then
+ specify the start and end value of the property. The procedure is
+ equal for properties in classes you have implemented
+ yourself--just check with QVariantAnimation that your QVariant
+ type is supported.
+
+ The QVariantAnimation class description explains how to set up the
+ animation in detail. Note, however, that if a start value is not
+ set, the property will start at the value it had when the
+ QPropertyAnimation instance was created.
+
+ QPropertyAnimation works like a charm on its own. For complex
+ animations that, for instance, contain several objects,
+ QAnimationGroup is provided. An animation group is an animation
+ that can contain other animations, and that can manage when its
+ animations are played. Look at QParallelAnimationGroup for an
+ example.
+
+ \sa QVariantAnimation, QAnimationGroup, {The Animation Framework}
+*/
+
+#include "qpropertyanimation.h"
+#include "qanimationgroup.h"
+#include "qpropertyanimation_p.h"
+
+#include <private/qmutexpool_p.h>
+
+#ifndef QT_NO_ANIMATION
+
+QT_BEGIN_NAMESPACE
+
+void QPropertyAnimationPrivate::updateMetaProperty()
+{
+ if (!target || propertyName.isEmpty()) {
+ propertyType = QVariant::Invalid;
+ propertyIndex = -1;
+ return;
+ }
+
+ //propertyType will be set to a valid type only if there is a Q_PROPERTY
+ //otherwise it will be set to QVariant::Invalid at the end of this function
+ propertyType = targetValue->property(propertyName).userType();
+ propertyIndex = targetValue->metaObject()->indexOfProperty(propertyName);
+
+ if (propertyType != QVariant::Invalid)
+ convertValues(propertyType);
+ if (propertyIndex == -1) {
+ //there is no Q_PROPERTY on the object
+ propertyType = QVariant::Invalid;
+ if (!targetValue->dynamicPropertyNames().contains(propertyName))
+ qWarning("QPropertyAnimation: you're trying to animate a non-existing property %s of your QObject", propertyName.constData());
+ } else if (!targetValue->metaObject()->property(propertyIndex).isWritable()) {
+ qWarning("QPropertyAnimation: you're trying to animate the non-writable property %s of your QObject", propertyName.constData());
+ }
+}
+
+void QPropertyAnimationPrivate::updateProperty(const QVariant &newValue)
+{
+ if (state == QAbstractAnimation::Stopped)
+ return;
+
+ if (!target) {
+ q_func()->stop(); //the target was destroyed we need to stop the animation
+ return;
+ }
+
+ if (newValue.userType() == propertyType) {
+ //no conversion is needed, we directly call the QMetaObject::metacall
+ void *data = const_cast<void*>(newValue.constData());
+ QMetaObject::metacall(targetValue, QMetaObject::WriteProperty, propertyIndex, &data);
+ } else {
+ targetValue->setProperty(propertyName.constData(), newValue);
+ }
+}
+
+/*!
+ Construct a QPropertyAnimation object. \a parent is passed to QObject's
+ constructor.
+*/
+QPropertyAnimation::QPropertyAnimation(QObject *parent)
+ : QVariantAnimation(*new QPropertyAnimationPrivate, parent)
+{
+}
+
+/*!
+ Construct a QPropertyAnimation object. \a parent is passed to QObject's
+ constructor. The animation changes the property \a propertyName on \a
+ target. The default duration is 250ms.
+
+ \sa targetObject, propertyName
+*/
+QPropertyAnimation::QPropertyAnimation(QObject *target, const QByteArray &propertyName, QObject *parent)
+ : QVariantAnimation(*new QPropertyAnimationPrivate, parent)
+{
+ setTargetObject(target);
+ setPropertyName(propertyName);
+}
+
+/*!
+ Destroys the QPropertyAnimation instance.
+ */
+QPropertyAnimation::~QPropertyAnimation()
+{
+ stop();
+}
+
+/*!
+ \property QPropertyAnimation::targetObject
+ \brief the target QObject for this animation.
+
+ This property defines the target QObject for this animation.
+ */
+QObject *QPropertyAnimation::targetObject() const
+{
+ return d_func()->target.data();
+}
+
+void QPropertyAnimation::setTargetObject(QObject *target)
+{
+ Q_D(QPropertyAnimation);
+ if (d->targetValue == target)
+ return;
+
+ if (d->state != QAbstractAnimation::Stopped) {
+ qWarning("QPropertyAnimation::setTargetObject: you can't change the target of a running animation");
+ return;
+ }
+
+ d->target = d->targetValue = target;
+ d->updateMetaProperty();
+}
+
+/*!
+ \property QPropertyAnimation::propertyName
+ \brief the target property name for this animation
+
+ This property defines the target property name for this animation. The
+ property name is required for the animation to operate.
+ */
+QByteArray QPropertyAnimation::propertyName() const
+{
+ Q_D(const QPropertyAnimation);
+ return d->propertyName;
+}
+
+void QPropertyAnimation::setPropertyName(const QByteArray &propertyName)
+{
+ Q_D(QPropertyAnimation);
+ if (d->state != QAbstractAnimation::Stopped) {
+ qWarning("QPropertyAnimation::setPropertyName: you can't change the property name of a running animation");
+ return;
+ }
+
+ d->propertyName = propertyName;
+ d->updateMetaProperty();
+}
+
+
+/*!
+ \reimp
+ */
+bool QPropertyAnimation::event(QEvent *event)
+{
+ return QVariantAnimation::event(event);
+}
+
+/*!
+ This virtual function is called by QVariantAnimation whenever the current value
+ changes. \a value is the new, updated value. It updates the current value
+ of the property on the target object.
+
+ \sa currentValue, currentTime
+ */
+void QPropertyAnimation::updateCurrentValue(const QVariant &value)
+{
+ Q_D(QPropertyAnimation);
+ d->updateProperty(value);
+}
+
+/*!
+ \reimp
+
+ If the startValue is not defined when the state of the animation changes from Stopped to Running,
+ the current property value is used as the initial value for the animation.
+*/
+void QPropertyAnimation::updateState(QAbstractAnimation::State newState,
+ QAbstractAnimation::State oldState)
+{
+ Q_D(QPropertyAnimation);
+
+ if (!d->target && oldState == Stopped) {
+ qWarning("QPropertyAnimation::updateState (%s): Changing state of an animation without target",
+ d->propertyName.constData());
+ return;
+ }
+
+ QVariantAnimation::updateState(newState, oldState);
+
+ QPropertyAnimation *animToStop = 0;
+ {
+#ifndef QT_NO_THREAD
+ QMutexLocker locker(QMutexPool::globalInstanceGet(&staticMetaObject));
+#endif
+ typedef QPair<QObject *, QByteArray> QPropertyAnimationPair;
+ typedef QHash<QPropertyAnimationPair, QPropertyAnimation*> QPropertyAnimationHash;
+ static QPropertyAnimationHash hash;
+ //here we need to use value because we need to know to which pointer
+ //the animation was referring in case stopped because the target was destroyed
+ QPropertyAnimationPair key(d->targetValue, d->propertyName);
+ if (newState == Running) {
+ d->updateMetaProperty();
+ animToStop = hash.value(key, 0);
+ hash.insert(key, this);
+ // update the default start value
+ if (oldState == Stopped) {
+ d->setDefaultStartEndValue(d->targetValue->property(d->propertyName.constData()));
+ //let's check if we have a start value and an end value
+ if (!startValue().isValid() && (d->direction == Backward || !d->defaultStartEndValue.isValid())) {
+ qWarning("QPropertyAnimation::updateState (%s, %s, %s): starting an animation without start value",
+ d->propertyName.constData(), d->target.data()->metaObject()->className(),
+ qPrintable(d->target.data()->objectName()));
+ }
+ if (!endValue().isValid() && (d->direction == Forward || !d->defaultStartEndValue.isValid())) {
+ qWarning("QPropertyAnimation::updateState (%s, %s, %s): starting an animation without end value",
+ d->propertyName.constData(), d->target.data()->metaObject()->className(),
+ qPrintable(d->target.data()->objectName()));
+ }
+ }
+ } else if (hash.value(key) == this) {
+ hash.remove(key);
+ }
+ }
+
+ //we need to do that after the mutex was unlocked
+ if (animToStop) {
+ // try to stop the top level group
+ QAbstractAnimation *current = animToStop;
+ while (current->group() && current->state() != Stopped)
+ current = current->group();
+ current->stop();
+ }
+}
+
+#include "moc_qpropertyanimation.cpp"
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_ANIMATION
diff --git a/src/corelib/animation/qpropertyanimation.h b/src/corelib/animation/qpropertyanimation.h
new file mode 100644
index 0000000000..379efe10f7
--- /dev/null
+++ b/src/corelib/animation/qpropertyanimation.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPROPERTYANIMATION_H
+#define QPROPERTYANIMATION_H
+
+#include <QtCore/qvariantanimation.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+#ifndef QT_NO_ANIMATION
+
+class QPropertyAnimationPrivate;
+class Q_CORE_EXPORT QPropertyAnimation : public QVariantAnimation
+{
+ Q_OBJECT
+ Q_PROPERTY(QByteArray propertyName READ propertyName WRITE setPropertyName)
+ Q_PROPERTY(QObject* targetObject READ targetObject WRITE setTargetObject)
+
+public:
+ QPropertyAnimation(QObject *parent = 0);
+ QPropertyAnimation(QObject *target, const QByteArray &propertyName, QObject *parent = 0);
+ ~QPropertyAnimation();
+
+ QObject *targetObject() const;
+ void setTargetObject(QObject *target);
+
+ QByteArray propertyName() const;
+ void setPropertyName(const QByteArray &propertyName);
+
+protected:
+ bool event(QEvent *event);
+ void updateCurrentValue(const QVariant &value);
+ void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState);
+
+private:
+ Q_DISABLE_COPY(QPropertyAnimation)
+ Q_DECLARE_PRIVATE(QPropertyAnimation)
+};
+
+#endif //QT_NO_ANIMATION
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QPROPERTYANIMATION_H
diff --git a/src/corelib/animation/qpropertyanimation_p.h b/src/corelib/animation/qpropertyanimation_p.h
new file mode 100644
index 0000000000..f1df91ed1f
--- /dev/null
+++ b/src/corelib/animation/qpropertyanimation_p.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPROPERTYANIMATION_P_H
+#define QPROPERTYANIMATION_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of QIODevice. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qpropertyanimation.h"
+
+#include "private/qvariantanimation_p.h"
+
+#ifndef QT_NO_ANIMATION
+
+QT_BEGIN_NAMESPACE
+
+class QPropertyAnimationPrivate : public QVariantAnimationPrivate
+{
+ Q_DECLARE_PUBLIC(QPropertyAnimation)
+public:
+ QPropertyAnimationPrivate()
+ : targetValue(0), propertyType(0), propertyIndex(-1)
+ {
+ }
+
+ QWeakPointer<QObject> target;
+ //we use targetValue to be able to unregister the target from the global hash
+ QObject *targetValue;
+
+ //for the QProperty
+ int propertyType;
+ int propertyIndex;
+
+ QByteArray propertyName;
+ void updateProperty(const QVariant &);
+ void updateMetaProperty();
+};
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_ANIMATION
+
+#endif //QPROPERTYANIMATION_P_H
diff --git a/src/corelib/animation/qsequentialanimationgroup.cpp b/src/corelib/animation/qsequentialanimationgroup.cpp
new file mode 100644
index 0000000000..2e73104c6e
--- /dev/null
+++ b/src/corelib/animation/qsequentialanimationgroup.cpp
@@ -0,0 +1,588 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QSequentialAnimationGroup
+ \brief The QSequentialAnimationGroup class provides a sequential group of animations.
+ \since 4.6
+ \ingroup animation
+
+ QSequentialAnimationGroup is a QAnimationGroup that runs its
+ animations in sequence, i.e., it starts one animation after
+ another has finished playing. The animations are played in the
+ order they are added to the group (using
+ \l{QAnimationGroup::}{addAnimation()} or
+ \l{QAnimationGroup::}{insertAnimation()}). The animation group
+ finishes when its last animation has finished.
+
+ At each moment there is at most one animation that is active in
+ the group; it is returned by currentAnimation(). An empty group
+ has no current animation.
+
+ A sequential animation group can be treated as any other
+ animation, i.e., it can be started, stopped, and added to other
+ groups. You can also call addPause() or insertPause() to add a
+ pause to a sequential animation group.
+
+ \code
+ QSequentialAnimationGroup *group = new QSequentialAnimationGroup;
+
+ group->addAnimation(anim1);
+ group->addAnimation(anim2);
+
+ group->start();
+ \endcode
+
+ In this example, \c anim1 and \c anim2 are two already set up
+ \l{QPropertyAnimation}s.
+
+ \sa QAnimationGroup, QAbstractAnimation, {The Animation Framework}
+*/
+
+#include "qsequentialanimationgroup.h"
+#include "qsequentialanimationgroup_p.h"
+
+#include "qpauseanimation.h"
+
+#include <QtCore/qdebug.h>
+
+#ifndef QT_NO_ANIMATION
+
+QT_BEGIN_NAMESPACE
+
+bool QSequentialAnimationGroupPrivate::atEnd() const
+{
+ // we try to detect if we're at the end of the group
+ //this is true if the following conditions are true:
+ // 1. we're in the last loop
+ // 2. the direction is forward
+ // 3. the current animation is the last one
+ // 4. the current animation has reached its end
+ const int animTotalCurrentTime = QAbstractAnimationPrivate::get(currentAnimation)->totalCurrentTime;
+ return (currentLoop == loopCount - 1
+ && direction == QAbstractAnimation::Forward
+ && currentAnimation == animations.last()
+ && animTotalCurrentTime == animationActualTotalDuration(currentAnimationIndex));
+}
+
+int QSequentialAnimationGroupPrivate::animationActualTotalDuration(int index) const
+{
+ QAbstractAnimation *anim = animations.at(index);
+ int ret = anim->totalDuration();
+ if (ret == -1 && actualDuration.size() > index)
+ ret = actualDuration.at(index); //we can try the actual duration there
+ return ret;
+}
+
+QSequentialAnimationGroupPrivate::AnimationIndex QSequentialAnimationGroupPrivate::indexForCurrentTime() const
+{
+ Q_ASSERT(!animations.isEmpty());
+
+ AnimationIndex ret;
+ int duration = 0;
+
+ for (int i = 0; i < animations.size(); ++i) {
+ duration = animationActualTotalDuration(i);
+
+ // 'animation' is the current animation if one of these reasons is true:
+ // 1. it's duration is undefined
+ // 2. it ends after msecs
+ // 3. it is the last animation (this can happen in case there is at least 1 uncontrolled animation)
+ // 4. it ends exactly in msecs and the direction is backwards
+ if (duration == -1 || currentTime < (ret.timeOffset + duration)
+ || (currentTime == (ret.timeOffset + duration) && direction == QAbstractAnimation::Backward)) {
+ ret.index = i;
+ return ret;
+ }
+
+ // 'animation' has a non-null defined duration and is not the one at time 'msecs'.
+ ret.timeOffset += duration;
+ }
+
+ // this can only happen when one of those conditions is true:
+ // 1. the duration of the group is undefined and we passed its actual duration
+ // 2. there are only 0-duration animations in the group
+ ret.timeOffset -= duration;
+ ret.index = animations.size() - 1;
+ return ret;
+}
+
+void QSequentialAnimationGroupPrivate::restart()
+{
+ // restarting the group by making the first/last animation the current one
+ if (direction == QAbstractAnimation::Forward) {
+ lastLoop = 0;
+ if (currentAnimationIndex == 0)
+ activateCurrentAnimation();
+ else
+ setCurrentAnimation(0);
+ } else { // direction == QAbstractAnimation::Backward
+ lastLoop = loopCount - 1;
+ int index = animations.size() - 1;
+ if (currentAnimationIndex == index)
+ activateCurrentAnimation();
+ else
+ setCurrentAnimation(index);
+ }
+}
+
+/*!
+ \internal
+ This manages advancing the execution of a group running forwards (time has gone forward),
+ which is the same behaviour for rewinding the execution of a group running backwards
+ (time has gone backward).
+*/
+void QSequentialAnimationGroupPrivate::advanceForwards(const AnimationIndex &newAnimationIndex)
+{
+ if (lastLoop < currentLoop) {
+ // we need to fast forward to the end
+ for (int i = currentAnimationIndex; i < animations.size(); ++i) {
+ QAbstractAnimation *anim = animations.at(i);
+ setCurrentAnimation(i, true);
+ anim->setCurrentTime(animationActualTotalDuration(i));
+ }
+ // this will make sure the current animation is reset to the beginning
+ if (animations.size() == 1)
+ // we need to force activation because setCurrentAnimation will have no effect
+ activateCurrentAnimation();
+ else
+ setCurrentAnimation(0, true);
+ }
+
+ // and now we need to fast forward from the current position to
+ for (int i = currentAnimationIndex; i < newAnimationIndex.index; ++i) { //### WRONG,
+ QAbstractAnimation *anim = animations.at(i);
+ setCurrentAnimation(i, true);
+ anim->setCurrentTime(animationActualTotalDuration(i));
+ }
+ // setting the new current animation will happen later
+}
+
+/*!
+ \internal
+ This manages rewinding the execution of a group running forwards (time has gone forward),
+ which is the same behaviour for advancing the execution of a group running backwards
+ (time has gone backward).
+*/
+void QSequentialAnimationGroupPrivate::rewindForwards(const AnimationIndex &newAnimationIndex)
+{
+ if (lastLoop > currentLoop) {
+ // we need to fast rewind to the beginning
+ for (int i = currentAnimationIndex; i >= 0 ; --i) {
+ QAbstractAnimation *anim = animations.at(i);
+ setCurrentAnimation(i, true);
+ anim->setCurrentTime(0);
+ }
+ // this will make sure the current animation is reset to the end
+ if (animations.size() == 1)
+ // we need to force activation because setCurrentAnimation will have no effect
+ activateCurrentAnimation();
+ else
+ setCurrentAnimation(animations.count() - 1, true);
+ }
+
+ // and now we need to fast rewind from the current position to
+ for (int i = currentAnimationIndex; i > newAnimationIndex.index; --i) {
+ QAbstractAnimation *anim = animations.at(i);
+ setCurrentAnimation(i, true);
+ anim->setCurrentTime(0);
+ }
+ // setting the new current animation will happen later
+}
+
+/*!
+ \fn QSequentialAnimationGroup::currentAnimationChanged(QAbstractAnimation *current)
+
+ QSequentialAnimationGroup emits this signal when currentAnimation
+ has been changed. \a current is the current animation.
+
+ \sa currentAnimation()
+*/
+
+
+/*!
+ Constructs a QSequentialAnimationGroup.
+ \a parent is passed to QObject's constructor.
+*/
+QSequentialAnimationGroup::QSequentialAnimationGroup(QObject *parent)
+ : QAnimationGroup(*new QSequentialAnimationGroupPrivate, parent)
+{
+}
+
+/*!
+ \internal
+*/
+QSequentialAnimationGroup::QSequentialAnimationGroup(QSequentialAnimationGroupPrivate &dd,
+ QObject *parent)
+ : QAnimationGroup(dd, parent)
+{
+}
+
+/*!
+ Destroys the animation group. It will also destroy all its animations.
+*/
+QSequentialAnimationGroup::~QSequentialAnimationGroup()
+{
+}
+
+/*!
+ Adds a pause of \a msecs to this animation group.
+ The pause is considered as a special type of animation, thus
+ \l{QAnimationGroup::animationCount()}{animationCount} will be
+ increased by one.
+
+ \sa insertPause(), QAnimationGroup::addAnimation()
+*/
+QPauseAnimation *QSequentialAnimationGroup::addPause(int msecs)
+{
+ QPauseAnimation *pause = new QPauseAnimation(msecs);
+ addAnimation(pause);
+ return pause;
+}
+
+/*!
+ Inserts a pause of \a msecs milliseconds at \a index in this animation
+ group.
+
+ \sa addPause(), QAnimationGroup::insertAnimation()
+*/
+QPauseAnimation *QSequentialAnimationGroup::insertPause(int index, int msecs)
+{
+ Q_D(const QSequentialAnimationGroup);
+
+ if (index < 0 || index > d->animations.size()) {
+ qWarning("QSequentialAnimationGroup::insertPause: index is out of bounds");
+ return 0;
+ }
+
+ QPauseAnimation *pause = new QPauseAnimation(msecs);
+ insertAnimation(index, pause);
+ return pause;
+}
+
+
+/*!
+ \property QSequentialAnimationGroup::currentAnimation
+ Returns the animation in the current time.
+
+ \sa currentAnimationChanged()
+*/
+QAbstractAnimation *QSequentialAnimationGroup::currentAnimation() const
+{
+ Q_D(const QSequentialAnimationGroup);
+ return d->currentAnimation;
+}
+
+/*!
+ \reimp
+*/
+int QSequentialAnimationGroup::duration() const
+{
+ Q_D(const QSequentialAnimationGroup);
+ int ret = 0;
+
+ for (int i = 0; i < d->animations.size(); ++i) {
+ QAbstractAnimation *animation = d->animations.at(i);
+ const int currentDuration = animation->totalDuration();
+ if (currentDuration == -1)
+ return -1; // Undetermined length
+
+ ret += currentDuration;
+ }
+
+ return ret;
+}
+
+/*!
+ \reimp
+*/
+void QSequentialAnimationGroup::updateCurrentTime(int currentTime)
+{
+ Q_D(QSequentialAnimationGroup);
+ if (!d->currentAnimation)
+ return;
+
+ const QSequentialAnimationGroupPrivate::AnimationIndex newAnimationIndex = d->indexForCurrentTime();
+
+ // remove unneeded animations from actualDuration list
+ while (newAnimationIndex.index < d->actualDuration.size())
+ d->actualDuration.removeLast();
+
+ // newAnimationIndex.index is the new current animation
+ if (d->lastLoop < d->currentLoop
+ || (d->lastLoop == d->currentLoop && d->currentAnimationIndex < newAnimationIndex.index)) {
+ // advancing with forward direction is the same as rewinding with backwards direction
+ d->advanceForwards(newAnimationIndex);
+ } else if (d->lastLoop > d->currentLoop
+ || (d->lastLoop == d->currentLoop && d->currentAnimationIndex > newAnimationIndex.index)) {
+ // rewinding with forward direction is the same as advancing with backwards direction
+ d->rewindForwards(newAnimationIndex);
+ }
+
+ d->setCurrentAnimation(newAnimationIndex.index);
+
+ const int newCurrentTime = currentTime - newAnimationIndex.timeOffset;
+
+ if (d->currentAnimation) {
+ d->currentAnimation->setCurrentTime(newCurrentTime);
+ if (d->atEnd()) {
+ //we make sure that we don't exceed the duration here
+ d->currentTime += QAbstractAnimationPrivate::get(d->currentAnimation)->totalCurrentTime - newCurrentTime;
+ stop();
+ }
+ } else {
+ //the only case where currentAnimation could be null
+ //is when all animations have been removed
+ Q_ASSERT(d->animations.isEmpty());
+ d->currentTime = 0;
+ stop();
+ }
+
+ d->lastLoop = d->currentLoop;
+}
+
+/*!
+ \reimp
+*/
+void QSequentialAnimationGroup::updateState(QAbstractAnimation::State newState,
+ QAbstractAnimation::State oldState)
+{
+ Q_D(QSequentialAnimationGroup);
+ QAnimationGroup::updateState(newState, oldState);
+
+ if (!d->currentAnimation)
+ return;
+
+ switch (newState) {
+ case Stopped:
+ d->currentAnimation->stop();
+ break;
+ case Paused:
+ if (oldState == d->currentAnimation->state()
+ && oldState == QSequentialAnimationGroup::Running) {
+ d->currentAnimation->pause();
+ }
+ else
+ d->restart();
+ break;
+ case Running:
+ if (oldState == d->currentAnimation->state()
+ && oldState == QSequentialAnimationGroup::Paused)
+ d->currentAnimation->start();
+ else
+ d->restart();
+ break;
+ }
+}
+
+/*!
+ \reimp
+*/
+void QSequentialAnimationGroup::updateDirection(QAbstractAnimation::Direction direction)
+{
+ Q_D(QSequentialAnimationGroup);
+ // we need to update the direction of the current animation
+ if (state() != Stopped && d->currentAnimation)
+ d->currentAnimation->setDirection(direction);
+}
+
+/*!
+ \reimp
+*/
+bool QSequentialAnimationGroup::event(QEvent *event)
+{
+ return QAnimationGroup::event(event);
+}
+
+void QSequentialAnimationGroupPrivate::setCurrentAnimation(int index, bool intermediate)
+{
+ Q_Q(QSequentialAnimationGroup);
+
+ index = qMin(index, animations.count() - 1);
+
+ if (index == -1) {
+ Q_ASSERT(animations.isEmpty());
+ currentAnimationIndex = -1;
+ currentAnimation = 0;
+ return;
+ }
+
+ // need these two checks below because this func can be called after the current animation
+ // has been removed
+ if (index == currentAnimationIndex && animations.at(index) == currentAnimation)
+ return;
+
+ // stop the old current animation
+ if (currentAnimation)
+ currentAnimation->stop();
+
+ currentAnimation = animations.at(index);
+ currentAnimationIndex = index;
+
+ emit q->currentAnimationChanged(currentAnimation);
+
+ activateCurrentAnimation(intermediate);
+}
+
+void QSequentialAnimationGroupPrivate::activateCurrentAnimation(bool intermediate)
+{
+ if (!currentAnimation || state == QSequentialAnimationGroup::Stopped)
+ return;
+
+ currentAnimation->stop();
+
+ // we ensure the direction is consistent with the group's direction
+ currentAnimation->setDirection(direction);
+
+ // connects to the finish signal of uncontrolled animations
+ if (currentAnimation->totalDuration() == -1)
+ connectUncontrolledAnimation(currentAnimation);
+
+ currentAnimation->start();
+ if (!intermediate && state == QSequentialAnimationGroup::Paused)
+ currentAnimation->pause();
+}
+
+void QSequentialAnimationGroupPrivate::_q_uncontrolledAnimationFinished()
+{
+ Q_Q(QSequentialAnimationGroup);
+ Q_ASSERT(qobject_cast<QAbstractAnimation *>(q->sender()) == currentAnimation);
+
+ // we trust the duration returned by the animation
+ while (actualDuration.size() < (currentAnimationIndex + 1))
+ actualDuration.append(-1);
+ actualDuration[currentAnimationIndex] = currentAnimation->currentTime();
+
+ disconnectUncontrolledAnimation(currentAnimation);
+
+ if ((direction == QAbstractAnimation::Forward && currentAnimation == animations.last())
+ || (direction == QAbstractAnimation::Backward && currentAnimationIndex == 0)) {
+ // we don't handle looping of a group with undefined duration
+ q->stop();
+ } else if (direction == QAbstractAnimation::Forward) {
+ // set the current animation to be the next one
+ setCurrentAnimation(currentAnimationIndex + 1);
+ } else {
+ // set the current animation to be the previous one
+ setCurrentAnimation(currentAnimationIndex - 1);
+ }
+}
+
+/*!
+ \internal
+ This method is called whenever an animation is added to
+ the group at index \a index.
+ Note: We only support insertion after the current animation
+*/
+void QSequentialAnimationGroupPrivate::animationInsertedAt(int index)
+{
+ if (currentAnimation == 0)
+ setCurrentAnimation(0); // initialize the current animation
+
+ if (currentAnimationIndex == index
+ && currentAnimation->currentTime() == 0 && currentAnimation->currentLoop() == 0) {
+ //in this case we simply insert an animation before the current one has actually started
+ setCurrentAnimation(index);
+ }
+
+ //we update currentAnimationIndex in case it has changed (the animation pointer is still valid)
+ currentAnimationIndex = animations.indexOf(currentAnimation);
+
+ if (index < currentAnimationIndex || currentLoop != 0) {
+ qWarning("QSequentialGroup::insertAnimation only supports to add animations after the current one.");
+ return; //we're not affected because it is added after the current one
+ }
+}
+
+/*!
+ \internal
+ This method is called whenever an animation is removed from
+ the group at index \a index. The animation is no more listed when this
+ method is called.
+*/
+void QSequentialAnimationGroupPrivate::animationRemoved(int index, QAbstractAnimation *anim)
+{
+ Q_Q(QSequentialAnimationGroup);
+ QAnimationGroupPrivate::animationRemoved(index, anim);
+
+ Q_ASSERT(currentAnimation); // currentAnimation should always be set
+
+ if (actualDuration.size() > index)
+ actualDuration.removeAt(index);
+
+ const int currentIndex = animations.indexOf(currentAnimation);
+ if (currentIndex == -1) {
+ //we're removing the current animation
+
+ disconnectUncontrolledAnimation(currentAnimation);
+
+ if (index < animations.count())
+ setCurrentAnimation(index); //let's try to take the next one
+ else if (index > 0)
+ setCurrentAnimation(index - 1);
+ else// case all animations were removed
+ setCurrentAnimation(-1);
+ } else if (currentAnimationIndex > index) {
+ currentAnimationIndex--;
+ }
+
+ // duration of the previous animations up to the current animation
+ currentTime = 0;
+ for (int i = 0; i < currentAnimationIndex; ++i) {
+ const int current = animationActualTotalDuration(i);
+ currentTime += current;
+ }
+
+ if (currentIndex != -1) {
+ //the current animation is not the one being removed
+ //so we add its current time to the current time of this group
+ currentTime += QAbstractAnimationPrivate::get(currentAnimation)->totalCurrentTime;
+ }
+
+ //let's also update the total current time
+ totalCurrentTime = currentTime + loopCount * q->duration();
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qsequentialanimationgroup.cpp"
+
+#endif //QT_NO_ANIMATION
diff --git a/src/corelib/animation/qsequentialanimationgroup.h b/src/corelib/animation/qsequentialanimationgroup.h
new file mode 100644
index 0000000000..3bb766183f
--- /dev/null
+++ b/src/corelib/animation/qsequentialanimationgroup.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSEQUENTIALANIMATIONGROUP_H
+#define QSEQUENTIALANIMATIONGROUP_H
+
+#include <QtCore/qanimationgroup.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+#ifndef QT_NO_ANIMATION
+
+class QPauseAnimation;
+class QSequentialAnimationGroupPrivate;
+
+class Q_CORE_EXPORT QSequentialAnimationGroup : public QAnimationGroup
+{
+ Q_OBJECT
+ Q_PROPERTY(QAbstractAnimation* currentAnimation READ currentAnimation NOTIFY currentAnimationChanged)
+
+public:
+ QSequentialAnimationGroup(QObject *parent = 0);
+ ~QSequentialAnimationGroup();
+
+ QPauseAnimation *addPause(int msecs);
+ QPauseAnimation *insertPause(int index, int msecs);
+
+ QAbstractAnimation *currentAnimation() const;
+ int duration() const;
+
+Q_SIGNALS:
+ void currentAnimationChanged(QAbstractAnimation *current);
+
+protected:
+ QSequentialAnimationGroup(QSequentialAnimationGroupPrivate &dd, QObject *parent);
+ bool event(QEvent *event);
+
+ void updateCurrentTime(int);
+ void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState);
+ void updateDirection(QAbstractAnimation::Direction direction);
+
+private:
+ Q_DISABLE_COPY(QSequentialAnimationGroup)
+ Q_DECLARE_PRIVATE(QSequentialAnimationGroup)
+ Q_PRIVATE_SLOT(d_func(), void _q_uncontrolledAnimationFinished())
+};
+
+#endif //QT_NO_ANIMATION
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif //QSEQUENTIALANIMATIONGROUP_H
diff --git a/src/corelib/animation/qsequentialanimationgroup_p.h b/src/corelib/animation/qsequentialanimationgroup_p.h
new file mode 100644
index 0000000000..2337e845f3
--- /dev/null
+++ b/src/corelib/animation/qsequentialanimationgroup_p.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSEQUENTIALANIMATIONGROUP_P_H
+#define QSEQUENTIALANIMATIONGROUP_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of QIODevice. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qsequentialanimationgroup.h"
+#include "private/qanimationgroup_p.h"
+
+#ifndef QT_NO_ANIMATION
+
+QT_BEGIN_NAMESPACE
+
+class QSequentialAnimationGroupPrivate : public QAnimationGroupPrivate
+{
+ Q_DECLARE_PUBLIC(QSequentialAnimationGroup)
+public:
+ QSequentialAnimationGroupPrivate()
+ : currentAnimation(0), currentAnimationIndex(-1), lastLoop(0)
+ { }
+
+
+ struct AnimationIndex
+ {
+ AnimationIndex() : index(0), timeOffset(0) {}
+ // index points to the animation at timeOffset, skipping 0 duration animations.
+ // Note that the index semantic is slightly different depending on the direction.
+ int index; // the index of the animation in timeOffset
+ int timeOffset; // time offset when the animation at index starts.
+ };
+
+ int animationActualTotalDuration(int index) const;
+ AnimationIndex indexForCurrentTime() const;
+
+ void setCurrentAnimation(int index, bool intermediate = false);
+ void activateCurrentAnimation(bool intermediate = false);
+
+ void animationInsertedAt(int index);
+ void animationRemoved(int index, QAbstractAnimation *anim);
+
+ bool atEnd() const;
+
+ QAbstractAnimation *currentAnimation;
+ int currentAnimationIndex;
+
+ // this is the actual duration of uncontrolled animations
+ // it helps seeking and even going forward
+ QList<int> actualDuration;
+
+ void restart();
+ int lastLoop;
+
+ // handle time changes
+ void rewindForwards(const AnimationIndex &newAnimationIndex);
+ void advanceForwards(const AnimationIndex &newAnimationIndex);
+
+ // private slot
+ void _q_uncontrolledAnimationFinished();
+};
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_ANIMATION
+
+#endif //QSEQUENTIALANIMATIONGROUP_P_H
diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp
new file mode 100644
index 0000000000..c76cb89ff9
--- /dev/null
+++ b/src/corelib/animation/qvariantanimation.cpp
@@ -0,0 +1,701 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qvariantanimation.h"
+#include "qvariantanimation_p.h"
+
+#include <QtCore/qrect.h>
+#include <QtCore/qline.h>
+#include <QtCore/qmutex.h>
+#include <private/qmutexpool_p.h>
+
+#ifndef QT_NO_ANIMATION
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QVariantAnimation
+ \ingroup animation
+ \brief The QVariantAnimation class provides an abstract base class for animations.
+ \since 4.6
+
+ This class is part of \l{The Animation Framework}. It serves as a
+ base class for property and item animations, with functions for
+ shared functionality.
+
+ QVariantAnimation cannot be used directly as it is an abstract
+ class; it has a pure virtual method called updateCurrentValue().
+ The class performs interpolation over
+ \l{QVariant}s, but leaves using the interpolated values to its
+ subclasses. Currently, Qt provides QPropertyAnimation, which
+ animates Qt \l{Qt's Property System}{properties}. See the
+ QPropertyAnimation class description if you wish to animate such
+ properties.
+
+ You can then set start and end values for the property by calling
+ setStartValue() and setEndValue(), and finally call start() to
+ start the animation. QVariantAnimation will interpolate the
+ property of the target object and emit valueChanged(). To react to
+ a change in the current value you have to reimplement the
+ updateCurrentValue() virtual function.
+
+ It is also possible to set values at specified steps situated
+ between the start and end value. The interpolation will then
+ touch these points at the specified steps. Note that the start and
+ end values are defined as the key values at 0.0 and 1.0.
+
+ There are two ways to affect how QVariantAnimation interpolates
+ the values. You can set an easing curve by calling
+ setEasingCurve(), and configure the duration by calling
+ setDuration(). You can change how the QVariants are interpolated
+ by creating a subclass of QVariantAnimation, and reimplementing
+ the virtual interpolated() function.
+
+ Subclassing QVariantAnimation can be an alternative if you have
+ \l{QVariant}s that you do not wish to declare as Qt properties.
+ Note, however, that you in most cases will be better off declaring
+ your QVariant as a property.
+
+ Not all QVariant types are supported. Below is a list of currently
+ supported QVariant types:
+
+ \list
+ \o \l{QMetaType::}{Int}
+ \o \l{QMetaType::}{Double}
+ \o \l{QMetaType::}{Float}
+ \o \l{QMetaType::}{QLine}
+ \o \l{QMetaType::}{QLineF}
+ \o \l{QMetaType::}{QPoint}
+ \o \l{QMetaType::}{QPointF}
+ \o \l{QMetaType::}{QSize}
+ \o \l{QMetaType::}{QSizeF}
+ \o \l{QMetaType::}{QRect}
+ \o \l{QMetaType::}{QRectF}
+ \o \l{QMetaType::}{QColor}
+ \endlist
+
+ If you need to interpolate other variant types, including custom
+ types, you have to implement interpolation for these yourself.
+ To do this, you can register an interpolator function for a given
+ type. This function takes 3 parameters: the start value, the end value
+ and the current progress.
+
+ Example:
+ \code
+ QVariant myColorInterpolator(const QColor &start, const QColor &end, qreal progress)
+ {
+ ...
+ return QColor(...);
+ }
+ ...
+ qRegisterAnimationInterpolator<QColor>(myColorInterpolator);
+ \endcode
+
+ Another option is to reimplement interpolated(), which returns
+ interpolation values for the value being interpolated.
+
+ \omit We need some snippets around here. \endomit
+
+ \sa QPropertyAnimation, QAbstractAnimation, {The Animation Framework}
+*/
+
+/*!
+ \fn void QVariantAnimation::valueChanged(const QVariant &value)
+
+ QVariantAnimation emits this signal whenever the current \a value changes.
+
+ \sa currentValue, startValue, endValue
+*/
+
+/*!
+ \fn void QVariantAnimation::updateCurrentValue(const QVariant &value) = 0;
+
+ This pure virtual function is called every time the animation's current
+ value changes. The \a value argument is the new current value.
+
+ \sa currentValue
+*/
+
+static bool animationValueLessThan(const QVariantAnimation::KeyValue &p1, const QVariantAnimation::KeyValue &p2)
+{
+ return p1.first < p2.first;
+}
+
+static QVariant defaultInterpolator(const void *, const void *, qreal)
+{
+ return QVariant();
+}
+
+template<> Q_INLINE_TEMPLATE QRect _q_interpolate(const QRect &f, const QRect &t, qreal progress)
+{
+ QRect ret;
+ ret.setCoords(_q_interpolate(f.left(), t.left(), progress),
+ _q_interpolate(f.top(), t.top(), progress),
+ _q_interpolate(f.right(), t.right(), progress),
+ _q_interpolate(f.bottom(), t.bottom(), progress));
+ return ret;
+}
+
+template<> Q_INLINE_TEMPLATE QRectF _q_interpolate(const QRectF &f, const QRectF &t, qreal progress)
+{
+ qreal x1, y1, w1, h1;
+ f.getRect(&x1, &y1, &w1, &h1);
+ qreal x2, y2, w2, h2;
+ t.getRect(&x2, &y2, &w2, &h2);
+ return QRectF(_q_interpolate(x1, x2, progress), _q_interpolate(y1, y2, progress),
+ _q_interpolate(w1, w2, progress), _q_interpolate(h1, h2, progress));
+}
+
+template<> Q_INLINE_TEMPLATE QLine _q_interpolate(const QLine &f, const QLine &t, qreal progress)
+{
+ return QLine( _q_interpolate(f.p1(), t.p1(), progress), _q_interpolate(f.p2(), t.p2(), progress));
+}
+
+template<> Q_INLINE_TEMPLATE QLineF _q_interpolate(const QLineF &f, const QLineF &t, qreal progress)
+{
+ return QLineF( _q_interpolate(f.p1(), t.p1(), progress), _q_interpolate(f.p2(), t.p2(), progress));
+}
+
+QVariantAnimationPrivate::QVariantAnimationPrivate() : duration(250), interpolator(&defaultInterpolator)
+{ }
+
+void QVariantAnimationPrivate::convertValues(int t)
+{
+ //this ensures that all the keyValues are of type t
+ for (int i = 0; i < keyValues.count(); ++i) {
+ QVariantAnimation::KeyValue &pair = keyValues[i];
+ pair.second.convert(static_cast<QVariant::Type>(t));
+ }
+ //we also need update to the current interval if needed
+ currentInterval.start.second.convert(static_cast<QVariant::Type>(t));
+ currentInterval.end.second.convert(static_cast<QVariant::Type>(t));
+
+ //... and the interpolator
+ updateInterpolator();
+}
+
+void QVariantAnimationPrivate::updateInterpolator()
+{
+ int type = currentInterval.start.second.userType();
+ if (type == currentInterval.end.second.userType())
+ interpolator = getInterpolator(type);
+ else
+ interpolator = 0;
+
+ //we make sure that the interpolator is always set to something
+ if (!interpolator)
+ interpolator = &defaultInterpolator;
+}
+
+/*!
+ \internal
+ The goal of this function is to update the currentInterval member. As a consequence, we also
+ need to update the currentValue.
+ Set \a force to true to always recalculate the interval.
+*/
+void QVariantAnimationPrivate::recalculateCurrentInterval(bool force/*=false*/)
+{
+ // can't interpolate if we don't have at least 2 values
+ if ((keyValues.count() + (defaultStartEndValue.isValid() ? 1 : 0)) < 2)
+ return;
+
+ const qreal progress = easing.valueForProgress(((duration == 0) ? qreal(1) : qreal(currentTime) / qreal(duration)));
+
+ //0 and 1 are still the boundaries
+ if (force || (currentInterval.start.first > 0 && progress < currentInterval.start.first)
+ || (currentInterval.end.first < 1 && progress > currentInterval.end.first)) {
+ //let's update currentInterval
+ QVariantAnimation::KeyValues::const_iterator it = qLowerBound(keyValues.constBegin(),
+ keyValues.constEnd(),
+ qMakePair(progress, QVariant()),
+ animationValueLessThan);
+ if (it == keyValues.constBegin()) {
+ //the item pointed to by it is the start element in the range
+ if (it->first == 0 && keyValues.count() > 1) {
+ currentInterval.start = *it;
+ currentInterval.end = *(it+1);
+ } else {
+ currentInterval.start = qMakePair(qreal(0), defaultStartEndValue);
+ currentInterval.end = *it;
+ }
+ } else if (it == keyValues.constEnd()) {
+ --it; //position the iterator on the last item
+ if (it->first == 1 && keyValues.count() > 1) {
+ //we have an end value (item with progress = 1)
+ currentInterval.start = *(it-1);
+ currentInterval.end = *it;
+ } else {
+ //we use the default end value here
+ currentInterval.start = *it;
+ currentInterval.end = qMakePair(qreal(1), defaultStartEndValue);
+ }
+ } else {
+ currentInterval.start = *(it-1);
+ currentInterval.end = *it;
+ }
+
+ // update all the values of the currentInterval
+ updateInterpolator();
+ }
+ setCurrentValueForProgress(progress);
+}
+
+void QVariantAnimationPrivate::setCurrentValueForProgress(const qreal progress)
+{
+ Q_Q(QVariantAnimation);
+
+ const qreal startProgress = currentInterval.start.first;
+ const qreal endProgress = currentInterval.end.first;
+ const qreal localProgress = (progress - startProgress) / (endProgress - startProgress);
+
+ QVariant ret = q->interpolated(currentInterval.start.second,
+ currentInterval.end.second,
+ localProgress);
+ qSwap(currentValue, ret);
+ q->updateCurrentValue(currentValue);
+ static QBasicAtomicInt changedSignalIndex = Q_BASIC_ATOMIC_INITIALIZER(0);
+ if (!changedSignalIndex) {
+ //we keep the mask so that we emit valueChanged only when needed (for performance reasons)
+ changedSignalIndex.testAndSetRelaxed(0, signalIndex("valueChanged(QVariant)"));
+ }
+ if (isSignalConnected(changedSignalIndex) && currentValue != ret) {
+ //the value has changed
+ emit q->valueChanged(currentValue);
+ }
+}
+
+QVariant QVariantAnimationPrivate::valueAt(qreal step) const
+{
+ QVariantAnimation::KeyValues::const_iterator result =
+ qBinaryFind(keyValues.begin(), keyValues.end(), qMakePair(step, QVariant()), animationValueLessThan);
+ if (result != keyValues.constEnd())
+ return result->second;
+
+ return QVariant();
+}
+
+void QVariantAnimationPrivate::setValueAt(qreal step, const QVariant &value)
+{
+ if (step < qreal(0.0) || step > qreal(1.0)) {
+ qWarning("QVariantAnimation::setValueAt: invalid step = %f", step);
+ return;
+ }
+
+ QVariantAnimation::KeyValue pair(step, value);
+
+ QVariantAnimation::KeyValues::iterator result = qLowerBound(keyValues.begin(), keyValues.end(), pair, animationValueLessThan);
+ if (result == keyValues.end() || result->first != step) {
+ keyValues.insert(result, pair);
+ } else {
+ if (value.isValid())
+ result->second = value; // replaces the previous value
+ else
+ keyValues.erase(result); // removes the previous value
+ }
+
+ recalculateCurrentInterval(/*force=*/true);
+}
+
+void QVariantAnimationPrivate::setDefaultStartEndValue(const QVariant &value)
+{
+ defaultStartEndValue = value;
+ recalculateCurrentInterval(/*force=*/true);
+}
+
+/*!
+ Construct a QVariantAnimation object. \a parent is passed to QAbstractAnimation's
+ constructor.
+*/
+QVariantAnimation::QVariantAnimation(QObject *parent) : QAbstractAnimation(*new QVariantAnimationPrivate, parent)
+{
+}
+
+/*!
+ \internal
+*/
+QVariantAnimation::QVariantAnimation(QVariantAnimationPrivate &dd, QObject *parent) : QAbstractAnimation(dd, parent)
+{
+}
+
+/*!
+ Destroys the animation.
+*/
+QVariantAnimation::~QVariantAnimation()
+{
+}
+
+/*!
+ \property QVariantAnimation::easingCurve
+ \brief the easing curve of the animation
+
+ This property defines the easing curve of the animation. By
+ default, a linear easing curve is used, resulting in linear
+ interpolation. Other curves are provided, for instance,
+ QEasingCurve::InCirc, which provides a circular entry curve.
+ Another example is QEasingCurve::InOutElastic, which provides an
+ elastic effect on the values of the interpolated variant.
+
+ QVariantAnimation will use the QEasingCurve::valueForProgress() to
+ transform the "normalized progress" (currentTime / totalDuration)
+ of the animation into the effective progress actually
+ used by the animation. It is this effective progress that will be
+ the progress when interpolated() is called. Also, the steps in the
+ keyValues are referring to this effective progress.
+
+ The easing curve is used with the interpolator, the interpolated()
+ virtual function, the animation's duration, and iterationCount, to
+ control how the current value changes as the animation progresses.
+*/
+QEasingCurve QVariantAnimation::easingCurve() const
+{
+ Q_D(const QVariantAnimation);
+ return d->easing;
+}
+
+void QVariantAnimation::setEasingCurve(const QEasingCurve &easing)
+{
+ Q_D(QVariantAnimation);
+ d->easing = easing;
+ d->recalculateCurrentInterval();
+}
+
+typedef QVector<QVariantAnimation::Interpolator> QInterpolatorVector;
+Q_GLOBAL_STATIC(QInterpolatorVector, registeredInterpolators)
+
+/*!
+ \fn void qRegisterAnimationInterpolator(QVariant (*func)(const T &from, const T &to, qreal progress))
+ \relates QVariantAnimation
+ \threadsafe
+
+ Registers a custom interpolator \a func for the template type \c{T}.
+ The interpolator has to be registered before the animation is constructed.
+ To unregister (and use the default interpolator) set \a func to 0.
+ */
+
+/*!
+ \internal
+ \typedef QVariantAnimation::Interpolator
+
+ This is a typedef for a pointer to a function with the following
+ signature:
+ \code
+ QVariant myInterpolator(const QVariant &from, const QVariant &to, qreal progress);
+ \endcode
+
+*/
+
+/*! \internal
+ * Registers a custom interpolator \a func for the specific \a interpolationType.
+ * The interpolator has to be registered before the animation is constructed.
+ * To unregister (and use the default interpolator) set \a func to 0.
+ */
+void QVariantAnimation::registerInterpolator(QVariantAnimation::Interpolator func, int interpolationType)
+{
+ // will override any existing interpolators
+ QInterpolatorVector *interpolators = registeredInterpolators();
+ // When built on solaris with GCC, the destructors can be called
+ // in such an order that we get here with interpolators == NULL,
+ // to continue causes the app to crash on exit with a SEGV
+ if (interpolators) {
+#ifndef QT_NO_THREAD
+ QMutexLocker locker(QMutexPool::globalInstanceGet(interpolators));
+#endif
+ if (int(interpolationType) >= interpolators->count())
+ interpolators->resize(int(interpolationType) + 1);
+ interpolators->replace(interpolationType, func);
+ }
+}
+
+
+template<typename T> static inline QVariantAnimation::Interpolator castToInterpolator(QVariant (*func)(const T &from, const T &to, qreal progress))
+{
+ return reinterpret_cast<QVariantAnimation::Interpolator>(func);
+}
+
+QVariantAnimation::Interpolator QVariantAnimationPrivate::getInterpolator(int interpolationType)
+{
+ QInterpolatorVector *interpolators = registeredInterpolators();
+#ifndef QT_NO_THREAD
+ QMutexLocker locker(QMutexPool::globalInstanceGet(interpolators));
+#endif
+ QVariantAnimation::Interpolator ret = 0;
+ if (interpolationType < interpolators->count()) {
+ ret = interpolators->at(interpolationType);
+ if (ret) return ret;
+ }
+
+ switch(interpolationType)
+ {
+ case QMetaType::Int:
+ return castToInterpolator(_q_interpolateVariant<int>);
+ case QMetaType::Double:
+ return castToInterpolator(_q_interpolateVariant<double>);
+ case QMetaType::Float:
+ return castToInterpolator(_q_interpolateVariant<float>);
+ case QMetaType::QLine:
+ return castToInterpolator(_q_interpolateVariant<QLine>);
+ case QMetaType::QLineF:
+ return castToInterpolator(_q_interpolateVariant<QLineF>);
+ case QMetaType::QPoint:
+ return castToInterpolator(_q_interpolateVariant<QPoint>);
+ case QMetaType::QPointF:
+ return castToInterpolator(_q_interpolateVariant<QPointF>);
+ case QMetaType::QSize:
+ return castToInterpolator(_q_interpolateVariant<QSize>);
+ case QMetaType::QSizeF:
+ return castToInterpolator(_q_interpolateVariant<QSizeF>);
+ case QMetaType::QRect:
+ return castToInterpolator(_q_interpolateVariant<QRect>);
+ case QMetaType::QRectF:
+ return castToInterpolator(_q_interpolateVariant<QRectF>);
+ default:
+ return 0; //this type is not handled
+ }
+}
+
+/*!
+ \property QVariantAnimation::duration
+ \brief the duration of the animation
+
+ This property describes the duration in milliseconds of the
+ animation. The default duration is 250 milliseconds.
+
+ \sa QAbstractAnimation::duration()
+ */
+int QVariantAnimation::duration() const
+{
+ Q_D(const QVariantAnimation);
+ return d->duration;
+}
+
+void QVariantAnimation::setDuration(int msecs)
+{
+ Q_D(QVariantAnimation);
+ if (msecs < 0) {
+ qWarning("QVariantAnimation::setDuration: cannot set a negative duration");
+ return;
+ }
+ if (d->duration == msecs)
+ return;
+ d->duration = msecs;
+ d->recalculateCurrentInterval();
+}
+
+/*!
+ \property QVariantAnimation::startValue
+ \brief the optional start value of the animation
+
+ This property describes the optional start value of the animation. If
+ omitted, or if a null QVariant is assigned as the start value, the
+ animation will use the current position of the end when the animation
+ is started.
+
+ \sa endValue
+*/
+QVariant QVariantAnimation::startValue() const
+{
+ return keyValueAt(0);
+}
+
+void QVariantAnimation::setStartValue(const QVariant &value)
+{
+ setKeyValueAt(0, value);
+}
+
+/*!
+ \property QVariantAnimation::endValue
+ \brief the end value of the animation
+
+ This property describes the end value of the animation.
+
+ \sa startValue
+ */
+QVariant QVariantAnimation::endValue() const
+{
+ return keyValueAt(1);
+}
+
+void QVariantAnimation::setEndValue(const QVariant &value)
+{
+ setKeyValueAt(1, value);
+}
+
+
+/*!
+ Returns the key frame value for the given \a step. The given \a step
+ must be in the range 0 to 1. If there is no KeyValue for \a step,
+ it returns an invalid QVariant.
+
+ \sa keyValues(), setKeyValueAt()
+*/
+QVariant QVariantAnimation::keyValueAt(qreal step) const
+{
+ return d_func()->valueAt(step);
+}
+
+/*!
+ \typedef QVariantAnimation::KeyValue
+
+ This is a typedef for QPair<qreal, QVariant>.
+*/
+/*!
+ \typedef QVariantAnimation::KeyValues
+
+ This is a typedef for QVector<KeyValue>
+*/
+
+/*!
+ Creates a key frame at the given \a step with the given \a value.
+ The given \a step must be in the range 0 to 1.
+
+ \sa setKeyValues(), keyValueAt()
+*/
+void QVariantAnimation::setKeyValueAt(qreal step, const QVariant &value)
+{
+ d_func()->setValueAt(step, value);
+}
+
+/*!
+ Returns the key frames of this animation.
+
+ \sa keyValueAt(), setKeyValues()
+*/
+QVariantAnimation::KeyValues QVariantAnimation::keyValues() const
+{
+ return d_func()->keyValues;
+}
+
+/*!
+ Replaces the current set of key frames with the given \a keyValues.
+ the step of the key frames must be in the range 0 to 1.
+
+ \sa keyValues(), keyValueAt()
+*/
+void QVariantAnimation::setKeyValues(const KeyValues &keyValues)
+{
+ Q_D(QVariantAnimation);
+ d->keyValues = keyValues;
+ qSort(d->keyValues.begin(), d->keyValues.end(), animationValueLessThan);
+ d->recalculateCurrentInterval(/*force=*/true);
+}
+
+/*!
+ \property QVariantAnimation::currentValue
+ \brief the current value of the animation.
+
+ This property describes the current value; an interpolated value
+ between the \l{startValue}{start value} and the \l{endValue}{end
+ value}, using the current time for progress. The value itself is
+ obtained from interpolated(), which is called repeatedly as the
+ animation is running.
+
+ QVariantAnimation calls the virtual updateCurrentValue() function
+ when the current value changes. This is particularly useful for
+ subclasses that need to track updates. For example,
+ QPropertyAnimation uses this function to animate Qt \l{Qt's
+ Property System}{properties}.
+
+ \sa startValue, endValue
+*/
+QVariant QVariantAnimation::currentValue() const
+{
+ Q_D(const QVariantAnimation);
+ if (!d->currentValue.isValid())
+ const_cast<QVariantAnimationPrivate*>(d)->recalculateCurrentInterval();
+ return d->currentValue;
+}
+
+/*!
+ \reimp
+ */
+bool QVariantAnimation::event(QEvent *event)
+{
+ return QAbstractAnimation::event(event);
+}
+
+/*!
+ \reimp
+*/
+void QVariantAnimation::updateState(QAbstractAnimation::State newState,
+ QAbstractAnimation::State oldState)
+{
+ Q_UNUSED(oldState);
+ Q_UNUSED(newState);
+}
+
+/*!
+
+ This virtual function returns the linear interpolation between
+ variants \a from and \a to, at \a progress, usually a value
+ between 0 and 1. You can reimplement this function in a subclass
+ of QVariantAnimation to provide your own interpolation algorithm.
+
+ Note that in order for the interpolation to work with a
+ QEasingCurve that return a value smaller than 0 or larger than 1
+ (such as QEasingCurve::InBack) you should make sure that it can
+ extrapolate. If the semantic of the datatype does not allow
+ extrapolation this function should handle that gracefully.
+
+ You should call the QVariantAnimation implementation of this
+ function if you want your class to handle the types already
+ supported by Qt (see class QVariantAnimation description for a
+ list of supported types).
+
+ \sa QEasingCurve
+ */
+QVariant QVariantAnimation::interpolated(const QVariant &from, const QVariant &to, qreal progress) const
+{
+ return d_func()->interpolator(from.constData(), to.constData(), progress);
+}
+
+/*!
+ \reimp
+ */
+void QVariantAnimation::updateCurrentTime(int)
+{
+ d_func()->recalculateCurrentInterval();
+}
+
+QT_END_NAMESPACE
+
+#include "moc_qvariantanimation.cpp"
+
+#endif //QT_NO_ANIMATION
diff --git a/src/corelib/animation/qvariantanimation.h b/src/corelib/animation/qvariantanimation.h
new file mode 100644
index 0000000000..d6badf513a
--- /dev/null
+++ b/src/corelib/animation/qvariantanimation.h
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANIMATION_H
+#define QANIMATION_H
+
+#include <QtCore/qeasingcurve.h>
+#include <QtCore/qabstractanimation.h>
+#include <QtCore/qvector.h>
+#include <QtCore/qvariant.h>
+#include <QtCore/qpair.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+#ifndef QT_NO_ANIMATION
+
+class QVariantAnimationPrivate;
+class Q_CORE_EXPORT QVariantAnimation : public QAbstractAnimation
+{
+ Q_OBJECT
+ Q_PROPERTY(QVariant startValue READ startValue WRITE setStartValue)
+ Q_PROPERTY(QVariant endValue READ endValue WRITE setEndValue)
+ Q_PROPERTY(QVariant currentValue READ currentValue NOTIFY valueChanged)
+ Q_PROPERTY(int duration READ duration WRITE setDuration)
+ Q_PROPERTY(QEasingCurve easingCurve READ easingCurve WRITE setEasingCurve)
+
+public:
+ typedef QPair<qreal, QVariant> KeyValue;
+ typedef QVector<KeyValue> KeyValues;
+
+ QVariantAnimation(QObject *parent = 0);
+ ~QVariantAnimation();
+
+ QVariant startValue() const;
+ void setStartValue(const QVariant &value);
+
+ QVariant endValue() const;
+ void setEndValue(const QVariant &value);
+
+ QVariant keyValueAt(qreal step) const;
+ void setKeyValueAt(qreal step, const QVariant &value);
+
+ KeyValues keyValues() const;
+ void setKeyValues(const KeyValues &values);
+
+ QVariant currentValue() const;
+
+ int duration() const;
+ void setDuration(int msecs);
+
+ QEasingCurve easingCurve() const;
+ void setEasingCurve(const QEasingCurve &easing);
+
+ typedef QVariant (*Interpolator)(const void *from, const void *to, qreal progress);
+
+Q_SIGNALS:
+ void valueChanged(const QVariant &value);
+
+protected:
+ QVariantAnimation(QVariantAnimationPrivate &dd, QObject *parent = 0);
+ bool event(QEvent *event);
+
+ void updateCurrentTime(int);
+ void updateState(QAbstractAnimation::State newState, QAbstractAnimation::State oldState);
+
+ virtual void updateCurrentValue(const QVariant &value) = 0;
+ virtual QVariant interpolated(const QVariant &from, const QVariant &to, qreal progress) const;
+
+private:
+ template <typename T> friend void qRegisterAnimationInterpolator(QVariant (*func)(const T &, const T &, qreal));
+ static void registerInterpolator(Interpolator func, int interpolationType);
+
+ Q_DISABLE_COPY(QVariantAnimation)
+ Q_DECLARE_PRIVATE(QVariantAnimation)
+};
+
+template <typename T>
+void qRegisterAnimationInterpolator(QVariant (*func)(const T &from, const T &to, qreal progress)) {
+ QVariantAnimation::registerInterpolator(reinterpret_cast<QVariantAnimation::Interpolator>(func), qMetaTypeId<T>());
+}
+
+#endif //QT_NO_ANIMATION
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif //QANIMATION_H
diff --git a/src/corelib/animation/qvariantanimation_p.h b/src/corelib/animation/qvariantanimation_p.h
new file mode 100644
index 0000000000..2a8d9d4f07
--- /dev/null
+++ b/src/corelib/animation/qvariantanimation_p.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QANIMATION_P_H
+#define QANIMATION_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of QIODevice. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "qvariantanimation.h"
+#include <QtCore/qeasingcurve.h>
+#include <QtCore/qmetaobject.h>
+#include <QtCore/qvector.h>
+
+#include "private/qabstractanimation_p.h"
+
+#ifndef QT_NO_ANIMATION
+
+QT_BEGIN_NAMESPACE
+
+class QVariantAnimationPrivate : public QAbstractAnimationPrivate
+{
+ Q_DECLARE_PUBLIC(QVariantAnimation)
+public:
+
+ QVariantAnimationPrivate();
+
+ static QVariantAnimationPrivate *get(QVariantAnimation *q)
+ {
+ return q->d_func();
+ }
+
+ void setDefaultStartEndValue(const QVariant &value);
+
+
+ QVariant currentValue;
+ QVariant defaultStartEndValue;
+
+ //this is used to keep track of the KeyValue interval in which we currently are
+ struct
+ {
+ QVariantAnimation::KeyValue start, end;
+ } currentInterval;
+
+ QEasingCurve easing;
+ int duration;
+ QVariantAnimation::KeyValues keyValues;
+ QVariantAnimation::Interpolator interpolator;
+
+ void setCurrentValueForProgress(const qreal progress);
+ void recalculateCurrentInterval(bool force=false);
+ void setValueAt(qreal, const QVariant &);
+ QVariant valueAt(qreal step) const;
+ void convertValues(int t);
+
+ void updateInterpolator();
+
+ //XXX this is needed by dui
+ static Q_CORE_EXPORT QVariantAnimation::Interpolator getInterpolator(int interpolationType);
+};
+
+//this should make the interpolation faster
+template<typename T> inline T _q_interpolate(const T &f, const T &t, qreal progress)
+{
+ return T(f + (t - f) * progress);
+}
+
+template<typename T > inline QVariant _q_interpolateVariant(const T &from, const T &to, qreal progress)
+{
+ return _q_interpolate(from, to, progress);
+}
+
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_ANIMATION
+
+#endif //QANIMATION_P_H
diff --git a/src/corelib/arch/alpha/arch.pri b/src/corelib/arch/alpha/arch.pri
new file mode 100644
index 0000000000..448a531f07
--- /dev/null
+++ b/src/corelib/arch/alpha/arch.pri
@@ -0,0 +1,4 @@
+#
+# Alpha architecture
+#
+!*-g++*:SOURCES += $$QT_ARCH_CPP/qatomic_alpha.s
diff --git a/src/corelib/arch/alpha/qatomic_alpha.s b/src/corelib/arch/alpha/qatomic_alpha.s
new file mode 100644
index 0000000000..d225de794b
--- /dev/null
+++ b/src/corelib/arch/alpha/qatomic_alpha.s
@@ -0,0 +1,239 @@
+;/****************************************************************************
+;**
+;** Copyright (C) 2011 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$
+;** No Commercial Usage
+;** This file contains pre-release code and may not be distributed.
+;** You may use this file in accordance with the terms and conditions
+;** contained in the Technology Preview License Agreement accompanying
+;** this package.
+;**
+;** GNU Lesser General Public License Usage
+;** Alternatively, this file may be used under the terms of the GNU Lesser
+;** General Public License version 2.1 as published by the Free Software
+;** Foundation and appearing in the file LICENSE.LGPL included in the
+;** packaging of this file. Please review the following information to
+;** ensure the GNU Lesser General Public License version 2.1 requirements
+;** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+;**
+;** In addition, as a special exception, Nokia gives you certain additional
+;** rights. These rights are described in the Nokia Qt LGPL Exception
+;** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+;**
+;** If you have questions regarding the use of this file, please contact
+;** Nokia at qt-info@nokia.com.
+;**
+;**
+;**
+;**
+;**
+;**
+;**
+;**
+;** $QT_END_LICENSE$
+;**
+;****************************************************************************/
+ .set noreorder
+ .set volatile
+ .set noat
+ .arch ev4
+ .text
+ .align 2
+ .align 4
+ .globl q_atomic_test_and_set_int
+ .ent q_atomic_test_and_set_int
+q_atomic_test_and_set_int:
+ .frame $30,0,$26,0
+ .prologue 0
+1: ldl_l $0,0($16)
+ cmpeq $0,$17,$0
+ beq $0,3f
+ mov $18,$0
+ stl_c $0,0($16)
+ beq $0,2f
+ br 3f
+2: br 1b
+3: addl $31,$0,$0
+ ret $31,($26),1
+ .end q_atomic_test_and_set_int
+ .align 2
+ .align 4
+ .globl q_atomic_test_and_set_acquire_int
+ .ent q_atomic_test_and_set_acquire_int
+q_atomic_test_and_set_acquire_int:
+ .frame $30,0,$26,0
+ .prologue 0
+1: ldl_l $0,0($16)
+ cmpeq $0,$17,$0
+ beq $0,3f
+ mov $18,$0
+ stl_c $0,0($16)
+ beq $0,2f
+ br 3f
+2: br 1b
+3: mb
+ addl $31,$0,$0
+ ret $31,($26),1
+ .end q_atomic_test_and_set_acquire_int
+ .align 2
+ .align 4
+ .globl q_atomic_test_and_set_release_int
+ .ent q_atomic_test_and_set_release_int
+q_atomic_test_and_set_release_int:
+ .frame $30,0,$26,0
+ .prologue 0
+ mb
+1: ldl_l $0,0($16)
+ cmpeq $0,$17,$0
+ beq $0,3f
+ mov $18,$0
+ stl_c $0,0($16)
+ beq $0,2f
+ br 3f
+2: br 1b
+3: addl $31,$0,$0
+ ret $31,($26),1
+ .end q_atomic_test_and_set_release_int
+ .align 2
+ .align 4
+ .globl q_atomic_test_and_set_ptr
+ .ent q_atomic_test_and_set_ptr
+q_atomic_test_and_set_ptr:
+ .frame $30,0,$26,0
+ .prologue 0
+1: ldq_l $0,0($16)
+ cmpeq $0,$17,$0
+ beq $0,3f
+ mov $18,$0
+ stq_c $0,0($16)
+ beq $0,2f
+ br 3f
+2: br 1b
+3: addl $31,$0,$0
+ ret $31,($26),1
+ .end q_atomic_test_and_set_ptr
+ .align 2
+ .align 4
+ .globl q_atomic_increment
+ .ent q_atomic_increment
+q_atomic_increment:
+ .frame $30,0,$26,0
+ .prologue 0
+1: ldl_l $0,0($16)
+ addl $0,1,$1
+ stl_c $1,0($16)
+ beq $1,2f
+ br 3f
+2: br 1b
+3: addl $31,$0,$0
+ cmpeq $0,$1,$0
+ xor $0,1,$0
+ ret $31,($26),1
+ .end q_atomic_increment
+ .align 2
+ .align 4
+ .globl q_atomic_decrement
+ .ent q_atomic_decrement
+q_atomic_decrement:
+ .frame $30,0,$26,0
+ .prologue 0
+1: ldl_l $0,0($16)
+ subl $0,1,$1
+ stl_c $1,0($16)
+ beq $1,2f
+ br 3f
+2: br 1b
+3: addl $31,$0,$0
+ cmpeq $0,1,$0
+ xor $0,1,$0
+ ret $31,($26),1
+ .end q_atomic_decrement
+ .align 2
+ .align 4
+ .globl q_atomic_set_int
+ .ent q_atomic_set_int
+q_atomic_set_int:
+ .frame $30,0,$26,0
+ .prologue 0
+1: ldl_l $0,0($16)
+ mov $17,$1
+ stl_c $1,0($16)
+ beq $1,2f
+ br 3f
+2: br 1b
+3: addl $31,$0,$0
+ ret $31,($26),1
+ .end q_atomic_set_int
+ .align 2
+ .align 4
+ .globl q_atomic_set_ptr
+ .ent q_atomic_set_ptr
+q_atomic_set_ptr:
+ .frame $30,0,$26,0
+ .prologue 0
+1: ldq_l $0,0($16)
+ mov $17,$1
+ stq_c $1,0($16)
+ beq $1,2f
+ br 3f
+2: br 1b
+3: ret $31,($26),1
+ .end q_atomic_set_ptr
+
+ .align 2
+ .align 4
+ .globl q_atomic_fetch_and_add_int
+ .ent q_atomic_fetch_and_add_int
+q_atomic_fetch_and_add_int:
+ .frame $30,0,$26,0
+ .prologue 0
+1: ldl_l $0,0($16)
+ addl $0,$17,$1
+ stl_c $1,0($16)
+ beq $1,2f
+ br 3f
+2: br 1b
+3: addl $31,$0,$0
+ ret $31,($26),1
+ .end q_atomic_fetch_and_add_int
+
+ .align 2
+ .align 4
+ .globl q_atomic_fetch_and_add_acquire_int
+ .ent q_atomic_fetch_and_add_acquire_int
+q_atomic_fetch_and_add_acquire_int:
+ .frame $30,0,$26,0
+ .prologue 0
+1: ldl_l $0,0($16)
+ addl $0,$17,$1
+ stl_c $1,0($16)
+ beq $1,2f
+ br 3f
+2: br 1b
+3: mb
+ addl $31,$0,$0
+ ret $31,($26),1
+ .end q_atomic_fetch_and_add_acquire_int
+
+ .align 2
+ .align 4
+ .globl q_atomic_fetch_and_add_release_int
+ .ent q_atomic_fetch_and_add_release_int
+q_atomic_fetch_and_add_release_int:
+ .frame $30,0,$26,0
+ .prologue 0
+ mb
+1: ldl_l $0,0($16)
+ addl $0,$17,$1
+ stl_c $1,0($16)
+ beq $1,2f
+ br 3f
+2: br 1b
+3: addl $31,$0,$0
+ ret $31,($26),1
+ .end q_atomic_fetch_and_add_release_int
diff --git a/src/corelib/arch/arch.pri b/src/corelib/arch/arch.pri
new file mode 100644
index 0000000000..cd23e5e855
--- /dev/null
+++ b/src/corelib/arch/arch.pri
@@ -0,0 +1,38 @@
+win32:HEADERS += arch/qatomic_windows.h \
+ arch/qatomic_generic.h
+
+win32-g++*:HEADERS += arch/qatomic_i386.h \
+ arch/qatomic_x86_64.h
+
+mac:HEADERS += arch/qatomic_macosx.h \
+ arch/qatomic_generic.h
+
+symbian:HEADERS += arch/qatomic_symbian.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 \
+ arch/qatomic_ia64.h \
+ arch/qatomic_parisc.h \
+ arch/qatomic_sparc.h \
+ arch/qatomic_arch.h \
+ arch/qatomic_generic.h \
+ arch/qatomic_powerpc.h \
+ arch/qatomic_arm.h \
+ arch/qatomic_armv5.h \
+ arch/qatomic_armv6.h \
+ arch/qatomic_armv7.h \
+ arch/qatomic_i386.h \
+ arch/qatomic_mips.h \
+ arch/qatomic_s390.h \
+ arch/qatomic_x86_64.h \
+ arch/qatomic_sh.h \
+ arch/qatomic_sh4a.h
+
+QT_ARCH_CPP = $$QT_SOURCE_TREE/src/corelib/arch/$$QT_ARCH
+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
new file mode 100644
index 0000000000..79e4bfc115
--- /dev/null
+++ b/src/corelib/arch/arm/arch.pri
@@ -0,0 +1,4 @@
+#
+# 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
new file mode 100644
index 0000000000..8f06515247
--- /dev/null
+++ b/src/corelib/arch/arm/qatomic_arm.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <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
new file mode 100644
index 0000000000..37f231ee61
--- /dev/null
+++ b/src/corelib/arch/avr32/arch.pri
@@ -0,0 +1,3 @@
+#
+# AVR32 architecture
+#
diff --git a/src/corelib/arch/bfin/arch.pri b/src/corelib/arch/bfin/arch.pri
new file mode 100644
index 0000000000..fa198ae8bb
--- /dev/null
+++ b/src/corelib/arch/bfin/arch.pri
@@ -0,0 +1,3 @@
+#
+# Blackfin architecture
+#
diff --git a/src/corelib/arch/generic/arch.pri b/src/corelib/arch/generic/arch.pri
new file mode 100644
index 0000000000..8fee63fa5d
--- /dev/null
+++ b/src/corelib/arch/generic/arch.pri
@@ -0,0 +1,6 @@
+#
+# 'generic' architecture
+#
+
+unix:SOURCES += qatomic_generic_unix.cpp
+win32:SOURCES += qatomic_generic_windows.cpp
diff --git a/src/corelib/arch/generic/qatomic_generic_unix.cpp b/src/corelib/arch/generic/qatomic_generic_unix.cpp
new file mode 100644
index 0000000000..5ab4c6b943
--- /dev/null
+++ b/src/corelib/arch/generic/qatomic_generic_unix.cpp
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#if !defined(Q_OS_SYMBIAN) || (defined(Q_OS_SYMBIAN) && !defined(Q_CC_RVCT))
+
+#include "qplatformdefs.h"
+
+#include <QtCore/qatomic.h>
+
+QT_BEGIN_NAMESPACE
+static pthread_mutex_t qAtomicMutex = PTHREAD_MUTEX_INITIALIZER;
+
+Q_CORE_EXPORT
+bool QBasicAtomicInt_testAndSetOrdered(volatile int *_q_value, int expectedValue, int newValue)
+{
+ bool returnValue = false;
+ pthread_mutex_lock(&qAtomicMutex);
+ if (*_q_value == expectedValue) {
+ *_q_value = newValue;
+ returnValue = true;
+ }
+ pthread_mutex_unlock(&qAtomicMutex);
+ return returnValue;
+}
+
+Q_CORE_EXPORT
+int QBasicAtomicInt_fetchAndStoreOrdered(volatile int *_q_value, int newValue)
+{
+ int returnValue;
+ pthread_mutex_lock(&qAtomicMutex);
+ returnValue = *_q_value;
+ *_q_value = newValue;
+ pthread_mutex_unlock(&qAtomicMutex);
+ return returnValue;
+}
+
+Q_CORE_EXPORT
+int QBasicAtomicInt_fetchAndAddOrdered(volatile int *_q_value, int valueToAdd)
+{
+ int returnValue;
+ pthread_mutex_lock(&qAtomicMutex);
+ returnValue = *_q_value;
+ *_q_value += valueToAdd;
+ pthread_mutex_unlock(&qAtomicMutex);
+ return returnValue;
+}
+
+Q_CORE_EXPORT
+bool QBasicAtomicPointer_testAndSetOrdered(void * volatile *_q_value,
+ void *expectedValue,
+ void *newValue)
+{
+ bool returnValue = false;
+ pthread_mutex_lock(&qAtomicMutex);
+ if (*_q_value == expectedValue) {
+ *_q_value = newValue;
+ returnValue = true;
+ }
+ pthread_mutex_unlock(&qAtomicMutex);
+ return returnValue;
+}
+
+Q_CORE_EXPORT
+void *QBasicAtomicPointer_fetchAndStoreOrdered(void * volatile *_q_value, void *newValue)
+{
+ void *returnValue;
+ pthread_mutex_lock(&qAtomicMutex);
+ returnValue = *_q_value;
+ *_q_value = newValue;
+ pthread_mutex_unlock(&qAtomicMutex);
+ return returnValue;
+}
+
+Q_CORE_EXPORT
+void *QBasicAtomicPointer_fetchAndAddOrdered(void * volatile *_q_value, qptrdiff valueToAdd)
+{
+ void *returnValue;
+ pthread_mutex_lock(&qAtomicMutex);
+ returnValue = *_q_value;
+ *_q_value = reinterpret_cast<char *>(returnValue) + valueToAdd;
+ pthread_mutex_unlock(&qAtomicMutex);
+ 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
new file mode 100644
index 0000000000..c2496db45c
--- /dev/null
+++ b/src/corelib/arch/generic/qatomic_generic_windows.cpp
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplatformdefs.h"
+
+#include <QtCore/qatomic.h>
+
+
+class QCriticalSection
+{
+public:
+ QCriticalSection() { InitializeCriticalSection(&section); }
+ ~QCriticalSection() { DeleteCriticalSection(&section); }
+ void lock() { EnterCriticalSection(&section); }
+ void unlock() { LeaveCriticalSection(&section); }
+
+private:
+ CRITICAL_SECTION section;
+};
+
+static QCriticalSection qAtomicCriticalSection;
+
+Q_CORE_EXPORT
+bool QBasicAtomicInt_testAndSetOrdered(volatile int *_q_value, int expectedValue, int newValue)
+{
+ bool returnValue = false;
+ qAtomicCriticalSection.lock();
+ if (*_q_value == expectedValue) {
+ *_q_value = newValue;
+ returnValue = true;
+ }
+ qAtomicCriticalSection.unlock();
+ return returnValue;
+}
+
+Q_CORE_EXPORT
+int QBasicAtomicInt_fetchAndStoreOrdered(volatile int *_q_value, int newValue)
+{
+ int returnValue;
+ qAtomicCriticalSection.lock();
+ returnValue = *_q_value;
+ *_q_value = newValue;
+ qAtomicCriticalSection.unlock();
+ return returnValue;
+}
+
+Q_CORE_EXPORT
+int QBasicAtomicInt_fetchAndAddOrdered(volatile int *_q_value, int valueToAdd)
+{
+ int returnValue;
+ qAtomicCriticalSection.lock();
+ returnValue = *_q_value;
+ *_q_value += valueToAdd;
+ qAtomicCriticalSection.unlock();
+ return returnValue;
+}
+
+Q_CORE_EXPORT
+bool QBasicAtomicPointer_testAndSetOrdered(void * volatile *_q_value,
+ void *expectedValue,
+ void *newValue)
+{
+ bool returnValue = false;
+ qAtomicCriticalSection.lock();
+ if (*_q_value == expectedValue) {
+ *_q_value = newValue;
+ returnValue = true;
+ }
+ qAtomicCriticalSection.unlock();
+ return returnValue;
+}
+
+Q_CORE_EXPORT
+void *QBasicAtomicPointer_fetchAndStoreOrdered(void * volatile *_q_value, void *newValue)
+{
+ void *returnValue;
+ qAtomicCriticalSection.lock();
+ returnValue = *_q_value;
+ *_q_value = newValue;
+ qAtomicCriticalSection.unlock();
+ return returnValue;
+}
+
+Q_CORE_EXPORT
+void *QBasicAtomicPointer_fetchAndAddOrdered(void * volatile *_q_value, qptrdiff valueToAdd)
+{
+ void *returnValue;
+ qAtomicCriticalSection.lock();
+ returnValue = *_q_value;
+ *_q_value = reinterpret_cast<char *>(returnValue) + valueToAdd;
+ qAtomicCriticalSection.unlock();
+ return returnValue;
+}
diff --git a/src/corelib/arch/i386/arch.pri b/src/corelib/arch/i386/arch.pri
new file mode 100644
index 0000000000..3101dae01b
--- /dev/null
+++ b/src/corelib/arch/i386/arch.pri
@@ -0,0 +1,4 @@
+#
+# 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
new file mode 100644
index 0000000000..08158f926b
--- /dev/null
+++ b/src/corelib/arch/i386/qatomic_i386.s
@@ -0,0 +1,103 @@
+ .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
new file mode 100644
index 0000000000..63afa967a4
--- /dev/null
+++ b/src/corelib/arch/ia64/arch.pri
@@ -0,0 +1,4 @@
+#
+# 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
new file mode 100644
index 0000000000..c988cfcd10
--- /dev/null
+++ b/src/corelib/arch/ia64/qatomic_ia64.s
@@ -0,0 +1,74 @@
+;/****************************************************************************
+;**
+;** Copyright (C) 2011 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$
+;** No Commercial Usage
+;** This file contains pre-release code and may not be distributed.
+;** You may use this file in accordance with the terms and conditions
+;** contained in the Technology Preview License Agreement accompanying
+;** this package.
+;**
+;** GNU Lesser General Public License Usage
+;** Alternatively, this file may be used under the terms of the GNU Lesser
+;** General Public License version 2.1 as published by the Free Software
+;** Foundation and appearing in the file LICENSE.LGPL included in the
+;** packaging of this file. Please review the following information to
+;** ensure the GNU Lesser General Public License version 2.1 requirements
+;** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+;**
+;** In addition, as a special exception, Nokia gives you certain additional
+;** rights. These rights are described in the Nokia Qt LGPL Exception
+;** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+;**
+;** If you have questions regarding the use of this file, please contact
+;** Nokia at qt-info@nokia.com.
+;**
+;**
+;**
+;**
+;**
+;**
+;**
+;**
+;** $QT_END_LICENSE$
+;**
+;****************************************************************************/
+ .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
new file mode 100644
index 0000000000..2c4196ec32
--- /dev/null
+++ b/src/corelib/arch/integrity/arch.pri
@@ -0,0 +1,3 @@
+#
+# INTEGRITY RTOS architecture
+#
diff --git a/src/corelib/arch/macosx/arch.pri b/src/corelib/arch/macosx/arch.pri
new file mode 100644
index 0000000000..a2b1bf759a
--- /dev/null
+++ b/src/corelib/arch/macosx/arch.pri
@@ -0,0 +1,6 @@
+#
+# 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
new file mode 100644
index 0000000000..c9a318dccd
--- /dev/null
+++ b/src/corelib/arch/macosx/qatomic32_ppc.s
@@ -0,0 +1,169 @@
+;/****************************************************************************
+;**
+;** Copyright (C) 2011 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$
+;** No Commercial Usage
+;** This file contains pre-release code and may not be distributed.
+;** You may use this file in accordance with the terms and conditions
+;** contained in the Technology Preview License Agreement accompanying
+;** this package.
+;**
+;** GNU Lesser General Public License Usage
+;** Alternatively, this file may be used under the terms of the GNU Lesser
+;** General Public License version 2.1 as published by the Free Software
+;** Foundation and appearing in the file LICENSE.LGPL included in the
+;** packaging of this file. Please review the following information to
+;** ensure the GNU Lesser General Public License version 2.1 requirements
+;** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+;**
+;** In addition, as a special exception, Nokia gives you certain additional
+;** rights. These rights are described in the Nokia Qt LGPL Exception
+;** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+;**
+;** If you have questions regarding the use of this file, please contact
+;** Nokia at qt-info@nokia.com.
+;**
+;**
+;**
+;**
+;**
+;**
+;**
+;**
+;** $QT_END_LICENSE$
+;**
+;****************************************************************************/
+ .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
new file mode 100644
index 0000000000..296c845ab3
--- /dev/null
+++ b/src/corelib/arch/mips/arch.pri
@@ -0,0 +1,8 @@
+#
+# 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
new file mode 100644
index 0000000000..d4c0191cfa
--- /dev/null
+++ b/src/corelib/arch/mips/qatomic_mips32.s
@@ -0,0 +1,150 @@
+;/****************************************************************************
+;**
+;** Copyright (C) 2011 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$
+;** No Commercial Usage
+;** This file contains pre-release code and may not be distributed.
+;** You may use this file in accordance with the terms and conditions
+;** contained in the Technology Preview License Agreement accompanying
+;** this package.
+;**
+;** GNU Lesser General Public License Usage
+;** Alternatively, this file may be used under the terms of the GNU Lesser
+;** General Public License version 2.1 as published by the Free Software
+;** Foundation and appearing in the file LICENSE.LGPL included in the
+;** packaging of this file. Please review the following information to
+;** ensure the GNU Lesser General Public License version 2.1 requirements
+;** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+;**
+;** In addition, as a special exception, Nokia gives you certain additional
+;** rights. These rights are described in the Nokia Qt LGPL Exception
+;** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+;**
+;** If you have questions regarding the use of this file, please contact
+;** Nokia at qt-info@nokia.com.
+;**
+;**
+;**
+;**
+;**
+;**
+;**
+;**
+;** $QT_END_LICENSE$
+;**
+;****************************************************************************/
+ .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
new file mode 100644
index 0000000000..993991f0b7
--- /dev/null
+++ b/src/corelib/arch/mips/qatomic_mips64.s
@@ -0,0 +1,138 @@
+;/****************************************************************************
+;**
+;** Copyright (C) 2011 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$
+;** No Commercial Usage
+;** This file contains pre-release code and may not be distributed.
+;** You may use this file in accordance with the terms and conditions
+;** contained in the Technology Preview License Agreement accompanying
+;** this package.
+;**
+;** GNU Lesser General Public License Usage
+;** Alternatively, this file may be used under the terms of the GNU Lesser
+;** General Public License version 2.1 as published by the Free Software
+;** Foundation and appearing in the file LICENSE.LGPL included in the
+;** packaging of this file. Please review the following information to
+;** ensure the GNU Lesser General Public License version 2.1 requirements
+;** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+;**
+;** In addition, as a special exception, Nokia gives you certain additional
+;** rights. These rights are described in the Nokia Qt LGPL Exception
+;** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+;**
+;** If you have questions regarding the use of this file, please contact
+;** Nokia at qt-info@nokia.com.
+;**
+;**
+;**
+;**
+;**
+;**
+;**
+;**
+;** $QT_END_LICENSE$
+;**
+;****************************************************************************/
+ .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/arch.pri b/src/corelib/arch/parisc/arch.pri
new file mode 100644
index 0000000000..fab2897f04
--- /dev/null
+++ b/src/corelib/arch/parisc/arch.pri
@@ -0,0 +1,5 @@
+#
+# HP PA-RISC architecture
+#
+SOURCES += $$QT_ARCH_CPP/q_ldcw.s \
+ $$QT_ARCH_CPP/qatomic_parisc.cpp
diff --git a/src/corelib/arch/parisc/q_ldcw.s b/src/corelib/arch/parisc/q_ldcw.s
new file mode 100644
index 0000000000..f8f40467ec
--- /dev/null
+++ b/src/corelib/arch/parisc/q_ldcw.s
@@ -0,0 +1,62 @@
+;/****************************************************************************
+;**
+;** Copyright (C) 2011 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$
+;** No Commercial Usage
+;** This file contains pre-release code and may not be distributed.
+;** You may use this file in accordance with the terms and conditions
+;** contained in the Technology Preview License Agreement accompanying
+;** this package.
+;**
+;** GNU Lesser General Public License Usage
+;** Alternatively, this file may be used under the terms of the GNU Lesser
+;** General Public License version 2.1 as published by the Free Software
+;** Foundation and appearing in the file LICENSE.LGPL included in the
+;** packaging of this file. Please review the following information to
+;** ensure the GNU Lesser General Public License version 2.1 requirements
+;** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+;**
+;** In addition, as a special exception, Nokia gives you certain additional
+;** rights. These rights are described in the Nokia Qt LGPL Exception
+;** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+;**
+;** If you have questions regarding the use of this file, please contact
+;** Nokia at qt-info@nokia.com.
+;**
+;**
+;**
+;**
+;**
+;**
+;**
+;**
+;** $QT_END_LICENSE$
+;**
+;****************************************************************************/
+ .SPACE $PRIVATE$
+ .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
+ .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
+ .SPACE $TEXT$
+ .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
+ .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
+ .IMPORT $global$,DATA
+ .IMPORT $$dyncall,MILLICODE
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+
+ .align 4
+ .EXPORT q_ldcw,ENTRY,PRIV_LEV=3,ARGW0=GR,RTNVAL=GR
+q_ldcw
+ .PROC
+ .CALLINFO FRAME=0,CALLS,SAVE_RP
+ .ENTRY
+ ldcw 0(%r26),%r1
+ bv %r0(%r2)
+ copy %r1,%r28
+ .EXIT
+ .PROCEND
diff --git a/src/corelib/arch/parisc/qatomic_parisc.cpp b/src/corelib/arch/parisc/qatomic_parisc.cpp
new file mode 100644
index 0000000000..fa446c5d7b
--- /dev/null
+++ b/src/corelib/arch/parisc/qatomic_parisc.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qhash.h>
+
+QT_BEGIN_NAMESPACE
+
+QT_USE_NAMESPACE
+
+#define UNLOCKED {-1,-1,-1,-1}
+#define UNLOCKED2 UNLOCKED,UNLOCKED
+#define UNLOCKED4 UNLOCKED2,UNLOCKED2
+#define UNLOCKED8 UNLOCKED4,UNLOCKED4
+#define UNLOCKED16 UNLOCKED8,UNLOCKED8
+#define UNLOCKED32 UNLOCKED16,UNLOCKED16
+#define UNLOCKED64 UNLOCKED32,UNLOCKED32
+#define UNLOCKED128 UNLOCKED64,UNLOCKED64
+#define UNLOCKED256 UNLOCKED128,UNLOCKED128
+
+// use a 4k page for locks
+static int locks[256][4] = { UNLOCKED256 };
+
+int *getLock(volatile void *addr)
+{ return locks[qHash(const_cast<void *>(addr)) % 256]; }
+
+static int *align16(int *lock)
+{
+ ulong off = (((ulong) lock) % 16);
+ return off ? (int *)(ulong(lock) + 16 - off) : lock;
+}
+
+extern "C" {
+
+ int q_ldcw(volatile int *addr);
+
+ void q_atomic_lock(int *lock)
+ {
+ // ldcw requires a 16-byte aligned address
+ volatile int *x = align16(lock);
+ while (q_ldcw(x) == 0)
+ ;
+ }
+
+ void q_atomic_unlock(int *lock)
+ { lock[0] = lock[1] = lock[2] = lock[3] = -1; }
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/corelib/arch/powerpc/arch.pri b/src/corelib/arch/powerpc/arch.pri
new file mode 100644
index 0000000000..1989ac73a7
--- /dev/null
+++ b/src/corelib/arch/powerpc/arch.pri
@@ -0,0 +1,10 @@
+#
+# PowerPC architecture
+#
+!*-g++* {
+ *-64 {
+ SOURCES += $$QT_ARCH_CPP/qatomic64.s
+ } else {
+ SOURCES += $$QT_ARCH_CPP/qatomic32.s
+ }
+}
diff --git a/src/corelib/arch/powerpc/qatomic32.s b/src/corelib/arch/powerpc/qatomic32.s
new file mode 100644
index 0000000000..a446359e25
--- /dev/null
+++ b/src/corelib/arch/powerpc/qatomic32.s
@@ -0,0 +1,525 @@
+############################################################################
+##
+## Copyright (C) 2011 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$
+## No Commercial Usage
+## This file contains pre-release code and may not be distributed.
+## You may use this file in accordance with the terms and conditions
+## contained in the Technology Preview License Agreement accompanying
+## this package.
+##
+## GNU Lesser General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU Lesser
+## General Public License version 2.1 as published by the Free Software
+## Foundation and appearing in the file LICENSE.LGPL included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU Lesser General Public License version 2.1 requirements
+## will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+##
+## In addition, as a special exception, Nokia gives you certain additional
+## rights. These rights are described in the Nokia Qt LGPL Exception
+## version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+##
+## If you have questions regarding the use of this file, please contact
+## Nokia at qt-info@nokia.com.
+##
+##
+##
+##
+##
+##
+##
+##
+## $QT_END_LICENSE$
+##
+############################################################################
+ .machine "ppc"
+ .toc
+ .csect .text[PR]
+
+ .align 2
+ .globl q_atomic_test_and_set_int
+ .globl .q_atomic_test_and_set_int
+ .csect q_atomic_test_and_set_int[DS],3
+q_atomic_test_and_set_int:
+ .long .q_atomic_test_and_set_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_test_and_set_int:
+ lwarx 6,0,3
+ xor. 6,6,4
+ bne $+12
+ stwcx. 5,0,3
+ bne- $-16
+ subfic 3,6,0
+ adde 3,3,6
+ blr
+LT..q_atomic_test_and_set_int:
+ .long 0
+ .byte 0,9,32,64,0,0,3,0
+ .long 0
+ .long LT..q_atomic_test_and_set_int-.q_atomic_test_and_set_int
+ .short 25
+ .byte "q_atomic_test_and_set_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_test_and_set_acquire_int
+ .globl .q_atomic_test_and_set_acquire_int
+ .csect q_atomic_test_and_set_acquire_int[DS],3
+q_atomic_test_and_set_acquire_int:
+ .long .q_atomic_test_and_set_acquire_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_test_and_set_acquire_int:
+ lwarx 6,0,3
+ xor. 6,6,4
+ bne $+16
+ stwcx. 5,0,3
+ bne- $-16
+ isync
+ subfic 3,6,0
+ adde 3,3,6
+ blr
+LT..q_atomic_test_and_set_acquire_int:
+ .long 0
+ .byte 0,9,32,64,0,0,3,0
+ .long 0
+ .long LT..q_atomic_test_and_set_acquire_int-.q_atomic_test_and_set_acquire_int
+ .short 33
+ .byte "q_atomic_test_and_set_acquire_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_test_and_set_release_int
+ .globl .q_atomic_test_and_set_release_int
+ .csect q_atomic_test_and_set_release_int[DS],3
+q_atomic_test_and_set_release_int:
+ .long .q_atomic_test_and_set_release_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_test_and_set_release_int:
+ eieio
+ lwarx 6,0,3
+ xor. 6,6,4
+ bne $+12
+ stwcx. 5,0,3
+ bne- $-16
+ subfic 3,6,0
+ adde 3,3,6
+ blr
+LT..q_atomic_test_and_set_release_int:
+ .long 0
+ .byte 0,9,32,64,0,0,3,0
+ .long 0
+ .long LT..q_atomic_test_and_set_release_int-.q_atomic_test_and_set_release_int
+ .short 33
+ .byte "q_atomic_test_and_set_release_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_test_and_set_ptr
+ .globl .q_atomic_test_and_set_ptr
+ .csect q_atomic_test_and_set_ptr[DS],3
+q_atomic_test_and_set_ptr:
+ .long .q_atomic_test_and_set_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_test_and_set_ptr:
+ lwarx 6,0,3
+ xor. 6,6,4
+ bne $+12
+ stwcx. 5,0,3
+ bne- $-16
+ subfic 3,6,0
+ adde 3,3,6
+ blr
+LT..q_atomic_test_and_set_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,3,0
+ .long 0
+ .long LT..q_atomic_test_and_set_ptr-.q_atomic_test_and_set_ptr
+ .short 25
+ .byte "q_atomic_test_and_set_ptr"
+ .align 2
+
+ .align 2
+ .globl q_atomic_test_and_set_acquire_ptr
+ .globl .q_atomic_test_and_set_acquire_ptr
+ .csect q_atomic_test_and_set_acquire_ptr[DS],3
+q_atomic_test_and_set_acquire_ptr:
+ .long .q_atomic_test_and_set_acquire_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_test_and_set_acquire_ptr:
+ lwarx 6,0,3
+ xor. 6,6,4
+ bne $+16
+ stwcx. 5,0,3
+ bne- $-16
+ isync
+ subfic 3,6,0
+ adde 3,3,6
+ blr
+LT..q_atomic_test_and_set_acquire_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,3,0
+ .long 0
+ .long LT..q_atomic_test_and_set_acquire_ptr-.q_atomic_test_and_set_acquire_ptr
+ .short 25
+ .byte "q_atomic_test_and_set_acquire_ptr"
+ .align 2
+
+ .align 2
+ .globl q_atomic_test_and_set_release_ptr
+ .globl .q_atomic_test_and_set_release_ptr
+ .csect q_atomic_test_and_set_release_ptr[DS],3
+q_atomic_test_and_set_release_ptr:
+ .long .q_atomic_test_and_set_release_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_test_and_set_release_ptr:
+ eieio
+ lwarx 6,0,3
+ xor. 6,6,4
+ bne $+12
+ stwcx. 5,0,3
+ bne- $-16
+ subfic 3,6,0
+ adde 3,3,6
+ blr
+LT..q_atomic_test_and_set_release_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,3,0
+ .long 0
+ .long LT..q_atomic_test_and_set_release_ptr-.q_atomic_test_and_set_release_ptr
+ .short 33
+ .byte "q_atomic_test_and_set_release_ptr"
+ .align 2
+
+ .align 2
+ .globl q_atomic_increment
+ .globl .q_atomic_increment
+ .csect q_atomic_increment[DS],3
+q_atomic_increment:
+ .long .q_atomic_increment,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_increment:
+ lwarx 4,0,3
+ addi 4,4,1
+ stwcx. 4,0,3
+ bne- $-12
+ mr 3,4
+ blr
+LT..q_atomic_increment:
+ .long 0
+ .byte 0,9,32,64,0,0,1,0
+ .long 0
+ .long LT..q_atomic_increment-.q_atomic_increment
+ .short 18
+ .byte "q_atomic_increment"
+ .align 2
+
+ .align 2
+ .globl q_atomic_decrement
+ .globl .q_atomic_decrement
+ .csect q_atomic_decrement[DS],3
+q_atomic_decrement:
+ .long .q_atomic_decrement,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_decrement:
+ lwarx 4,0,3
+ subi 4,4,1
+ stwcx. 4,0,3
+ bne- $-12
+ mr 3,4
+ blr
+LT..q_atomic_decrement:
+ .long 0
+ .byte 0,9,32,64,0,0,1,0
+ .long 0
+ .long LT..q_atomic_decrement-.q_atomic_decrement
+ .short 18
+ .byte "q_atomic_decrement"
+ .align 2
+
+ .align 2
+ .globl q_atomic_set_int
+ .globl .q_atomic_set_int
+ .csect q_atomic_set_int[DS],3
+q_atomic_set_int:
+ .long .q_atomic_set_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_set_int:
+ lwarx 5,0,3
+ stwcx. 4,0,3
+ bne- $-8
+ mr 3,5
+ blr
+LT..q_atomic_set_int:
+ .long 0
+ .byte 0,9,32,64,0,0,2,0
+ .long 0
+ .long LT..q_atomic_set_int-.q_atomic_set_int
+ .short 16
+ .byte "q_atomic_set_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_store_acquire_int
+ .globl .q_atomic_fetch_and_store_acquire_int
+ .csect q_atomic_fetch_and_store_acquire_int[DS],3
+q_atomic_fetch_and_store_acquire_int:
+ .long .q_atomic_fetch_and_store_acquire_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_store_acquire_int:
+ lwarx 5,0,3
+ stwcx. 4,0,3
+ bne- $-8
+ isync
+ mr 3,5
+ blr
+LT..q_atomic_fetch_and_store_acquire_int:
+ .long 0
+ .byte 0,9,32,64,0,0,2,0
+ .long 0
+ .long LT..q_atomic_fetch_and_store_acquire_int-.q_atomic_fetch_and_store_acquire_int
+ .short 16
+ .byte "q_atomic_fetch_and_store_acquire_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_store_release_int
+ .globl .q_atomic_fetch_and_store_release_int
+ .csect q_atomic_fetch_and_store_release_int[DS],3
+q_atomic_fetch_and_store_release_int:
+ .long .q_atomic_fetch_and_store_release_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_store_release_int:
+ eieio
+ lwarx 5,0,3
+ stwcx. 4,0,3
+ bne- $-8
+ mr 3,5
+ blr
+LT..q_atomic_fetch_and_store_release_int:
+ .long 0
+ .byte 0,9,32,64,0,0,2,0
+ .long 0
+ .long LT..q_atomic_fetch_and_store_release_int-.q_atomic_fetch_and_store_release_int
+ .short 16
+ .byte "q_atomic_fetch_and_store_release_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_set_ptr
+ .globl .q_atomic_set_ptr
+ .csect q_atomic_set_ptr[DS],3
+q_atomic_set_ptr:
+ .long .q_atomic_set_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_set_ptr:
+ lwarx 5,0,3
+ stwcx. 4,0,3
+ bne- $-8
+ mr 3,5
+ blr
+LT..q_atomic_set_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,2,0
+ .long 0
+ .long LT..q_atomic_set_ptr-.q_atomic_set_ptr
+ .short 16
+ .byte "q_atomic_set_ptr"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_store_acquire_ptr
+ .globl .q_atomic_fetch_and_store_acquire_ptr
+ .csect q_atomic_fetch_and_store_acquire_ptr[DS],3
+q_atomic_fetch_and_store_acquire_ptr:
+ .long .q_atomic_fetch_and_store_acquire_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_store_acquire_ptr:
+ lwarx 5,0,3
+ stwcx. 4,0,3
+ bne- $-8
+ isync
+ mr 3,5
+ blr
+LT..q_atomic_fetch_and_store_acquire_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,2,0
+ .long 0
+ .long LT..q_atomic_fetch_and_store_acquire_ptr-.q_atomic_fetch_and_store_acquire_ptr
+ .short 16
+ .byte "q_atomic_fetch_and_store_acquire_ptr"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_store_release_ptr
+ .globl .q_atomic_fetch_and_store_release_ptr
+ .csect q_atomic_fetch_and_store_release_ptr[DS],3
+q_atomic_fetch_and_store_release_ptr:
+ .long .q_atomic_fetch_and_store_release_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_store_release_ptr:
+ eieio
+ lwarx 5,0,3
+ stwcx. 4,0,3
+ bne- $-8
+ mr 3,5
+ blr
+LT..q_atomic_fetch_and_store_release_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,2,0
+ .long 0
+ .long LT..q_atomic_fetch_and_store_release_ptr-.q_atomic_fetch_and_store_release_ptr
+ .short 16
+ .byte "q_atomic_fetch_and_store_release_ptr"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_add_int
+ .globl .q_atomic_fetch_and_add_int
+ .csect q_atomic_fetch_and_add_int[DS],3
+q_atomic_fetch_and_add_int:
+ .long .q_atomic_fetch_and_add_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_add_int:
+ lwarx 5,0,3
+ add 6,4,5
+ stwcx. 6,0,3
+ bne- $-12
+ mr 3,5
+ blr
+LT..q_atomic_fetch_and_add_int:
+ .long 0
+ .byte 0,9,32,64,0,0,1,0
+ .long 0
+ .long LT..q_atomic_fetch_and_add_int-.q_atomic_fetch_and_add_int
+ .short 18
+ .byte "q_atomic_fetch_and_add_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_add_acquire_int
+ .globl .q_atomic_fetch_and_add_acquire_int
+ .csect q_atomic_fetch_and_add_acquire_int[DS],3
+q_atomic_fetch_and_add_acquire_int:
+ .long .q_atomic_fetch_and_add_acquire_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_add_acquire_int:
+ lwarx 5,0,3
+ add 6,4,5
+ stwcx. 6,0,3
+ bne- $-12
+ isync
+ mr 3,5
+ blr
+LT..q_atomic_fetch_and_add_acquire_int:
+ .long 0
+ .byte 0,9,32,64,0,0,1,0
+ .long 0
+ .long LT..q_atomic_fetch_and_add_acquire_int-.q_atomic_fetch_and_add_acquire_int
+ .short 18
+ .byte "q_atomic_fetch_and_add_acquire_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_add_release_int
+ .globl .q_atomic_fetch_and_add_release_int
+ .csect q_atomic_fetch_and_add_release_int[DS],3
+q_atomic_fetch_and_add_release_int:
+ .long .q_atomic_fetch_and_add_release_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_add_release_int:
+ eieio
+ lwarx 5,0,3
+ add 6,4,5
+ stwcx. 6,0,3
+ bne- $-12
+ mr 3,5
+ blr
+LT..q_atomic_fetch_and_add_release_int:
+ .long 0
+ .byte 0,9,32,64,0,0,1,0
+ .long 0
+ .long LT..q_atomic_fetch_and_add_release_int-.q_atomic_fetch_and_add_release_int
+ .short 34
+ .byte "q_atomic_fetch_and_add_release_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_add_ptr
+ .globl .q_atomic_fetch_and_add_ptr
+ .csect q_atomic_fetch_and_add_ptr[DS],3
+q_atomic_fetch_and_add_ptr:
+ .long .q_atomic_fetch_and_add_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_add_ptr:
+ lwarx 5,0,3
+ add 6,4,5
+ stwcx. 6,0,3
+ bne- $-12
+ mr 3,5
+ blr
+LT..q_atomic_fetch_and_add_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,1,0
+ .long 0
+ .long LT..q_atomic_fetch_and_add_ptr-.q_atomic_fetch_and_add_ptr
+ .short 26
+ .byte "q_atomic_fetch_and_add_ptr"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_add_acquire_ptr
+ .globl .q_atomic_fetch_and_add_acquire_ptr
+ .csect q_atomic_fetch_and_add_acquire_ptr[DS],3
+q_atomic_fetch_and_add_acquire_ptr:
+ .long .q_atomic_fetch_and_add_acquire_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_add_acquire_ptr:
+ lwarx 5,0,3
+ add 6,4,5
+ stwcx. 6,0,3
+ bne- $-12
+ isync
+ mr 3,5
+ blr
+LT..q_atomic_fetch_and_add_acquire_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,1,0
+ .long 0
+ .long LT..q_atomic_fetch_and_add_acquire_ptr-.q_atomic_fetch_and_add_acquire_ptr
+ .short 34
+ .byte "q_atomic_fetch_and_add_acquire_ptr"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_add_release_ptr
+ .globl .q_atomic_fetch_and_add_release_ptr
+ .csect q_atomic_fetch_and_add_release_ptr[DS],3
+q_atomic_fetch_and_add_release_ptr:
+ .long .q_atomic_fetch_and_add_release_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_add_release_ptr:
+ eieio
+ lwarx 5,0,3
+ add 6,4,5
+ stwcx. 6,0,3
+ bne- $-12
+ mr 3,5
+ blr
+LT..q_atomic_fetch_and_add_release_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,1,0
+ .long 0
+ .long LT..q_atomic_fetch_and_add_release_ptr-.q_atomic_fetch_and_add_release_ptr
+ .short 34
+ .byte "q_atomic_fetch_and_add_release_ptr"
+ .align 2
+
+_section_.text:
+ .csect .data[RW],3
+ .long _section_.text
diff --git a/src/corelib/arch/powerpc/qatomic64.s b/src/corelib/arch/powerpc/qatomic64.s
new file mode 100644
index 0000000000..9bf31912a1
--- /dev/null
+++ b/src/corelib/arch/powerpc/qatomic64.s
@@ -0,0 +1,533 @@
+############################################################################
+##
+## Copyright (C) 2011 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$
+## No Commercial Usage
+## This file contains pre-release code and may not be distributed.
+## You may use this file in accordance with the terms and conditions
+## contained in the Technology Preview License Agreement accompanying
+## this package.
+##
+## GNU Lesser General Public License Usage
+## Alternatively, this file may be used under the terms of the GNU Lesser
+## General Public License version 2.1 as published by the Free Software
+## Foundation and appearing in the file LICENSE.LGPL included in the
+## packaging of this file. Please review the following information to
+## ensure the GNU Lesser General Public License version 2.1 requirements
+## will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+##
+## In addition, as a special exception, Nokia gives you certain additional
+## rights. These rights are described in the Nokia Qt LGPL Exception
+## version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+##
+## If you have questions regarding the use of this file, please contact
+## Nokia at qt-info@nokia.com.
+##
+##
+##
+##
+##
+##
+##
+##
+## $QT_END_LICENSE$
+##
+############################################################################
+ .machine "ppc64"
+ .toc
+ .csect .text[PR]
+
+ .align 2
+ .globl q_atomic_test_and_set_int
+ .globl .q_atomic_test_and_set_int
+ .csect q_atomic_test_and_set_int[DS],3
+q_atomic_test_and_set_int:
+ .llong .q_atomic_test_and_set_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_test_and_set_int:
+ lwarx 6,0,3
+ xor. 6,6,4
+ bne $+12
+ stwcx. 5,0,3
+ bne- $-16
+ subfic 3,6,0
+ adde 3,3,6
+ extsw 3,3
+ blr
+LT..q_atomic_test_and_set_int:
+ .long 0
+ .byte 0,9,32,64,0,0,3,0
+ .long 0
+ .long LT..q_atomic_test_and_set_int-.q_atomic_test_and_set_int
+ .short 25
+ .byte "q_atomic_test_and_set_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_test_and_set_acquire_int
+ .globl .q_atomic_test_and_set_acquire_int
+ .csect q_atomic_test_and_set_acquire_int[DS],3
+q_atomic_test_and_set_acquire_int:
+ .llong .q_atomic_test_and_set_acquire_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_test_and_set_acquire_int:
+ lwarx 6,0,3
+ xor. 6,6,4
+ bne $+16
+ stwcx. 5,0,3
+ bne- $-16
+ isync
+ subfic 3,6,0
+ adde 3,3,6
+ extsw 3,3
+ blr
+LT..q_atomic_test_and_set_acquire_int:
+ .long 0
+ .byte 0,9,32,64,0,0,3,0
+ .long 0
+ .long LT..q_atomic_test_and_set_acquire_int-.q_atomic_test_and_set_acquire_int
+ .short 33
+ .byte "q_atomic_test_and_set_acquire_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_test_and_set_release_int
+ .globl .q_atomic_test_and_set_release_int
+ .csect q_atomic_test_and_set_release_int[DS],3
+q_atomic_test_and_set_release_int:
+ .llong .q_atomic_test_and_set_release_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_test_and_set_release_int:
+ eieio
+ lwarx 6,0,3
+ xor. 6,6,4
+ bne $+12
+ stwcx. 5,0,3
+ bne- $-16
+ subfic 3,6,0
+ adde 3,3,6
+ extsw 3,3
+ blr
+LT..q_atomic_test_and_set_release_int:
+ .long 0
+ .byte 0,9,32,64,0,0,3,0
+ .long 0
+ .long LT..q_atomic_test_and_set_release_int-.q_atomic_test_and_set_release_int
+ .short 33
+ .byte "q_atomic_test_and_set_release_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_test_and_set_ptr
+ .globl .q_atomic_test_and_set_ptr
+ .csect q_atomic_test_and_set_ptr[DS],3
+q_atomic_test_and_set_ptr:
+ .llong .q_atomic_test_and_set_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_test_and_set_ptr:
+ ldarx 6,0,3
+ xor. 6,6,4
+ bne $+12
+ stdcx. 5,0,3
+ bne- $-16
+ subfic 3,6,0
+ adde 3,3,6
+ blr
+LT..q_atomic_test_and_set_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,3,0
+ .long 0
+ .long LT..q_atomic_test_and_set_ptr-.q_atomic_test_and_set_ptr
+ .short 25
+ .byte "q_atomic_test_and_set_ptr"
+ .align 2
+
+ .align 2
+ .globl q_atomic_test_and_set_acquire_ptr
+ .globl .q_atomic_test_and_set_acquire_ptr
+ .csect q_atomic_test_and_set_acquire_ptr[DS],3
+q_atomic_test_and_set_acquire_ptr:
+ .llong .q_atomic_test_and_set_acquire_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_test_and_set_acquire_ptr:
+ ldarx 6,0,3
+ xor. 6,6,4
+ bne $+16
+ stdcx. 5,0,3
+ bne- $-16
+ isync
+ subfic 3,6,0
+ adde 3,3,6
+ blr
+LT..q_atomic_test_and_set_acquire_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,3,0
+ .long 0
+ .long LT..q_atomic_test_and_set_acquire_ptr-.q_atomic_test_and_set_acquire_ptr
+ .short 33
+ .byte "q_atomic_test_and_set_acquire_ptr"
+ .align 2
+
+ .align 2
+ .globl q_atomic_test_and_set_release_ptr
+ .globl .q_atomic_test_and_set_release_ptr
+ .csect q_atomic_test_and_set_release_ptr[DS],3
+q_atomic_test_and_set_release_ptr:
+ .llong .q_atomic_test_and_set_release_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_test_and_set_release_ptr:
+ eieio
+ ldarx 6,0,3
+ xor. 6,6,4
+ bne $+12
+ stdcx. 5,0,3
+ bne- $-16
+ subfic 3,6,0
+ adde 3,3,6
+ blr
+LT..q_atomic_test_and_set_release_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,3,0
+ .long 0
+ .long LT..q_atomic_test_and_set_release_ptr-.q_atomic_test_and_set_release_ptr
+ .short 33
+ .byte "q_atomic_test_and_set_release_ptr"
+ .align 2
+
+ .align 2
+ .globl q_atomic_increment
+ .globl .q_atomic_increment
+ .csect q_atomic_increment[DS],3
+q_atomic_increment:
+ .llong .q_atomic_increment,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_increment:
+ lwarx 4,0,3
+ addi 5,4,1
+ extsw 4,5
+ stwcx. 4,0,3
+ bne- $-16
+ mr 3,4
+ blr
+LT..q_atomic_increment:
+ .long 0
+ .byte 0,9,32,64,0,0,1,0
+ .long 0
+ .long LT..q_atomic_increment-.q_atomic_increment
+ .short 18
+ .byte "q_atomic_increment"
+ .align 2
+
+ .align 2
+ .globl q_atomic_decrement
+ .globl .q_atomic_decrement
+ .csect q_atomic_decrement[DS],3
+q_atomic_decrement:
+ .llong .q_atomic_decrement,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_decrement:
+ lwarx 4,0,3
+ subi 5,4,1
+ extsw 4,5
+ stwcx. 4,0,3
+ bne- $-16
+ mr 3,4
+ blr
+LT..q_atomic_decrement:
+ .long 0
+ .byte 0,9,32,64,0,0,1,0
+ .long 0
+ .long LT..q_atomic_decrement-.q_atomic_decrement
+ .short 18
+ .byte "q_atomic_decrement"
+ .align 2
+
+ .align 2
+ .globl q_atomic_set_int
+ .globl .q_atomic_set_int
+ .csect q_atomic_set_int[DS],3
+q_atomic_set_int:
+ .llong .q_atomic_set_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_set_int:
+ lwarx 5,0,3
+ stwcx. 4,0,3
+ bne- $-8
+ extsw 3,5
+ blr
+LT..q_atomic_set_int:
+ .long 0
+ .byte 0,9,32,64,0,0,2,0
+ .long 0
+ .long LT..q_atomic_set_int-.q_atomic_set_int
+ .short 16
+ .byte "q_atomic_set_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_store_acquire_int
+ .globl .q_atomic_fetch_and_store_acquire_int
+ .csect q_atomic_fetch_and_store_acquire_int[DS],3
+q_atomic_fetch_and_store_acquire_int:
+ .llong .q_atomic_fetch_and_store_acquire_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_store_acquire_int:
+ lwarx 5,0,3
+ stwcx. 4,0,3
+ bne- $-8
+ isync
+ extsw 3,5
+ blr
+LT..q_atomic_fetch_and_store_acquire_int:
+ .long 0
+ .byte 0,9,32,64,0,0,2,0
+ .long 0
+ .long LT..q_atomic_fetch_and_store_acquire_int-.q_atomic_fetch_and_store_acquire_int
+ .short 36
+ .byte "q_atomic_fetch_and_store_acquire_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_store_release_int
+ .globl .q_atomic_fetch_and_store_release_int
+ .csect q_atomic_fetch_and_store_release_int[DS],3
+q_atomic_fetch_and_store_release_int:
+ .llong .q_atomic_fetch_and_store_release_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_store_release_int:
+ eieio
+ lwarx 5,0,3
+ stwcx. 4,0,3
+ bne- $-8
+ extsw 3,5
+ blr
+LT..q_atomic_fetch_and_store_release_int:
+ .long 0
+ .byte 0,9,32,64,0,0,2,0
+ .long 0
+ .long LT..q_atomic_fetch_and_store_release_int-.q_atomic_fetch_and_store_release_int
+ .short 36
+ .byte "q_atomic_fetch_and_store_release_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_set_ptr
+ .globl .q_atomic_set_ptr
+ .csect q_atomic_set_ptr[DS],3
+q_atomic_set_ptr:
+ .llong .q_atomic_set_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_set_ptr:
+ ldarx 5,0,3
+ stdcx. 4,0,3
+ bne- $-8
+ mr 3,5
+ blr
+LT..q_atomic_set_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,2,0
+ .long 0
+ .long LT..q_atomic_set_ptr-.q_atomic_set_ptr
+ .short 16
+ .byte "q_atomic_set_ptr"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_store_acquire_ptr
+ .globl .q_atomic_fetch_and_store_acquire_ptr
+ .csect q_atomic_fetch_and_store_acquire_ptr[DS],3
+q_atomic_fetch_and_store_acquire_ptr:
+ .llong .q_atomic_fetch_and_store_acquire_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_store_acquire_ptr:
+ ldarx 5,0,3
+ stdcx. 4,0,3
+ bne- $-8
+ isync
+ mr 3,5
+ blr
+LT..q_atomic_fetch_and_store_acquire_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,2,0
+ .long 0
+ .long LT..q_atomic_fetch_and_store_acquire_ptr-.q_atomic_fetch_and_store_acquire_ptr
+ .short 36
+ .byte "q_atomic_fetch_and_store_acquire_ptr"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_store_release_ptr
+ .globl .q_atomic_fetch_and_store_release_ptr
+ .csect q_atomic_fetch_and_store_release_ptr[DS],3
+q_atomic_fetch_and_store_release_ptr:
+ .llong .q_atomic_fetch_and_store_release_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_store_release_ptr:
+ eieio
+ ldarx 5,0,3
+ stdcx. 4,0,3
+ bne- $-8
+ mr 3,5
+ blr
+LT..q_atomic_fetch_and_store_release_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,2,0
+ .long 0
+ .long LT..q_atomic_fetch_and_store_release_ptr-.q_atomic_fetch_and_store_release_ptr
+ .short 36
+ .byte "q_atomic_fetch_and_store_release_ptr"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_add_int
+ .globl .q_atomic_fetch_and_add_int
+ .csect q_atomic_fetch_and_add_int[DS],3
+q_atomic_fetch_and_add_int:
+ .llong .q_atomic_fetch_and_add_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_add_int:
+ lwarx 5,0,3
+ add 6,4,5
+ extsw 7,6
+ stwcx. 7,0,3
+ bne- $-16
+ extsw 3,5
+ blr
+LT..q_atomic_fetch_and_add_int:
+ .long 0
+ .byte 0,9,32,64,0,0,1,0
+ .long 0
+ .long LT..q_atomic_fetch_and_add_int-.q_atomic_fetch_and_add_int
+ .short 26
+ .byte "q_atomic_fetch_and_add_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_add_acquire_int
+ .globl .q_atomic_fetch_and_add_acquire_int
+ .csect q_atomic_fetch_and_add_acquire_int[DS],3
+q_atomic_fetch_and_add_acquire_int:
+ .llong .q_atomic_fetch_and_add_acquire_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_add_acquire_int:
+ lwarx 5,0,3
+ add 6,4,5
+ extsw 7,6
+ stwcx. 7,0,3
+ bne- $-16
+ isync
+ extsw 3,5
+ blr
+LT..q_atomic_fetch_and_add_acquire_int:
+ .long 0
+ .byte 0,9,32,64,0,0,1,0
+ .long 0
+ .long LT..q_atomic_fetch_and_add_acquire_int-.q_atomic_fetch_and_add_acquire_int
+ .short 34
+ .byte "q_atomic_fetch_and_add_acquire_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_add_release_int
+ .globl .q_atomic_fetch_and_add_release_int
+ .csect q_atomic_fetch_and_add_release_int[DS],3
+q_atomic_fetch_and_add_release_int:
+ .llong .q_atomic_fetch_and_add_release_int,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_add_release_int:
+ eieio
+ lwarx 5,0,3
+ add 6,4,5
+ extsw 7,6
+ stwcx. 7,0,3
+ bne- $-16
+ extsw 3,5
+ blr
+LT..q_atomic_fetch_and_add_release_int:
+ .long 0
+ .byte 0,9,32,64,0,0,1,0
+ .long 0
+ .long LT..q_atomic_fetch_and_add_release_int-.q_atomic_fetch_and_add_release_int
+ .short 34
+ .byte "q_atomic_fetch_and_add_release_int"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_add_ptr
+ .globl .q_atomic_fetch_and_add_ptr
+ .csect q_atomic_fetch_and_add_ptr[DS],3
+q_atomic_fetch_and_add_ptr:
+ .llong .q_atomic_fetch_and_add_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_add_ptr:
+ ldarx 5,0,3
+ add 6,4,5
+ stdcx. 6,0,3
+ bne- $-12
+ mr 3,5
+ blr
+LT..q_atomic_fetch_and_add_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,1,0
+ .long 0
+ .long LT..q_atomic_fetch_and_add_ptr-.q_atomic_fetch_and_add_ptr
+ .short 26
+ .byte "q_atomic_fetch_and_add_ptr"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_add_acquire_ptr
+ .globl .q_atomic_fetch_and_add_acquire_ptr
+ .csect q_atomic_fetch_and_add_acquire_ptr[DS],3
+q_atomic_fetch_and_add_acquire_ptr:
+ .llong .q_atomic_fetch_and_add_acquire_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_add_acquire_ptr:
+ ldarx 5,0,3
+ add 6,4,5
+ stdcx. 6,0,3
+ bne- $-12
+ isync
+ mr 3,5
+ blr
+LT..q_atomic_fetch_and_add_acquire_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,1,0
+ .long 0
+ .long LT..q_atomic_fetch_and_add_acquire_ptr-.q_atomic_fetch_and_add_acquire_ptr
+ .short 34
+ .byte "q_atomic_fetch_and_add_acquire_ptr"
+ .align 2
+
+ .align 2
+ .globl q_atomic_fetch_and_add_release_ptr
+ .globl .q_atomic_fetch_and_add_release_ptr
+ .csect q_atomic_fetch_and_add_release_ptr[DS],3
+q_atomic_fetch_and_add_release_ptr:
+ .llong .q_atomic_fetch_and_add_release_ptr,TOC[tc0],0
+ .csect .text[PR]
+.q_atomic_fetch_and_add_release_ptr:
+ eieio
+ ldarx 5,0,3
+ add 6,4,5
+ stdcx. 6,0,3
+ bne- $-12
+ mr 3,5
+ blr
+LT..q_atomic_fetch_and_add_release_ptr:
+ .long 0
+ .byte 0,9,32,64,0,0,1,0
+ .long 0
+ .long LT..q_atomic_fetch_and_add_release_ptr-.q_atomic_fetch_and_add_release_ptr
+ .short 34
+ .byte "q_atomic_fetch_and_add_release_ptr"
+ .align 2
+
+_section_.text:
+ .csect .data[RW],3
+ .llong _section_.text
diff --git a/src/corelib/arch/qatomic_alpha.h b/src/corelib/arch/qatomic_alpha.h
new file mode 100644
index 0000000000..be5d7ec884
--- /dev/null
+++ b/src/corelib/arch/qatomic_alpha.h
@@ -0,0 +1,642 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_ALPHA_H
+#define QATOMIC_ALPHA_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
+
+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_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
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
+{ return false; }
+
+#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; }
+
+#if defined(Q_CC_GNU)
+
+inline bool QBasicAtomicInt::ref()
+{
+ register int old, tmp;
+ asm volatile("1:\n"
+ "ldl_l %0,%2\n" /* old=*ptr; */
+ "addl %0,1,%1\n" /* tmp=old+1; */
+ "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %1,2f\n" /* if (tmp == 0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
+ :
+ : "memory");
+ return old != -1;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ register int old, tmp;
+ asm volatile("1:\n"
+ "ldl_l %0,%2\n" /* old=*ptr; */
+ "subl %0,1,%1\n" /* tmp=old-1; */
+ "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %1,2f\n" /* if (tmp==0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
+ :
+ : "memory");
+ return old != 1;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ register int ret;
+ asm volatile("1:\n"
+ "ldl_l %0,%1\n" /* ret=*ptr; */
+ "cmpeq %0,%2,%0\n"/* if (ret==expected) ret=0; else ret=1; */
+ "beq %0,3f\n" /* if (ret==0) goto 3; */
+ "mov %3,%0\n" /* ret=newval; */
+ "stl_c %0,%1\n" /* if ((*ptr=ret)!=ret) ret=0; else ret=1; */
+ "beq %0,2f\n" /* if (ret==0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ : "=&r" (ret), "+m" (_q_value)
+ : "r" (expectedValue), "r" (newValue)
+ : "memory");
+ return ret != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ register int ret;
+ asm volatile("1:\n"
+ "ldl_l %0,%1\n" /* ret=*ptr; */
+ "cmpeq %0,%2,%0\n"/* if (ret==expected) ret=0; else ret=1; */
+ "beq %0,3f\n" /* if (ret==0) goto 3; */
+ "mov %3,%0\n" /* ret=newval; */
+ "stl_c %0,%1\n" /* if ((*ptr=ret)!=ret) ret=0; else ret=1; */
+ "beq %0,2f\n" /* if (ret==0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ "mb\n"
+ : "=&r" (ret), "+m" (_q_value)
+ : "r" (expectedValue), "r" (newValue)
+ : "memory");
+ return ret != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ register int ret;
+ asm volatile("mb\n"
+ "1:\n"
+ "ldl_l %0,%1\n" /* ret=*ptr; */
+ "cmpeq %0,%2,%0\n"/* if (ret==expected) ret=0; else ret=1; */
+ "beq %0,3f\n" /* if (ret==0) goto 3; */
+ "mov %3,%0\n" /* ret=newval; */
+ "stl_c %0,%1\n" /* if ((*ptr=ret)!=ret) ret=0; else ret=1; */
+ "beq %0,2f\n" /* if (ret==0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ : "=&r" (ret), "+m" (_q_value)
+ : "r" (expectedValue), "r" (newValue)
+ : "memory");
+ return ret != 0;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+{
+ register int old, tmp;
+ asm volatile("1:\n"
+ "ldl_l %0,%2\n" /* old=*ptr; */
+ "mov %3,%1\n" /* tmp=newval; */
+ "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %1,2f\n" /* if (tmp==0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
+ : "r" (newValue)
+ : "memory");
+ return old;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ register int old, tmp;
+ asm volatile("1:\n"
+ "ldl_l %0,%2\n" /* old=*ptr; */
+ "mov %3,%1\n" /* tmp=newval; */
+ "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %1,2f\n" /* if (tmp==0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ "mb\n"
+ : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
+ : "r" (newValue)
+ : "memory");
+ return old;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ register int old, tmp;
+ asm volatile("mb\n"
+ "1:\n"
+ "ldl_l %0,%2\n" /* old=*ptr; */
+ "mov %3,%1\n" /* tmp=newval; */
+ "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %1,2f\n" /* if (tmp==0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
+ : "r" (newValue)
+ : "memory");
+ return old;
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ register int old, tmp;
+ asm volatile("1:\n"
+ "ldl_l %0,%2\n" /* old=*ptr; */
+ "addl %0,%3,%1\n"/* tmp=old+value; */
+ "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %1,2f\n" /* if (tmp == 0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
+ : "r" (valueToAdd)
+ : "memory");
+ return old;
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ register int old, tmp;
+ asm volatile("1:\n"
+ "ldl_l %0,%2\n" /* old=*ptr; */
+ "addl %0,%3,%1\n"/* tmp=old+value; */
+ "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %1,2f\n" /* if (tmp == 0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ "mb\n"
+ : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
+ : "r" (valueToAdd)
+ : "memory");
+ return old;
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ register int old, tmp;
+ asm volatile("mb\n"
+ "1:\n"
+ "ldl_l %0,%2\n" /* old=*ptr; */
+ "addl %0,%3,%1\n"/* tmp=old+value; */
+ "stl_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %1,2f\n" /* if (tmp == 0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
+ : "r" (valueToAdd)
+ : "memory");
+ return old;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
+{
+ register void *ret;
+ asm volatile("1:\n"
+ "ldq_l %0,%1\n" /* ret=*ptr; */
+ "cmpeq %0,%2,%0\n"/* if (ret==expected) tmp=0; else tmp=1; */
+ "beq %0,3f\n" /* if (tmp==0) goto 3; */
+ "mov %3,%0\n" /* tmp=newval; */
+ "stq_c %0,%1\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %0,2f\n" /* if (ret==0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ : "=&r" (ret), "+m" (_q_value)
+ : "r" (expectedValue), "r" (newValue)
+ : "memory");
+ return ret != 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
+{
+ register void *ret;
+ asm volatile("1:\n"
+ "ldq_l %0,%1\n" /* ret=*ptr; */
+ "cmpeq %0,%2,%0\n"/* if (ret==expected) tmp=0; else tmp=1; */
+ "beq %0,3f\n" /* if (tmp==0) goto 3; */
+ "mov %3,%0\n" /* tmp=newval; */
+ "stq_c %0,%1\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %0,2f\n" /* if (ret==0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ "mb\n"
+ : "=&r" (ret), "+m" (_q_value)
+ : "r" (expectedValue), "r" (newValue)
+ : "memory");
+ return ret != 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
+{
+ register void *ret;
+ asm volatile("mb\n"
+ "1:\n"
+ "ldq_l %0,%1\n" /* ret=*ptr; */
+ "cmpeq %0,%2,%0\n"/* if (ret==expected) tmp=0; else tmp=1; */
+ "beq %0,3f\n" /* if (tmp==0) goto 3; */
+ "mov %3,%0\n" /* tmp=newval; */
+ "stq_c %0,%1\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %0,2f\n" /* if (ret==0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ : "=&r" (ret), "+m" (_q_value)
+ : "r" (expectedValue), "r" (newValue)
+ : "memory");
+ return ret != 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
+{
+ register T *old, *tmp;
+ asm volatile("1:\n"
+ "ldq_l %0,%2\n" /* old=*ptr; */
+ "mov %3,%1\n" /* tmp=newval; */
+ "stq_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %1,2f\n" /* if (tmp==0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
+ : "r" (newValue)
+ : "memory");
+ return old;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
+{
+ register T *old, *tmp;
+ asm volatile("1:\n"
+ "ldq_l %0,%2\n" /* old=*ptr; */
+ "mov %3,%1\n" /* tmp=newval; */
+ "stq_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %1,2f\n" /* if (tmp==0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ "mb\n"
+ : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
+ : "r" (newValue)
+ : "memory");
+ return old;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
+{
+ register T *old, *tmp;
+ asm volatile("mb\n"
+ "1:\n"
+ "ldq_l %0,%2\n" /* old=*ptr; */
+ "mov %3,%1\n" /* tmp=newval; */
+ "stq_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %1,2f\n" /* if (tmp==0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ : "=&r" (old), "=&r" (tmp), "+m" (_q_value)
+ : "r" (newValue)
+ : "memory");
+ return old;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
+{
+ register T *old, *tmp;
+ asm volatile("1:\n"
+ "ldq_l %0,%2\n" /* old=*ptr; */
+ "addq %0,%3,%1\n"/* tmp=old+value; */
+ "stq_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %1,2f\n" /* if (tmp == 0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
+ : "r" (valueToAdd)
+ : "memory");
+ return reinterpret_cast<T *>(old);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
+{
+ register T *old, *tmp;
+ asm volatile("1:\n"
+ "ldq_l %0,%2\n" /* old=*ptr; */
+ "addq %0,%3,%1\n"/* tmp=old+value; */
+ "stq_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %1,2f\n" /* if (tmp == 0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ "mb\n"
+ : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
+ : "r" (valueToAdd)
+ : "memory");
+ return reinterpret_cast<T *>(old);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
+{
+ register T *old, *tmp;
+ asm volatile("mb\n"
+ "1:\n"
+ "ldq_l %0,%2\n" /* old=*ptr; */
+ "addq %0,%3,%1\n"/* tmp=old+value; */
+ "stq_c %1,%2\n" /* if ((*ptr=tmp)!=tmp) tmp=0; else tmp=1; */
+ "beq %1,2f\n" /* if (tmp == 0) goto 2; */
+ "br 3f\n" /* goto 3; */
+ "2: br 1b\n" /* goto 1; */
+ "3:\n"
+ : "=&r" (old), "=&r" (tmp), "+m"(_q_value)
+ : "r" (valueToAdd)
+ : "memory");
+ return reinterpret_cast<T *>(old);
+}
+
+#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_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 int q_atomic_fetch_and_add_acquire_int(volatile int *ptr, int value);
+ Q_CORE_EXPORT int q_atomic_fetch_and_add_release_int(volatile int *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::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 int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+{
+ return q_atomic_set_int(&_q_value, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ return q_atomic_fetch_and_store_acquire_int(&_q_value, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ return q_atomic_fetch_and_store_release_int(&_q_value, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ return q_atomic_fetch_and_add_int(&_q_value, valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ return q_atomic_fetch_and_add_acquire_int(&_q_value, valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ return q_atomic_fetch_and_add_release_int(&_q_value, valueToAdd);
+}
+
+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 T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
+{
+ return reinterpret_cast<T *>(q_atomic_set_ptr(&_q_value, newValue));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
+{
+ return reinterpret_cast<T *>(q_atomic_fetch_and_store_acquire_ptr(&_q_value, newValue));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
+{
+ return reinterpret_cast<T *>(q_atomic_fetch_and_store_release_ptr(&_q_value, newValue));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
+{
+ return reinterpret_cast<T *>(q_atomic_fetch_and_add_ptr(&_q_value, newValue));
+}
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
+{
+ return reinterpret_cast<T *>(q_atomic_fetch_and_add_acquire_ptr(&_q_value, newValue));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
+{
+ return reinterpret_cast<T *>(q_atomic_fetch_and_add_release_ptr(&_q_value, newValue));
+}
+
+#endif // Q_CC_GNU
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ return testAndSetAcquire(expectedValue, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{
+ return fetchAndStoreAcquire(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+{
+ return fetchAndAddAcquire(valueToAdd);
+}
+
+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>::fetchAndStoreOrdered(T *newValue)
+{
+ return fetchAndStoreAcquire(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+{
+ return fetchAndAddAcquire(valueToAdd);
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QATOMIC_ALPHA_H
diff --git a/src/corelib/arch/qatomic_arch.h b/src/corelib/arch/qatomic_arch.h
new file mode 100644
index 0000000000..3da833a424
--- /dev/null
+++ b/src/corelib/arch/qatomic_arch.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_ARCH_H
+#define QATOMIC_ARCH_H
+
+QT_BEGIN_HEADER
+
+#include "QtCore/qglobal.h"
+
+#if defined(QT_ARCH_INTEGRITY)
+# include "QtCore/qatomic_integrity.h"
+#elif defined(QT_ARCH_VXWORKS)
+# 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)
+# include "QtCore/qatomic_powerpc.h"
+#elif defined(QT_ARCH_S390)
+# 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_SYMBIAN)
+# include "QtCore/qatomic_symbian.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
+
+QT_END_HEADER
+
+#endif // QATOMIC_ARCH_H
diff --git a/src/corelib/arch/qatomic_arm.h b/src/corelib/arch/qatomic_arm.h
new file mode 100644
index 0000000000..07d21438d6
--- /dev/null
+++ b/src/corelib/arch/qatomic_arm.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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__) \
+ || defined(__ARM_ARCH_6Z__) \
+ || defined(__ARM_ARCH_6K__) \
+ || defined(__ARM_ARCH_6ZK__) \
+ || 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
new file mode 100644
index 0000000000..ac8fe9670e
--- /dev/null
+++ b/src/corelib/arch/qatomic_armv5.h
@@ -0,0 +1,431 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_ARMV5_H
+#define QATOMIC_ARMV5_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; }
+
+#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))
+
+#else
+
+extern Q_CORE_EXPORT char q_atomic_lock;
+Q_CORE_EXPORT void qt_atomic_yield(int *);
+
+#ifdef Q_CC_RVCT
+
+Q_CORE_EXPORT __asm char q_atomic_swp(volatile char *ptr, char newval);
+
+#else
+
+inline char q_atomic_swp(volatile char *ptr, char newval)
+{
+ register char ret;
+ asm volatile("swpb %0,%2,[%3]"
+ : "=&r"(ret), "=m" (*ptr)
+ : "r"(newval), "r"(ptr)
+ : "cc", "memory");
+ return ret;
+}
+
+#endif // Q_CC_RVCT
+
+#endif // QT_NO_ARM_EABI
+
+// Reference counting
+
+inline bool QBasicAtomicInt::ref()
+{
+#ifndef QT_NO_ARM_EABI
+ register int originalValue;
+ register int newValue;
+ do {
+ originalValue = _q_value;
+ newValue = originalValue + 1;
+ } while (qt_atomic_eabi_cmpxchg_int(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()
+{
+#ifndef QT_NO_ARM_EABI
+ register int originalValue;
+ register int newValue;
+ do {
+ originalValue = _q_value;
+ newValue = originalValue - 1;
+ } while (qt_atomic_eabi_cmpxchg_int(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)
+{
+#ifndef QT_NO_ARM_EABI
+ register int originalValue;
+ do {
+ originalValue = _q_value;
+ if (originalValue != expectedValue)
+ return false;
+ } while (qt_atomic_eabi_cmpxchg_int(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)
+{
+ add r2, pc, #0
+ bx r2
+ arm
+ swp r2,r1,[r0]
+ mov r0, r2
+ bx lr
+ thumb
+}
+
+#else
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+{
+ 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)
+{
+#ifndef QT_NO_ARM_EABI
+ register T *originalValue;
+ register T *newValue;
+ do {
+ originalValue = _q_value;
+ newValue = originalValue + valueToAdd;
+ } while (qt_atomic_eabi_cmpxchg_ptr(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
+
+QT_END_HEADER
+
+#endif // QATOMIC_ARMV5_H
diff --git a/src/corelib/arch/qatomic_armv6.h b/src/corelib/arch/qatomic_armv6.h
new file mode 100644
index 0000000000..3bd605853f
--- /dev/null
+++ b/src/corelib/arch/qatomic_armv6.h
@@ -0,0 +1,559 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_ARMV6_H
+#define QATOMIC_ARMV6_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
+
+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_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
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
+{ return false; }
+
+#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; }
+
+#ifndef Q_CC_RVCT
+
+#ifndef Q_DATA_MEMORY_BARRIER
+# define Q_DATA_MEMORY_BARRIER asm volatile("":::"memory")
+#endif
+#ifndef Q_COMPILER_MEMORY_BARRIER
+# define Q_COMPILER_MEMORY_BARRIER asm volatile("":::"memory")
+#endif
+
+inline bool QBasicAtomicInt::ref()
+{
+ register int newValue;
+ register int result;
+ asm volatile("0:\n"
+ "ldrex %[newValue], [%[_q_value]]\n"
+ "add %[newValue], %[newValue], #1\n"
+ "strex %[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;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ register int newValue;
+ register int result;
+ asm volatile("0:\n"
+ "ldrex %[newValue], [%[_q_value]]\n"
+ "sub %[newValue], %[newValue], #1\n"
+ "strex %[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;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ register int result;
+ asm volatile("0:\n"
+ "ldrex %[result], [%[_q_value]]\n"
+ "eors %[result], %[result], %[expectedValue]\n"
+ "strexeq %[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;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+{
+ register int originalValue;
+ register int result;
+ asm volatile("0:\n"
+ "ldrex %[originalValue], [%[_q_value]]\n"
+ "strex %[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;
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ register int originalValue;
+ register int newValue;
+ register int result;
+ asm volatile("0:\n"
+ "ldrex %[originalValue], [%[_q_value]]\n"
+ "add %[newValue], %[originalValue], %[valueToAdd]\n"
+ "strex %[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),
+ [_q_value] "r" (&_q_value)
+ : "cc");
+ return originalValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
+{
+ register T *result;
+ asm volatile("0:\n"
+ "ldrex %[result], [%[_q_value]]\n"
+ "eors %[result], %[result], %[expectedValue]\n"
+ "strexeq %[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 <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
+{
+ register T *originalValue;
+ register int result;
+ asm volatile("0:\n"
+ "ldrex %[originalValue], [%[_q_value]]\n"
+ "strex %[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 <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
+{
+ register T *originalValue;
+ register T *newValue;
+ register int result;
+ asm volatile("0:\n"
+ "ldrex %[originalValue], [%[_q_value]]\n"
+ "add %[newValue], %[originalValue], %[valueToAdd]\n"
+ "strex %[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)),
+ [_q_value] "r" (&_q_value)
+ : "cc");
+ return originalValue;
+}
+
+#else
+// This is Q_CC_RVCT
+
+// RVCT inline assembly documentation:
+// http://www.keil.com/support/man/docs/armcc/armcc_chdcffdb.htm
+// RVCT embedded assembly documentation:
+// http://www.keil.com/support/man/docs/armcc/armcc_chddbeib.htm
+
+#if __TARGET_ARCH_THUMB-0 < 4
+// save our pragma state and switch to ARM mode (unless using Thumb2)
+# pragma push
+# pragma arm
+#endif
+
+#ifndef Q_DATA_MEMORY_BARRIER
+# define Q_DATA_MEMORY_BARRIER __schedule_barrier()
+#endif
+#ifndef Q_COMPILER_MEMORY_BARRIER
+# define Q_COMPILER_MEMORY_BARRIER __schedule_barrier()
+#endif
+
+inline bool QBasicAtomicInt::ref()
+{
+ register int newValue;
+ register int result;
+ retry:
+ __asm {
+ ldrex newValue, [&_q_value]
+ add newValue, newValue, #1
+ strex result, newValue, [&_q_value]
+ teq result, #0
+ bne retry
+ }
+ return newValue != 0;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ register int newValue;
+ register int result;
+ retry:
+ __asm {
+ ldrex newValue, [&_q_value]
+ sub newValue, newValue, #1
+ strex result, newValue, [&_q_value]
+ teq result, #0
+ bne retry
+ }
+ return newValue != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ register int result;
+ retry:
+ __asm {
+ ldrex result, [&_q_value]
+ eors result, result, expectedValue
+ strexeq result, newValue, [&_q_value]
+ teqeq result, #1
+ beq retry
+ }
+ return result == 0;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+{
+ register int originalValue;
+ register int result;
+ retry:
+ __asm {
+ ldrex originalValue, [&_q_value]
+ strex result, newValue, [&_q_value]
+ teq result, #0
+ bne retry
+ }
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ register int originalValue;
+ register int newValue;
+ register int result;
+ retry:
+ __asm {
+ ldrex originalValue, [&_q_value]
+ add newValue, originalValue, valueToAdd
+ strex result, newValue, [&_q_value]
+ teq result, #0
+ bne retry
+ }
+ return originalValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
+{
+ register T *result;
+ retry:
+ __asm {
+ ldrex result, [&_q_value]
+ eors result, result, expectedValue
+ strexeq result, newValue, [&_q_value]
+ teqeq result, #1
+ beq retry
+ }
+ return result == 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
+{
+ register T *originalValue;
+ register int result;
+ retry:
+ __asm {
+ ldrex originalValue, [&_q_value]
+ strex result, newValue, [&_q_value]
+ teq result, #0
+ bne retry
+ }
+ return originalValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
+{
+ register T *originalValue;
+ register T *newValue;
+ register int result;
+ retry:
+ __asm {
+ ldrex originalValue, [&_q_value]
+ add newValue, originalValue, valueToAdd * sizeof(T)
+ strex result, newValue, [&_q_value]
+ teq result, #0
+ bne retry
+ }
+ return originalValue;
+}
+
+#if __TARGET_ARCH_THUMB-0 < 4
+# pragma pop
+#endif
+
+#endif
+
+// 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)
+{
+ Q_DATA_MEMORY_BARRIER;
+ T *returnValue = fetchAndAddRelaxed(valueToAdd);
+ Q_COMPILER_MEMORY_BARRIER;
+ return returnValue;
+}
+
+#undef Q_DATA_MEMORY_BARRIER
+#undef Q_COMPILER_MEMORY_BARRIER
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QATOMIC_ARMV6_H
diff --git a/src/corelib/arch/qatomic_armv7.h b/src/corelib/arch/qatomic_armv7.h
new file mode 100644
index 0000000000..b35866b32c
--- /dev/null
+++ b/src/corelib/arch/qatomic_armv7.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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")
+#else
+# define Q_DATA_MEMORY_BARRIER do{__asm { dmb } __schedule_barrier();}while(0)
+#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
new file mode 100644
index 0000000000..a650d73332
--- /dev/null
+++ b/src/corelib/arch/qatomic_avr32.h
@@ -0,0 +1,252 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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
new file mode 100644
index 0000000000..dd53342dfa
--- /dev/null
+++ b/src/corelib/arch/qatomic_bfin.h
@@ -0,0 +1,343 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_BFIN_H
+#define QATOMIC_BFIN_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; }
+
+#define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isTestAndSetNative()
+{ return false; }
+inline bool QBasicAtomicInt::isTestAndSetWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndStoreNative()
+{ return false; }
+inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndAddNative()
+{ return false; }
+inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE
+
+template <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_NOT_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
+{ return false; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
+{ return false; }
+
+#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; }
+
+#if defined(Q_OS_LINUX) && defined(Q_CC_GNU)
+
+QT_BEGIN_INCLUDE_NAMESPACE
+#include <asm/fixed_code.h>
+QT_END_INCLUDE_NAMESPACE
+
+inline bool QBasicAtomicInt::ref()
+{
+ int ret;
+ asm volatile("R0 = 1;\n\t"
+ "P0 = %3;\n\t"
+ "CALL (%2);\n\t"
+ "%0 = R0;"
+ : "=da" (ret), "=m" (_q_value)
+ : "a" (ATOMIC_ADD32), "da" (&_q_value), "m" (_q_value)
+ : "R0", "R1", "P0", "RETS", "memory");
+ return ret != 0;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ int ret;
+ asm volatile("R0 = 1;\n\t"
+ "P0 = %3;\n\t"
+ "CALL (%2);\n\t"
+ "%0 = R0;"
+ : "=da" (ret), "=m" (_q_value)
+ : "a" (ATOMIC_SUB32), "da" (&_q_value), "m" (_q_value)
+ : "R0", "R1", "P0", "RETS", "memory");
+ return ret != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ long int readval;
+ asm volatile ("P0 = %2;\n\t"
+ "R1 = %3;\n\t"
+ "R2 = %4;\n\t"
+ "CALL (%5);\n\t"
+ "%0 = R0;\n\t"
+ : "=da" (readval), "=m" (_q_value)
+ : "da" (&_q_value),
+ "da" (expectedValue),
+ "da" (newValue),
+ "a" (ATOMIC_CAS32),
+ "m" (_q_value)
+ : "P0", "R0", "R1", "R2", "RETS", "memory", "cc");
+ return readval == expectedValue;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{
+ asm volatile("R1 = %2;\n\t"
+ "P0 = %4;\n\t"
+ "CALL (%3);\n\t"
+ "%0 = R0;"
+ : "=da" (newValue), "=m" (_q_value)
+ : "da" (newValue), "a" (ATOMIC_XCHG32), "da" (&_q_value), "m" (_q_value)
+ : "R0", "R1", "P0", "RETS", "memory");
+ return newValue;
+}
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+{
+ int ret;
+ asm volatile("R0 = %[val];\n\t"
+ "P0 = %[qvalp];\n\t"
+ "CALL (%[addr]);\n\t"
+ "%[ret] = R1;"
+ : [ret] "=da" (ret), "=m" (_q_value)
+ : [addr] "a" (ATOMIC_ADD32), [qvalp] "da" (&_q_value), "m" (_q_value), [val] "da" (valueToAdd)
+ : "R0", "R1", "P0", "RETS", "memory");
+ return ret;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+{
+ T *readval;
+ asm volatile ("P0 = %2;\n\t"
+ "R1 = %3;\n\t"
+ "R2 = %4;\n\t"
+ "CALL (%5);\n\t"
+ "%0 = R0;\n\t"
+ : "=da" (readval), "=m" (_q_value)
+ : "da" (&_q_value),
+ "da" (expectedValue),
+ "da" (newValue),
+ "a" (ATOMIC_CAS32),
+ "m" (_q_value)
+ : "P0", "R0", "R1", "R2", "RETS", "memory", "cc");
+ return readval == expectedValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+{
+ asm volatile("R1 = %2;\n\t"
+ "P0 = %4;\n\t"
+ "CALL (%3);\n\t"
+ "%0 = R0;"
+ : "=da" (newValue), "=m" (_q_value)
+ : "da" (newValue), "a" (ATOMIC_XCHG32), "da" (&_q_value), "m" (_q_value)
+ : "R0", "R1", "P0", "RETS", "memory");
+ return newValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+{
+ T* ret;
+ asm volatile("R0 = %[val];\n\t"
+ "P0 = %[qvalp];\n\t"
+ "CALL (%[addr]);\n\t"
+ "%[ret] = R1;"
+ : [ret] "=da" (ret), "=m" (_q_value)
+ : [addr] "a" (ATOMIC_ADD32), [qvalp] "da" (&_q_value), "m" (_q_value), [val] "da" (valueToAdd * sizeof(T))
+ : "R0", "R1", "P0", "RETS", "memory");
+ return ret;
+}
+
+
+#endif // Q_OS_LINUX && Q_CC_GNU
+
+// Test and set for integers
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+// Fetch and store for integers
+
+inline int QBasicAtomicInt::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::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>::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
+
+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>::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_BFIN_H
diff --git a/src/corelib/arch/qatomic_bootstrap.h b/src/corelib/arch/qatomic_bootstrap.h
new file mode 100644
index 0000000000..7927d8b557
--- /dev/null
+++ b/src/corelib/arch/qatomic_bootstrap.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_BOOTSTRAP_H
+#define QATOMIC_BOOTSTRAP_H
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+inline bool QBasicAtomicInt::ref()
+{
+ return ++_q_value != 0;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ return --_q_value != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ if (_q_value == expectedValue) {
+ _q_value = newValue;
+ return true;
+ }
+ 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 int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ int returnValue = _q_value;
+ _q_value += valueToAdd;
+ return returnValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+{
+ if (_q_value == expectedValue) {
+ _q_value = newValue;
+ return true;
+ }
+ return false;
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QATOMIC_BOOTSTRAP_H
diff --git a/src/corelib/arch/qatomic_generic.h b/src/corelib/arch/qatomic_generic.h
new file mode 100644
index 0000000000..d9c864798e
--- /dev/null
+++ b/src/corelib/arch/qatomic_generic.h
@@ -0,0 +1,282 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_GENERIC_H
+#define QATOMIC_GENERIC_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; }
+
+#define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isTestAndSetNative()
+{ return false; }
+inline bool QBasicAtomicInt::isTestAndSetWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndStoreNative()
+{ return false; }
+inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndAddNative()
+{ return false; }
+inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE
+
+template <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_NOT_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
+{ return false; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
+{ return false; }
+
+#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; }
+
+Q_CORE_EXPORT bool QBasicAtomicInt_testAndSetOrdered(volatile int *, int, int);
+Q_CORE_EXPORT int QBasicAtomicInt_fetchAndStoreOrdered(volatile int *, int);
+Q_CORE_EXPORT int QBasicAtomicInt_fetchAndAddOrdered(volatile int *, int);
+
+Q_CORE_EXPORT bool QBasicAtomicPointer_testAndSetOrdered(void * volatile *, void *, void *);
+Q_CORE_EXPORT void *QBasicAtomicPointer_fetchAndStoreOrdered(void * volatile *, void *);
+Q_CORE_EXPORT void *QBasicAtomicPointer_fetchAndAddOrdered(void * volatile *, qptrdiff);
+
+// Reference counting
+
+inline bool QBasicAtomicInt::ref()
+{
+ return QBasicAtomicInt_fetchAndAddOrdered(&_q_value, 1) != -1;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ return QBasicAtomicInt_fetchAndAddOrdered(&_q_value, -1) != 1;
+}
+
+// Test and set for integers
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ return QBasicAtomicInt_testAndSetOrdered(&_q_value, expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+// Fetch and store for integers
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{
+ return QBasicAtomicInt_fetchAndStoreOrdered(&_q_value, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+// Fetch and add for integers
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+{
+ return QBasicAtomicInt_fetchAndAddOrdered(&_q_value, valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+// Test and set for pointers
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+{
+ union { T * volatile * typed; void * volatile * voidp; } pointer;
+ pointer.typed = &_q_value;
+ return QBasicAtomicPointer_testAndSetOrdered(pointer.voidp, expectedValue, newValue);
+}
+
+template <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
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+{
+ union { T * volatile * typed; void * volatile * voidp; } pointer;
+ union { T *typed; void *voidp; } returnValue;
+ pointer.typed = &_q_value;
+ returnValue.voidp = QBasicAtomicPointer_fetchAndStoreOrdered(pointer.voidp, newValue);
+ return returnValue.typed;
+}
+
+template <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)
+{
+ union { T * volatile *typed; void * volatile *voidp; } pointer;
+ union { T *typed; void *voidp; } returnValue;
+ pointer.typed = &_q_value;
+ returnValue.voidp = QBasicAtomicPointer_fetchAndAddOrdered(pointer.voidp, valueToAdd * sizeof(T));
+ return returnValue.typed;
+}
+
+template <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_GENERIC_H
diff --git a/src/corelib/arch/qatomic_i386.h b/src/corelib/arch/qatomic_i386.h
new file mode 100644
index 0000000000..73095a94f6
--- /dev/null
+++ b/src/corelib/arch/qatomic_i386.h
@@ -0,0 +1,361 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_I386_H
+#define QATOMIC_I386_H
+
+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_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; }
+
+#if defined(Q_CC_GNU) || defined(Q_CC_INTEL)
+
+inline bool QBasicAtomicInt::ref()
+{
+ unsigned char ret;
+ asm volatile("lock\n"
+ "incl %0\n"
+ "setne %1"
+ : "=m" (_q_value), "=qm" (ret)
+ : "m" (_q_value)
+ : "memory");
+ return ret != 0;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ unsigned char ret;
+ asm volatile("lock\n"
+ "decl %0\n"
+ "setne %1"
+ : "=m" (_q_value), "=qm" (ret)
+ : "m" (_q_value)
+ : "memory");
+ return ret != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ 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)
+ : "memory");
+ return ret != 0;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{
+ asm volatile("xchgl %0,%1"
+ : "=r" (newValue), "+m" (_q_value)
+ : "0" (newValue)
+ : "memory");
+ return newValue;
+}
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+{
+ asm volatile("lock\n"
+ "xaddl %0,%1"
+ : "=r" (valueToAdd), "+m" (_q_value)
+ : "0" (valueToAdd)
+ : "memory");
+ return valueToAdd;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+{
+ 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)
+ : "memory");
+ return ret != 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+{
+ asm volatile("xchgl %0,%1"
+ : "=r" (newValue), "+m" (_q_value)
+ : "0" (newValue)
+ : "memory");
+ return newValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+{
+ asm volatile("lock\n"
+ "xaddl %0,%1"
+ : "=r" (valueToAdd), "+m" (_q_value)
+ : "0" (valueToAdd * sizeof(T))
+ : "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);
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+template <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>::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>::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_I386_H
diff --git a/src/corelib/arch/qatomic_ia64.h b/src/corelib/arch/qatomic_ia64.h
new file mode 100644
index 0000000000..42f30266d2
--- /dev/null
+++ b/src/corelib/arch/qatomic_ia64.h
@@ -0,0 +1,813 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_IA64_H
+#define QATOMIC_IA64_H
+
+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
+
+inline bool QBasicAtomicInt::isFetchAndAddNative()
+{ return true; }
+inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
+{ return false; }
+
+#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; }
+
+inline bool _q_ia64_fetchadd_immediate(register int value)
+{
+ return value == 1 || value == -1
+ || value == 4 || value == -4
+ || value == 8 || value == -8
+ || value == 16 || value == -16;
+}
+
+#if defined(Q_CC_INTEL)
+
+// intrinsics provided by the Intel C++ Compiler
+#include <ia64intrin.h>
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ return static_cast<int>(_InterlockedExchange(&_q_value, newValue));
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ __memory_barrier();
+ return static_cast<int>(_InterlockedExchange(&_q_value, newValue));
+}
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ register int expectedValueCopy = expectedValue;
+ return (static_cast<int>(_InterlockedCompareExchange(&_q_value,
+ newValue,
+ expectedValueCopy))
+ == expectedValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ register int expectedValueCopy = expectedValue;
+ return (static_cast<int>(_InterlockedCompareExchange_acq(reinterpret_cast<volatile uint *>(&_q_value),
+ newValue,
+ expectedValueCopy))
+ == expectedValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ register int expectedValueCopy = expectedValue;
+ return (static_cast<int>(_InterlockedCompareExchange_rel(reinterpret_cast<volatile uint *>(&_q_value),
+ newValue,
+ expectedValueCopy))
+ == 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)) {
+ if (valueToAdd == 1)
+ return __fetchadd4_acq((unsigned int *)&_q_value, 1);
+ if (valueToAdd == -1)
+ return __fetchadd4_acq((unsigned int *)&_q_value, -1);
+ }
+ return _InterlockedExchangeAdd(&_q_value, valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ if (__builtin_constant_p(valueToAdd)) {
+ if (valueToAdd == 1)
+ return __fetchadd4_rel((unsigned int *)&_q_value, 1);
+ if (valueToAdd == -1)
+ return __fetchadd4_rel((unsigned int *)&_q_value, -1);
+ }
+ __memory_barrier();
+ 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;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ return _InterlockedDecrement(&_q_value) != 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
+{
+ return (T *)_InterlockedExchangePointer(reinterpret_cast<void * volatile*>(&_q_value), 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;
+ return (_InterlockedCompareExchangePointer(reinterpret_cast<void * volatile*>(&_q_value),
+ newValue,
+ expectedValueCopy)
+ == expectedValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
+{
+ union {
+ volatile void *x;
+ volatile unsigned long *p;
+ };
+ x = &_q_value;
+ register T *expectedValueCopy = expectedValue;
+ return (_InterlockedCompareExchange64_acq(p, quintptr(newValue), quintptr(expectedValueCopy))
+ == quintptr(expectedValue));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
+{
+ union {
+ volatile void *x;
+ volatile unsigned long *p;
+ };
+ x = &_q_value;
+ register T *expectedValueCopy = expectedValue;
+ return (_InterlockedCompareExchange64_rel(p, quintptr(newValue), quintptr(expectedValueCopy))
+ == quintptr(expectedValue));
+}
+
+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,
+ valueToAdd * sizeof(T));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
+{
+ __memory_barrier();
+ return (T *)_InterlockedExchangeAdd64((volatile long *)&_q_value,
+ valueToAdd * sizeof(T));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+{
+ __memory_barrier();
+ return fetchAndAddAcquire(valueToAdd);
+}
+
+#else // !Q_CC_INTEL
+
+# if defined(Q_CC_GNU)
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ int ret;
+ asm volatile("xchg4 %0=%1,%2\n"
+ : "=r" (ret), "+m" (_q_value)
+ : "r" (newValue)
+ : "memory");
+ return ret;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ int ret;
+ asm volatile("mf\n"
+ "xchg4 %0=%1,%2\n"
+ : "=r" (ret), "+m" (_q_value)
+ : "r" (newValue)
+ : "memory");
+ return ret;
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ int ret;
+ asm volatile("mov ar.ccv=%2\n"
+ ";;\n"
+ "cmpxchg4.acq %0=%1,%3,ar.ccv\n"
+ : "=r" (ret), "+m" (_q_value)
+ : "r" (expectedValue), "r" (newValue)
+ : "memory");
+ return ret == expectedValue;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ int ret;
+ asm volatile("mov ar.ccv=%2\n"
+ ";;\n"
+ "cmpxchg4.rel %0=%1,%3,ar.ccv\n"
+ : "=r" (ret), "+m" (_q_value)
+ : "r" (expectedValue), "r" (newValue)
+ : "memory");
+ return ret == expectedValue;
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ int ret;
+
+#if (__GNUC__ >= 4)
+ // We implement a fast fetch-and-add when we can
+ if (__builtin_constant_p(valueToAdd) && _q_ia64_fetchadd_immediate(valueToAdd)) {
+ asm volatile("fetchadd4.acq %0=%1,%2\n"
+ : "=r" (ret), "+m" (_q_value)
+ : "i" (valueToAdd)
+ : "memory");
+ return ret;
+ }
+#endif
+
+ // otherwise, use a loop around test-and-set
+ ret = _q_value;
+ asm volatile("0:\n"
+ " mov r9=%0\n"
+ " mov ar.ccv=%0\n"
+ " add %0=%0, %2\n"
+ " ;;\n"
+ " cmpxchg4.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;
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ int ret;
+
+#if (__GNUC__ >= 4)
+ // We implement a fast fetch-and-add when we can
+ if (__builtin_constant_p(valueToAdd) && _q_ia64_fetchadd_immediate(valueToAdd)) {
+ asm volatile("fetchadd4.rel %0=%1,%2\n"
+ : "=r" (ret), "+m" (_q_value)
+ : "i" (valueToAdd)
+ : "memory");
+ return ret;
+ }
+#endif
+
+ // otherwise, use a loop around test-and-set
+ ret = _q_value;
+ asm volatile("0:\n"
+ " mov r9=%0\n"
+ " mov ar.ccv=%0\n"
+ " add %0=%0, %2\n"
+ " ;;\n"
+ " cmpxchg4.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;
+}
+
+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)
+{
+ 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;
+
+#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))) {
+ asm volatile("fetchadd8.acq %0=%1,%2\n"
+ : "=r" (ret), "+m" (_q_value)
+ : "i" (valueToAdd * sizeof(T))
+ : "memory");
+ return ret;
+ }
+#endif
+
+ // otherwise, use a loop around test-and-set
+ ret = _q_value;
+ asm volatile("0:\n"
+ " mov r9=%0\n"
+ " mov ar.ccv=%0\n"
+ " add %0=%0, %2\n"
+ " ;;\n"
+ " cmpxchg8.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 * sizeof(T))
+ : "r9", "p6", "memory");
+ return ret;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
+{
+ T *ret;
+
+#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))) {
+ asm volatile("fetchadd8.rel %0=%1,%2\n"
+ : "=r" (ret), "+m" (_q_value)
+ : "i" (valueToAdd * sizeof(T))
+ : "memory");
+ return ret;
+ }
+#endif
+
+ // otherwise, use a loop around test-and-set
+ ret = _q_value;
+ asm volatile("0:\n"
+ " mov r9=%0\n"
+ " mov ar.ccv=%0\n"
+ " add %0=%0, %2\n"
+ " ;;\n"
+ " cmpxchg8.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 * sizeof(T))
+ : "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
+#include <ia64/sys/inline.h>
+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)
+{
+ return _Asm_xchg((_Asm_sz)_SZ_W, &_q_value, (unsigned)newValue,
+ (_Asm_ldhint)_LDHINT_NONE, FENCE);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ _Asm_mf(FENCE);
+ return _Asm_xchg((_Asm_sz)_SZ_W, &_q_value, (unsigned)newValue,
+ (_Asm_ldhint)_LDHINT_NONE, FENCE);
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ _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;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ _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;
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ 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;
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ 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;
+}
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+{
+ _Asm_mf(FENCE);
+ return fetchAndAddAcquire(valueToAdd);
+}
+
+inline bool QBasicAtomicInt::ref()
+{
+ return (int)_Asm_fetchadd((_Asm_fasz)_FASZ_W, (_Asm_sem)_SEM_ACQ,
+ &_q_value, 1, (_Asm_ldhint)_LDHINT_NONE, FENCE) != -1;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ return (int)_Asm_fetchadd((_Asm_fasz)_FASZ_W, (_Asm_sem)_SEM_REL,
+ &_q_value, -1, (_Asm_ldhint)_LDHINT_NONE, FENCE) != 1;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(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
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
+{
+ _Asm_mf(FENCE);
+ return fetchAndStoreAcquire(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(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
+ return ret == expectedValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(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
+ return ret == expectedValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
+{
+ // implement the test-and-set loop
+ 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);
+ return old;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
+{
+ // implement the test-and-set loop
+ 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);
+ return old;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+{
+ _Asm_mf(FENCE);
+ return fetchAndAddAcquire(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);
+} // extern "C"
+
+#endif
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ return testAndSetAcquire(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ return testAndSetAcquire(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
+{
+ return testAndSetAcquire(expectedValue, newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+{
+ return testAndSetAcquire(expectedValue, newValue);
+}
+
+#endif // Q_CC_INTEL
+
+inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+{
+ return fetchAndStoreAcquire(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{
+ return fetchAndStoreRelease(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ return fetchAndAddAcquire(valueToAdd);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
+{
+ return fetchAndStoreAcquire(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+{
+ return fetchAndStoreRelaxed(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
+{
+ return fetchAndAddAcquire(valueToAdd);
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QATOMIC_IA64_H
diff --git a/src/corelib/arch/qatomic_integrity.h b/src/corelib/arch/qatomic_integrity.h
new file mode 100644
index 0000000000..6563903a25
--- /dev/null
+++ b/src/corelib/arch/qatomic_integrity.h
@@ -0,0 +1,289 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 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$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_INTEGRITY_H
+#define QATOMIC_INTEGRITY_H
+
+#include <INTEGRITY.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+#define qt_i2addr(a) reinterpret_cast<Address *>(const_cast<int *>(a))
+#define qt_p2addr(a) reinterpret_cast<Address *>(const_cast<void *>(a))
+#define qt_addr(a) reinterpret_cast<Address>(a)
+
+
+#define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isReferenceCountingNative()
+{ return false; }
+inline bool QBasicAtomicInt::isReferenceCountingWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isTestAndSetNative()
+{ return true; }
+inline bool QBasicAtomicInt::isTestAndSetWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_NOT_NATIVE
+
+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 true; }
+inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
+{ return true; }
+
+#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE
+
+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_NOT_NATIVE
+
+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 true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndAddWaitFree()
+{ return true; }
+
+// Reference counting
+
+inline bool QBasicAtomicInt::ref()
+{
+ int oldval;
+ AtomicModify(qt_i2addr(&_q_value), qt_i2addr(&oldval), 0, 1);
+ return _q_value != -1;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ int oldval;
+ AtomicModify(qt_i2addr(&_q_value), qt_i2addr(&oldval), 0, -1U);
+ return _q_value != 0;
+}
+
+// Test and set for integers
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ return TestAndSet(qt_i2addr(&_q_value), expectedValue, newValue) == Success;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+// Fetch and store for integers
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{
+ int old_val;
+ do {
+ old_val = _q_value;
+ } while (TestAndSet(qt_i2addr(&_q_value), old_val, newValue) != Success);
+ return old_val;
+}
+
+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)
+{
+ int old_val;
+ do {
+ old_val = _q_value;
+ } while (TestAndSet(qt_i2addr(&_q_value), old_val, old_val + valueToAdd) != Success);
+ return old_val;
+}
+
+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)
+{
+ return TestAndSet((Address*)&_q_value, qt_addr(expectedValue), qt_addr(newValue)) == Success;
+}
+
+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
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+{
+ Address old_val;
+ do {
+ old_val = *reinterpret_cast<Address *>(const_cast<T *>(newValue));
+ } while (TestAndSet(reinterpret_cast<Address *>(const_cast<T **>(&_q_value)), old_val, qt_addr(newValue)) != Success);
+ return reinterpret_cast<T *>(old_val);
+}
+
+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)
+{
+ AtomicModify(qt_p2addr(&_q_value), qt_addr(_q_value), qt_addr(_q_value) + valueToAdd * sizeof(T));
+ return _q_value;
+}
+
+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_INTEGRITY_H
+
diff --git a/src/corelib/arch/qatomic_macosx.h b/src/corelib/arch/qatomic_macosx.h
new file mode 100644
index 0000000000..be4501f4d2
--- /dev/null
+++ b/src/corelib/arch/qatomic_macosx.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#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
new file mode 100644
index 0000000000..6f2607c524
--- /dev/null
+++ b/src/corelib/arch/qatomic_mips.h
@@ -0,0 +1,892 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_MIPS_H
+#define QATOMIC_MIPS_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
+
+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_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
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
+{ return false; }
+
+#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; }
+
+#if defined(Q_CC_GNU) && !defined(Q_OS_IRIX)
+
+#if _MIPS_SIM == _ABIO32
+#define SET_MIPS2 ".set mips2\n\t"
+#else
+#define SET_MIPS2
+#endif
+
+inline bool QBasicAtomicInt::ref()
+{
+ register int originalValue;
+ register int newValue;
+ asm volatile(".set push\n"
+ SET_MIPS2
+ "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;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ register int originalValue;
+ register int newValue;
+ asm volatile(".set push\n"
+ SET_MIPS2
+ "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)
+ : [minusOne] "i" (-1)
+ : "cc", "memory");
+ 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)
+{
+ 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"
+ "sync\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::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)
+{
+ 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"
+ "sync\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::fetchAndStoreRelease(int newValue)
+{
+ 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"
+ "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)
+ : "cc", "memory");
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ 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"
+ "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)
+ : "cc", "memory");
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ 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"
+ "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)
+ : "cc", "memory");
+ return result == 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(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"
+ "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>::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)
+{
+ register T *originalValue;
+ register T *tempValue;
+ asm volatile(".set push\n"
+ SET_MIPS2
+ "sync\n"
+ "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>::fetchAndStoreOrdered(T *newValue)
+{
+ 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"
+ "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>::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 // Q_CC_GNU
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QATOMIC_MIPS_H
diff --git a/src/corelib/arch/qatomic_parisc.h b/src/corelib/arch/qatomic_parisc.h
new file mode 100644
index 0000000000..eeff9266ee
--- /dev/null
+++ b/src/corelib/arch/qatomic_parisc.h
@@ -0,0 +1,305 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_PARISC_H
+#define QATOMIC_PARISC_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; }
+
+#define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isTestAndSetNative()
+{ return false; }
+inline bool QBasicAtomicInt::isTestAndSetWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndStoreNative()
+{ return false; }
+inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndAddNative()
+{ return false; }
+inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE
+
+template <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_NOT_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
+{ return false; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
+{ return false; }
+
+#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; }
+
+extern "C" {
+ Q_CORE_EXPORT void q_atomic_lock(int *lock);
+ Q_CORE_EXPORT void q_atomic_unlock(int *lock);
+}
+
+// Reference counting
+
+inline bool QBasicAtomicInt::ref()
+{
+ q_atomic_lock(_q_lock);
+ bool ret = (++_q_value != 0);
+ q_atomic_unlock(_q_lock);
+ return ret;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ q_atomic_lock(_q_lock);
+ bool ret = (--_q_value != 0);
+ q_atomic_unlock(_q_lock);
+ return ret;
+}
+
+// Test-and-set for integers
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ q_atomic_lock(_q_lock);
+ if (_q_value == expectedValue) {
+ _q_value = newValue;
+ q_atomic_unlock(_q_lock);
+ return true;
+ }
+ q_atomic_unlock(_q_lock);
+ return false;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+// Fetch-and-store for integers
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{
+ q_atomic_lock(_q_lock);
+ int returnValue = _q_value;
+ _q_value = newValue;
+ q_atomic_unlock(_q_lock);
+ return returnValue;
+}
+
+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)
+{
+ q_atomic_lock(_q_lock);
+ int originalValue = _q_value;
+ _q_value += valueToAdd;
+ q_atomic_unlock(_q_lock);
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+// Test and set for pointers
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetOrdered(T *expectedValue, T *newValue)
+{
+ q_atomic_lock(_q_lock);
+ if (_q_value == expectedValue) {
+ _q_value = newValue;
+ q_atomic_unlock(_q_lock);
+ return true;
+ }
+ q_atomic_unlock(_q_lock);
+ return false;
+}
+
+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
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+{
+ q_atomic_lock(_q_lock);
+ T *returnValue = (_q_value);
+ _q_value = newValue;
+ q_atomic_unlock(_q_lock);
+ return returnValue;
+}
+
+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)
+{
+ q_atomic_lock(_q_lock);
+ T *returnValue = (_q_value);
+ _q_value += valueToAdd;
+ q_atomic_unlock(_q_lock);
+ return returnValue;
+}
+
+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_PARISC_H
diff --git a/src/corelib/arch/qatomic_powerpc.h b/src/corelib/arch/qatomic_powerpc.h
new file mode 100644
index 0000000000..e261ff7192
--- /dev/null
+++ b/src/corelib/arch/qatomic_powerpc.h
@@ -0,0 +1,648 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_POWERPC_H
+#define QATOMIC_POWERPC_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
+
+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_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
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
+{ return false; }
+
+#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; }
+
+#if defined(Q_CC_GNU)
+
+#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2) \
+ || (!defined(__64BIT__) && !defined(__powerpc64__) && !defined(__ppc64__))
+# define _Q_VALUE "0, %[_q_value]"
+# define _Q_VALUE_MEMORY_OPERAND "+m" (_q_value)
+# define _Q_VALUE_REGISTER_OPERAND [_q_value] "r" (&_q_value),
+#else
+// On 64-bit with gcc >= 4.2
+# define _Q_VALUE "%y[_q_value]"
+# define _Q_VALUE_MEMORY_OPERAND [_q_value] "+Z" (_q_value)
+# define _Q_VALUE_REGISTER_OPERAND
+#endif
+
+inline bool QBasicAtomicInt::ref()
+{
+ register int originalValue;
+ register int newValue;
+ asm volatile("lwarx %[originalValue]," _Q_VALUE "\n"
+ "addi %[newValue], %[originalValue], %[one]\n"
+ "stwcx. %[newValue]," _Q_VALUE "\n"
+ "bne- $-12\n"
+ : [originalValue] "=&b" (originalValue),
+ [newValue] "=&r" (newValue),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [one] "i" (1)
+ : "cc", "memory");
+ return newValue != 0;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ register int originalValue;
+ register int newValue;
+ asm volatile("lwarx %[originalValue]," _Q_VALUE "\n"
+ "addi %[newValue], %[originalValue], %[minusOne]\n"
+ "stwcx. %[newValue]," _Q_VALUE "\n"
+ "bne- $-12\n"
+ : [originalValue] "=&b" (originalValue),
+ [newValue] "=&r" (newValue),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [minusOne] "i" (-1)
+ : "cc", "memory");
+ return newValue != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ register int result;
+ asm volatile("lwarx %[result]," _Q_VALUE "\n"
+ "xor. %[result], %[result], %[expectedValue]\n"
+ "bne $+12\n"
+ "stwcx. %[newValue]," _Q_VALUE "\n"
+ "bne- $-16\n"
+ : [result] "=&r" (result),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [expectedValue] "r" (expectedValue),
+ [newValue] "r" (newValue)
+ : "cc", "memory");
+ return result == 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ register int result;
+ asm volatile("lwarx %[result]," _Q_VALUE "\n"
+ "xor. %[result], %[result], %[expectedValue]\n"
+ "bne $+16\n"
+ "stwcx. %[newValue]," _Q_VALUE "\n"
+ "bne- $-16\n"
+ "isync\n"
+ : [result] "=&r" (result),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [expectedValue] "r" (expectedValue),
+ [newValue] "r" (newValue)
+ : "cc", "memory");
+ return result == 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ register int result;
+ asm volatile("eieio\n"
+ "lwarx %[result]," _Q_VALUE "\n"
+ "xor. %[result], %[result], %[expectedValue]\n"
+ "bne $+12\n"
+ "stwcx. %[newValue]," _Q_VALUE "\n"
+ "bne- $-16\n"
+ : [result] "=&r" (result),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [expectedValue] "r" (expectedValue),
+ [newValue] "r" (newValue)
+ : "cc", "memory");
+ return result == 0;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+{
+ register int originalValue;
+ asm volatile("lwarx %[originalValue]," _Q_VALUE "\n"
+ "stwcx. %[newValue]," _Q_VALUE "\n"
+ "bne- $-8\n"
+ : [originalValue] "=&r" (originalValue),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [newValue] "r" (newValue)
+ : "cc", "memory");
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ register int originalValue;
+ asm volatile("lwarx %[originalValue]," _Q_VALUE "\n"
+ "stwcx. %[newValue]," _Q_VALUE "\n"
+ "bne- $-8\n"
+ "isync\n"
+ : [originalValue] "=&r" (originalValue),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [newValue] "r" (newValue)
+ : "cc", "memory");
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ register int originalValue;
+ asm volatile("eieio\n"
+ "lwarx %[originalValue]," _Q_VALUE "\n"
+ "stwcx. %[newValue]," _Q_VALUE "\n"
+ "bne- $-8\n"
+ : [originalValue] "=&r" (originalValue),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [newValue] "r" (newValue)
+ : "cc", "memory");
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ register int originalValue;
+ register int newValue;
+ asm volatile("lwarx %[originalValue]," _Q_VALUE "\n"
+ "add %[newValue], %[originalValue], %[valueToAdd]\n"
+ "stwcx. %[newValue]," _Q_VALUE "\n"
+ "bne- $-12\n"
+ : [originalValue] "=&r" (originalValue),
+ [newValue] "=&r" (newValue),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [valueToAdd] "r" (valueToAdd)
+ : "cc", "memory");
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ register int originalValue;
+ register int newValue;
+ asm volatile("lwarx %[originalValue]," _Q_VALUE "\n"
+ "add %[newValue], %[originalValue], %[valueToAdd]\n"
+ "stwcx. %[newValue]," _Q_VALUE "\n"
+ "bne- $-12\n"
+ "isync\n"
+ : [originalValue] "=&r" (originalValue),
+ [newValue] "=&r" (newValue),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [valueToAdd] "r" (valueToAdd)
+ : "cc", "memory");
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ register int originalValue;
+ register int newValue;
+ asm volatile("eieio\n"
+ "lwarx %[originalValue]," _Q_VALUE "\n"
+ "add %[newValue], %[originalValue], %[valueToAdd]\n"
+ "stwcx. %[newValue]," _Q_VALUE "\n"
+ "bne- $-12\n"
+ : [originalValue] "=&r" (originalValue),
+ [newValue] "=&r" (newValue),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [valueToAdd] "r" (valueToAdd)
+ : "cc", "memory");
+ return originalValue;
+}
+
+#if defined(__64BIT__) || defined(__powerpc64__) || defined(__ppc64__)
+# define LPARX "ldarx"
+# define STPCX "stdcx."
+#else
+# define LPARX "lwarx"
+# define STPCX "stwcx."
+#endif
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
+{
+ register void *result;
+ asm volatile(LPARX" %[result]," _Q_VALUE "\n"
+ "xor. %[result], %[result], %[expectedValue]\n"
+ "bne $+12\n"
+ STPCX" %[newValue]," _Q_VALUE "\n"
+ "bne- $-16\n"
+ : [result] "=&r" (result),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [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 void *result;
+ asm volatile(LPARX" %[result]," _Q_VALUE "\n"
+ "xor. %[result], %[result], %[expectedValue]\n"
+ "bne $+16\n"
+ STPCX" %[newValue]," _Q_VALUE "\n"
+ "bne- $-16\n"
+ "isync\n"
+ : [result] "=&r" (result),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [expectedValue] "r" (expectedValue),
+ [newValue] "r" (newValue)
+ : "cc", "memory");
+ return result == 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
+{
+ register void *result;
+ asm volatile("eieio\n"
+ LPARX" %[result]," _Q_VALUE "\n"
+ "xor. %[result], %[result], %[expectedValue]\n"
+ "bne $+12\n"
+ STPCX" %[newValue]," _Q_VALUE "\n"
+ "bne- $-16\n"
+ : [result] "=&r" (result),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [expectedValue] "r" (expectedValue),
+ [newValue] "r" (newValue)
+ : "cc", "memory");
+ return result == 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
+{
+ register T *originalValue;
+ asm volatile(LPARX" %[originalValue]," _Q_VALUE "\n"
+ STPCX" %[newValue]," _Q_VALUE "\n"
+ "bne- $-8\n"
+ : [originalValue] "=&r" (originalValue),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [newValue] "r" (newValue)
+ : "cc", "memory");
+ return originalValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
+{
+ register T *originalValue;
+ asm volatile(LPARX" %[originalValue]," _Q_VALUE "\n"
+ STPCX" %[newValue]," _Q_VALUE "\n"
+ "bne- $-8\n"
+ "isync\n"
+ : [originalValue] "=&r" (originalValue),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [newValue] "r" (newValue)
+ : "cc", "memory");
+ return originalValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
+{
+ register T *originalValue;
+ asm volatile("eieio\n"
+ LPARX" %[originalValue]," _Q_VALUE "\n"
+ STPCX" %[newValue]," _Q_VALUE "\n"
+ "bne- $-8\n"
+ : [originalValue] "=&r" (originalValue),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [newValue] "r" (newValue)
+ : "cc", "memory");
+ return originalValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
+{
+ register T *originalValue;
+ register T *newValue;
+ asm volatile(LPARX" %[originalValue]," _Q_VALUE "\n"
+ "add %[newValue], %[originalValue], %[valueToAdd]\n"
+ STPCX" %[newValue]," _Q_VALUE "\n"
+ "bne- $-12\n"
+ : [originalValue] "=&r" (originalValue),
+ [newValue] "=&r" (newValue),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [valueToAdd] "r" (valueToAdd * sizeof(T))
+ : "cc", "memory");
+ return originalValue;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
+{
+ register T *originalValue;
+ register T *newValue;
+ asm volatile(LPARX" %[originalValue]," _Q_VALUE "\n"
+ "add %[newValue], %[originalValue], %[valueToAdd]\n"
+ STPCX" %[newValue]," _Q_VALUE "\n"
+ "bne- $-12\n"
+ "isync\n"
+ : [originalValue] "=&r" (originalValue),
+ [newValue] "=&r" (newValue),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [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("eieio\n"
+ LPARX" %[originalValue]," _Q_VALUE "\n"
+ "add %[newValue], %[originalValue], %[valueToAdd]\n"
+ STPCX" %[newValue]," _Q_VALUE "\n"
+ "bne- $-12\n"
+ : [originalValue] "=&r" (originalValue),
+ [newValue] "=&r" (newValue),
+ _Q_VALUE_MEMORY_OPERAND
+ : _Q_VALUE_REGISTER_OPERAND
+ [valueToAdd] "r" (valueToAdd * sizeof(T))
+ : "cc", "memory");
+ return originalValue;
+}
+
+#undef LPARX
+#undef STPCX
+#undef _Q_VALUE
+#undef _Q_VALUE_MEMORY_OPERAND
+#undef _Q_VALUE_REGISTER_OPERAND
+
+#else
+
+extern "C" {
+ int q_atomic_test_and_set_int(volatile int *ptr, int expectedValue, int newValue);
+ int q_atomic_test_and_set_acquire_int(volatile int *ptr, int expectedValue, int newValue);
+ int q_atomic_test_and_set_release_int(volatile int *ptr, int expectedValue, int newValue);
+ int q_atomic_test_and_set_ptr(volatile void *ptr, void *expectedValue, void *newValue);
+ int q_atomic_test_and_set_acquire_ptr(volatile void *ptr, void *expectedValue, void *newValue);
+ int q_atomic_test_and_set_release_ptr(volatile void *ptr, void *expectedValue, void *newValue);
+ int q_atomic_increment(volatile int *);
+ int q_atomic_decrement(volatile int *);
+ int q_atomic_set_int(volatile int *, int);
+ int q_atomic_fetch_and_store_acquire_int(volatile int *ptr, int newValue);
+ int q_atomic_fetch_and_store_release_int(volatile int *ptr, int newValue);
+ void *q_atomic_set_ptr(volatile void *, void *);
+ int q_atomic_fetch_and_store_acquire_ptr(volatile void *ptr, void *newValue);
+ int q_atomic_fetch_and_store_release_ptr(volatile void *ptr, void *newValue);
+ int q_atomic_fetch_and_add_int(volatile int *ptr, int valueToAdd);
+ int q_atomic_fetch_and_add_acquire_int(volatile int *ptr, int valueToAdd);
+ int q_atomic_fetch_and_add_release_int(volatile int *ptr, int valueToAdd);
+ void *q_atomic_fetch_and_add_ptr(volatile void *ptr, qptrdiff valueToAdd);
+ void *q_atomic_fetch_and_add_acquire_ptr(volatile void *ptr, qptrdiff valueToAdd);
+ void *q_atomic_fetch_and_add_release_ptr(volatile void *ptr, qptrdiff valueToAdd);
+} // 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::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 int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+{
+ return q_atomic_set_int(&_q_value, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ return q_atomic_fetch_and_store_acquire_int(&_q_value, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ return q_atomic_fetch_and_store_release_int(&_q_value, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ return q_atomic_fetch_and_add_int(&_q_value, valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ return q_atomic_fetch_and_add_acquire_int(&_q_value, valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ return q_atomic_fetch_and_add_release_int(&_q_value, valueToAdd);
+}
+
+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 T *QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
+{
+ return reinterpret_cast<T *>(q_atomic_set_ptr(&_q_value, newValue));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
+{
+ return reinterpret_cast<T *>(q_atomic_fetch_and_store_acquire_ptr(&_q_value, newValue));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
+{
+ return reinterpret_cast<T *>(q_atomic_fetch_and_store_release_ptr(&_q_value, newValue));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelaxed(qptrdiff valueToAdd)
+{
+ return reinterpret_cast<T *>(q_atomic_fetch_and_add_ptr(&_q_value, valueToAdd * sizeof(T)));
+}
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddAcquire(qptrdiff valueToAdd)
+{
+ return reinterpret_cast<T *>(q_atomic_fetch_and_add_acquire_ptr(&_q_value, valueToAdd * sizeof(T)));
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddRelease(qptrdiff valueToAdd)
+{
+ return reinterpret_cast<T *>(q_atomic_fetch_and_add_release_ptr(&_q_value, valueToAdd * sizeof(T)));
+}
+
+#endif
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ return testAndSetAcquire(expectedValue, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{
+ return fetchAndStoreAcquire(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+{
+ return fetchAndAddAcquire(valueToAdd);
+}
+
+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>::fetchAndStoreOrdered(T *newValue)
+{
+ return fetchAndStoreAcquire(newValue);
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T *QBasicAtomicPointer<T>::fetchAndAddOrdered(qptrdiff valueToAdd)
+{
+ return fetchAndAddAcquire(valueToAdd);
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QATOMIC_POWERPC_H
diff --git a/src/corelib/arch/qatomic_s390.h b/src/corelib/arch/qatomic_s390.h
new file mode 100644
index 0000000000..552ebe43fe
--- /dev/null
+++ b/src/corelib/arch/qatomic_s390.h
@@ -0,0 +1,426 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_S390_H
+#define QATOMIC_S390_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
+
+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_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
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
+{ return true; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
+{ return false; }
+
+#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; }
+
+#ifdef __GNUC__
+#define __GNU_EXTENSION __extension__
+#else
+#define __GNU_EXTENSION
+#endif
+
+#define __CS_LOOP(ptr, op_val, op_string, pre, post) __GNU_EXTENSION ({ \
+ volatile int old_val, new_val; \
+ __asm__ __volatile__(pre \
+ " l %0,0(%3)\n" \
+ "0: lr %1,%0\n" \
+ op_string " %1,%4\n" \
+ " cs %0,%1,0(%3)\n" \
+ " jl 0b\n" \
+ post \
+ : "=&d" (old_val), "=&d" (new_val), \
+ "=m" (*ptr) \
+ : "a" (ptr), "d" (op_val), \
+ "m" (*ptr) \
+ : "cc", "memory" ); \
+ new_val; \
+})
+
+#define __CS_OLD_LOOP(ptr, op_val, op_string, pre, post ) __GNU_EXTENSION ({ \
+ volatile int old_val, new_val; \
+ __asm__ __volatile__(pre \
+ " l %0,0(%3)\n" \
+ "0: lr %1,%0\n" \
+ op_string " %1,%4\n" \
+ " cs %0,%1,0(%3)\n" \
+ " jl 0b\n" \
+ post \
+ : "=&d" (old_val), "=&d" (new_val), \
+ "=m" (*ptr) \
+ : "a" (ptr), "d" (op_val), \
+ "m" (*ptr) \
+ : "cc", "memory" ); \
+ old_val; \
+})
+
+#ifdef __s390x__
+#define __CSG_OLD_LOOP(ptr, op_val, op_string, pre, post) __GNU_EXTENSION ({ \
+ long old_val, new_val; \
+ __asm__ __volatile__(pre \
+ " lg %0,0(%3)\n" \
+ "0: lgr %1,%0\n" \
+ op_string " %1,%4\n" \
+ " csg %0,%1,0(%3)\n" \
+ " jl 0b\n" \
+ post \
+ : "=&d" (old_val), "=&d" (new_val), \
+ "=m" (*ptr) \
+ : "a" (ptr), "d" (op_val), \
+ "m" (*ptr) \
+ : "cc", "memory" ); \
+ old_val; \
+})
+#endif
+
+inline bool QBasicAtomicInt::ref()
+{
+ return __CS_LOOP(&_q_value, 1, "ar", "", "") != 0;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ return __CS_LOOP(&_q_value, 1, "sr", "", "") != 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ int retval;
+ __asm__ __volatile__(
+ " lr %0,%3\n"
+ " cs %0,%4,0(%2)\n"
+ " ipm %0\n"
+ " srl %0,28\n"
+ "0:"
+ : "=&d" (retval), "=m" (_q_value)
+ : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
+ "m" (_q_value) : "cc", "memory" );
+ return retval == 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ int retval;
+ __asm__ __volatile__(
+ " lr %0,%3\n"
+ " cs %0,%4,0(%2)\n"
+ " ipm %0\n"
+ " srl %0,28\n"
+ "0:\n"
+ " bcr 15,0\n"
+ : "=&d" (retval), "=m" (_q_value)
+ : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
+ "m" (_q_value) : "cc", "memory" );
+ return retval == 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ int retval;
+ __asm__ __volatile__(
+ " bcr 15,0\n"
+ " lr %0,%3\n"
+ " cs %0,%4,0(%2)\n"
+ " ipm %0\n"
+ " srl %0,28\n"
+ "0:"
+ : "=&d" (retval), "=m" (_q_value)
+ : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
+ "m" (_q_value) : "cc", "memory" );
+ return retval == 0;
+}
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ return testAndSetAcquire(expectedValue, newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+{
+ return __CS_OLD_LOOP(&_q_value, newValue, "lr", "", "");
+}
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ return __CS_OLD_LOOP(&_q_value, newValue, "lr", "", "bcr 15,0\n");
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ return __CS_OLD_LOOP(&_q_value, newValue, "lr", "bcr 15,0\n", "");
+}
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{
+ return fetchAndStoreAcquire(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelaxed(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddAcquire(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddRelease(int valueToAdd)
+{
+ return fetchAndAddOrdered(valueToAdd);
+}
+
+inline int QBasicAtomicInt::fetchAndAddOrdered(int valueToAdd)
+{
+ return __CS_OLD_LOOP(&_q_value, valueToAdd, "ar", "", "bcr 15,0\n");
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValue, T *newValue)
+{
+ int retval;
+
+#ifndef __s390x__
+ __asm__ __volatile__(
+ " lr %0,%3\n"
+ " cs %0,%4,0(%2)\n"
+ " ipm %0\n"
+ " srl %0,28\n"
+ "0:"
+ : "=&d" (retval), "=m" (_q_value)
+ : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
+ "m" (_q_value) : "cc", "memory" );
+#else
+ __asm__ __volatile__(
+ " lgr %0,%3\n"
+ " csg %0,%4,0(%2)\n"
+ " ipm %0\n"
+ " srl %0,28\n"
+ "0:"
+ : "=&d" (retval), "=m" (_q_value)
+ : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
+ "m" (_q_value) : "cc", "memory" );
+#endif
+
+ return retval == 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetAcquire(T *expectedValue, T *newValue)
+{
+ int retval;
+
+#ifndef __s390x__
+ __asm__ __volatile__(
+ " lr %0,%3\n"
+ " cs %0,%4,0(%2)\n"
+ " ipm %0\n"
+ " srl %0,28\n"
+ "0:\n"
+ " bcr 15,0\n"
+ : "=&d" (retval), "=m" (_q_value)
+ : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
+ "m" (_q_value) : "cc", "memory" );
+#else
+ __asm__ __volatile__(
+ " lgr %0,%3\n"
+ " csg %0,%4,0(%2)\n"
+ " ipm %0\n"
+ " srl %0,28\n"
+ "0:\n"
+ " bcr 15,0\n"
+ : "=&d" (retval), "=m" (_q_value)
+ : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
+ "m" (_q_value) : "cc", "memory" );
+#endif
+
+ return retval == 0;
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelease(T *expectedValue, T *newValue)
+{
+ int retval;
+
+#ifndef __s390x__
+ __asm__ __volatile__(
+ " bcr 15,0\n"
+ " lr %0,%3\n"
+ " cs %0,%4,0(%2)\n"
+ " ipm %0\n"
+ " srl %0,28\n"
+ "0:"
+ : "=&d" (retval), "=m" (_q_value)
+ : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
+ "m" (_q_value) : "cc", "memory" );
+#else
+ __asm__ __volatile__(
+ " bcr 15,0\n"
+ " lgr %0,%3\n"
+ " csg %0,%4,0(%2)\n"
+ " ipm %0\n"
+ " srl %0,28\n"
+ "0:"
+ : "=&d" (retval), "=m" (_q_value)
+ : "a" (&_q_value), "d" (expectedValue) , "d" (newValue),
+ "m" (_q_value) : "cc", "memory" );
+#endif
+
+ return retval == 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)
+{
+#ifndef __s390x__
+ return (T*)__CS_OLD_LOOP(&_q_value, (int)newValue, "lr", "", "");
+#else
+ return (T*)__CSG_OLD_LOOP(&_q_value, (long)newValue, "lgr", "", "");
+#endif
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T* QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
+{
+#ifndef __s390x__
+ return (T*)__CS_OLD_LOOP(&_q_value, (int)newValue, "lr", "", "bcr 15,0 \n");
+#else
+ return (T*)__CSG_OLD_LOOP(&_q_value, (long)newValue, "lgr", "", "bcr 15,0 \n");
+#endif
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T* QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
+{
+#ifndef __s390x__
+ return (T*)__CS_OLD_LOOP(&_q_value, (int)newValue, "lr", "bcr 15,0 \n", "");
+#else
+ return (T*)__CSG_OLD_LOOP(&_q_value, (long)newValue, "lgr", "bcr 15,0\n", "");
+#endif
+}
+
+template <typename T>
+Q_INLINE_TEMPLATE T* QBasicAtomicPointer<T>::fetchAndStoreOrdered(T *newValue)
+{
+ return fetchAndStoreAcquire(newValue);
+}
+
+
+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);
+}
+
+#undef __GNU_EXTENSION
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QATOMIC_S390_H
diff --git a/src/corelib/arch/qatomic_sh.h b/src/corelib/arch/qatomic_sh.h
new file mode 100644
index 0000000000..0150ca4443
--- /dev/null
+++ b/src/corelib/arch/qatomic_sh.h
@@ -0,0 +1,330 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QATOMIC_SH_H
+#define QATOMIC_SH_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; }
+
+#define Q_ATOMIC_INT_TEST_AND_SET_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isTestAndSetNative()
+{ return false; }
+inline bool QBasicAtomicInt::isTestAndSetWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_FETCH_AND_STORE_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndStoreNative()
+{ return false; }
+inline bool QBasicAtomicInt::isFetchAndStoreWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NOT_NATIVE
+
+inline bool QBasicAtomicInt::isFetchAndAddNative()
+{ return false; }
+inline bool QBasicAtomicInt::isFetchAndAddWaitFree()
+{ return false; }
+
+#define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NOT_NATIVE
+
+template <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_NOT_NATIVE
+
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreNative()
+{ return false; }
+template <typename T>
+Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::isFetchAndStoreWaitFree()
+{ return false; }
+
+#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; }
+
+extern Q_CORE_EXPORT volatile char qt_atomic_lock;
+Q_CORE_EXPORT void qt_atomic_yield(int *count);
+
+inline int qt_atomic_tasb(volatile char *ptr)
+{
+ register int ret;
+ asm volatile("tas.b @%2\n"
+ "movt %0"
+ : "=&r"(ret), "=m"(*ptr)
+ : "r"(ptr)
+ : "cc", "memory");
+ return ret;
+}
+
+// Reference counting
+
+inline bool QBasicAtomicInt::ref()
+{
+ int count = 0;
+ while (qt_atomic_tasb(&qt_atomic_lock) == 0)
+ qt_atomic_yield(&count);
+ int originalValue = _q_value++;
+ qt_atomic_lock = 0;
+ return originalValue != -1;
+}
+
+inline bool QBasicAtomicInt::deref()
+{
+ int count = 0;
+ while (qt_atomic_tasb(&qt_atomic_lock) == 0)
+ qt_atomic_yield(&count);
+ int originalValue = _q_value--;
+ qt_atomic_lock = 0;
+ return originalValue != 1;
+}
+
+// Test and set for integers
+
+inline bool QBasicAtomicInt::testAndSetOrdered(int expectedValue, int newValue)
+{
+ bool returnValue = false;
+ int count = 0;
+ while (qt_atomic_tasb(&qt_atomic_lock) == 0)
+ qt_atomic_yield(&count);
+ if (_q_value == expectedValue) {
+ _q_value = newValue;
+ returnValue = true;
+ }
+ qt_atomic_lock = 0;
+ return returnValue;
+}
+
+inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetAcquire(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+inline bool QBasicAtomicInt::testAndSetRelease(int expectedValue, int newValue)
+{
+ return testAndSetOrdered(expectedValue, newValue);
+}
+
+// Fetch and store for integers
+
+inline int QBasicAtomicInt::fetchAndStoreOrdered(int newValue)
+{
+ int count = 0;
+ while (qt_atomic_tasb(&qt_atomic_lock) == 0)
+ qt_atomic_yield(&count);
+ int originalValue = _q_value;
+ _q_value = newValue;
+ qt_atomic_lock = 0;
+ return originalValue;
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelaxed(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreAcquire(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);
+}
+
+inline int QBasicAtomicInt::fetchAndStoreRelease(int newValue)
+{
+ return fetchAndStoreOrdered(newValue);