/****************************************************************************
**
** Copyright (C) 2006-2007 Trolltech ASA. All rights reserved.
**
** This file is part of the documentation of the Qt Toolkit.
**
** This file may be used under the terms of the GNU General Public
** License version 2.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of
** this file.  Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
** http://trolltech.com/products/qt/licenses/licensing/opensource/
**
** If you are unsure which license is appropriate for your use, please
** review the following information:
** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
** or contact the sales department at sales@trolltech.com.
**
** In addition, as a special exception, Trolltech gives you certain
** additional rights. These rights are described in the Trolltech GPL
** Exception version 1.0, which can be found at
** http://www.trolltech.com/products/qt/gplexception/ and in the file
** GPL_EXCEPTION.txt in this package.
**
** In addition, as a special exception, Trolltech, as the sole copyright
** holder for Qt Designer, grants users of the Qt/Eclipse Integration
** plug-in the right for the Qt/Eclipse Integration to link to
** functionality provided by Qt Designer and its related libraries.
**
** Trolltech reserves all rights not expressly granted herein.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/

/*!
    \page atomic-operations.html
    \title Implementing Atomic Operations
    \ingroup architecture
    \ingroup qtopiacore
    \brief A guide to implementing atomic operations on new architectures.

    Qt uses an optimization called \l {Implicitly Shared
    Classes}{implicit sharing} for many of its value classes.

    Starting with Qt 4, all of Qt's implicitly shared classes can
    safely be copied across threads like any other value classes,
    i.e., they are fully \l {Thread Support in Qt#Reentrancy and
    Thread-Safety}{reentrant}. This is accomplished by implementing
    reference counting operations using atomic hardware instructions
    on all the different platforms supported by Qt.

    To support a new architecture, it is important to ensure that
    these platform-specific atomic operations are implemented in a
    corresponding header file (\c qatomic_ARCH.h), and that this file
    is located in Qt's \c src/corelib/arch directory. For example, the
    Intel 80386 implementation is located in \c
    src/corelib/arch/qatomic_i386.h.

    Currently, Qt provides two classes providing several atomic
    operations, QAtomicInt and QAtomicPointer. These classes inherit
    from QBasicAtomicInt and QBasicAtomicPointer, respectively.

    When porting Qt to a new architecture, the QBasicAtomicInt and
    QBasicAtomicPointer classes must be implemented, \e not QAtomicInt
    and QAtomicPointer. The former classes do not have constructors,
    which makes them POD (plain-old-data). Both classes only have a
    single member variable called \c _q_value, which stores the
    value. This is the value that all of the atomic operations read
    and modify.

    All of the member functions mentioned in the QAtomicInt and
    QAtomicPointer API documentation must be implemented. Note that
    these the implementations of the atomic operations in these
    classes must be atomic with respect to both interrupts and
    multiple processors.

    \omit

    If you cannot implement these functions efficiently on your
    platform without great difficulty, consider defining
    Q_SPECIALIZED_QATOMIC and implementing the following members:

    \list
    \o \l {12}{struct QBasicAtomic}
    \o \l {13}{template <typename T> struct QBasicAtomicPointer<T>}
    \o \l {14}{int q_atomic_test_and_set_ptr()}
    \o \l {15}{void *q_atomic_set_ptr()}
    \endlist

    \endomit

    \warning The functions mentioned in this document are
    used internally by Qt and are not part of the public API. They may
    change in future versions of Qt. The purpose of this document is
    to aid people interested in porting Qt to a new architecture.

    \hr

    \section1 Member Documentation

    \target 1
    \section2
    int q_atomic_test_and_set_int (volatile int *ptr, int expected, int newval)

    Atomic test-and-set for integers.

    \code
    if (*ptr == expected) {
        *ptr = newval;
        return !0;
    }
    return 0;
    \endcode

    If the value in memory pointed to by \a ptr is the \a expected
    value, this function assigns \a newval to \a ptr and returns a
    non-zero value.  If the value in memory pointed to by \a ptr is \e not
    the \a expected value, this function does nothing and returns
    zero.

    There are 3 variants of the fetch-and-add integer function: Each
    variant implies a different memory semantic, i.e. the relation of
    memory operations before or after the test-and-set
    operation. Since modern hardware can reorder memory operations to
    improve performance, these functions are used to ensure the order
    of memory operations (often called a \e{memory barrier}).

    \bold{Note:} This variant of the test-and-set integer function
    implies that memory semantic is unspecified.

    See also \l{4}{q_atomic_test_and_set_ptr()}.

    \target 2
    \section2
    int q_atomic_test_and_set_acquire_int (volatile int *ptr, int expected, int newval)

    This function behaves essentially like the above function.

    \bold{Note:} This variant of the test-and-set integer function
    implies that the atomic test-and-set operation must be performed
    before memory operations after the test-and-set.

    \target 3
    \section2
    int q_atomic_test_and_set_release_int (volatile int *ptr, int expected, int newval)

    This function behaves essentially like the above function.

    \bold{Note:} This variant of the test-and-set integer function
    implies that all memory operations must be performed before the
    test-and-set.

    \target 4
    \section2
    int q_atomic_test_and_set_ptr (volatile void *ptr, void *expected, void *newval)

    Atomic test-and-set for pointers.

    \code
    if (*ptr == expected) {
        *ptr = newval;
        return !0;
    }
    return 0;
    \endcode

    If the value in memory pointed to by \a ptr is the \a expected
    value, this function assigns \a newval to \a ptr and returns a
    non-zero value.  If the value in memory pointed to by \a ptr is \e not
    the \a expected value, this function does nothing and returns
    zero.

    See also \l{1}{q_atomic_test_and_set_int()}.

    \target 5
    \section2 int q_atomic_increment (volatile int *ptr)

    Atomic integer increment.

    \code
    ++(*ptr);
    return *ptr ? !0 : 0;
    \endcode

    Increments the value in memory pointed to by \a ptr. This function
    returns zero if the new value of \a *ptr is zero; otherwise it returns
    a non-zero value.

    \bold{Tip:} Depending on the architecture, it may be easier to return the
    new value after incrementing \a *ptr:

    \code
    return ++(*ptr);
    \endcode

    Another option is to return the zero-flag that is set by some
    processors in control or status registers:

    \code
    ++(*ptr);
    return !(ControlRegister & ZeroFlag);
    \endcode

    See also \l{6}{q_atomic_decrement()}.

    \target 6
    \section2 int q_atomic_decrement (volatile int *ptr)

    Atomic integer decrement.

    \code
    --(*ptr);
    return *ptr ?  : 0;
    \endcode

    Decrements the value in memory pointed to by \a ptr. This function
    returns zero if the new value of \a *ptr is zero; otherwise it
    returns a non-zero value.

    \bold{Tip:} Depending on the architecture, it may be easier to return the
    new value after incrementing \a *ptr:

    \code
    return --(*ptr);
    \endcode

    Another option is to return the zero-flag that is set by some
    processors in control or status registers:

    \code
    --(*ptr);
    return !(ControlRegister & ZeroFlag);
    \endcode

    See also \l{5}{q_atomic_increment()}.

    \target 7
    \section2 int q_atomic_set_int (volatile int *ptr, int newval)

    Atomic fetch-and-store for integers.

    \code
    tmp = *ptr;
    *ptr = newval;
    return tmp;
    \endcode

    Sets the value in memory pointed to by \a ptr to \a newval and
    returns the previous value of \a *ptr.

    See also \l{8}{q_atomic_set_ptr()}.

    \target 8
    \section2 void *q_atomic_set_ptr (volatile void *ptr, void *newval)

    Atomic fetch-and-store for pointers.

    \code
    tmp = *ptr;
    *ptr = newval;
    return tmp;
    \endcode

    Sets the value in memory pointed to by \a ptr to \a newval and
    returns the previous value of \a *ptr.

    See also \l{7}{q_atomic_set_int()}.

    \target 9
    \section2 int q_atomic_fetch_and_add_int (volatile int *ptr, int value)

    Atomic fetch-and-add for integers.

    \code
    tmp = *ptr;
    *ptr += value;
    return tmp;
    \endcode

    Adds the value in memory pointed to by \a ptr with \a value and
    returns the previous value of \a *ptr;

    There are 3 variants of the test-and-set integer function: Each
    variant implies a different memory semantic, i.e. the relation of
    memory operations before or after the test-and-set
    operation. Since modern hardware can reorder memory operations to
    improve performance, these functions are used to ensure the order
    of memory operations (often called a \e{memory barrier}).

    \bold{Note:} This variant of the test-and-set integer function
    implies that memory semantic is unspecified.

    \target 10
    \section2
    int q_atomic_fetch_and_add_acquire_int (volatile int *ptr, int value)

    This function behaves essentially like the above function.

    \bold{Note:} This variant of the fetch-and-add integer function
    implies that the atomic fetch-and-add operation must be performed
    before memory operations after the fetch-and-add.

    \target 11
    \section2
    int q_atomic_fetch_and_add_release_int (volatile int *ptr, int value)

    This function behaves essentially like the above function.

    \bold{Note:} This variant of the fetch-and-add integer function
    implies that all memory operations must be performed before the
    fetch-and-add.

    \omit

    \target 12
    \section2 struct QBasicAtomic

    \target 13
    \section2 template <typename T> struct QBasicAtomicPointer<T>

    \target 14
    \section2
    int q_atomic_test_and_set_ptr (volatile void *ptr, void *expected, void *newval)

    \target 15
    \section2 void *q_atomic_set_ptr (volatile void *ptr, void *newval)

    \endomit
*/
