Oracle Coherence for C++ API
Release 3.6.1.0
E18813-01

- Main Page
- Namespaces
- Classes
- Files

# coherence/native/NativeAtomic64.hpp

    00001 /*
    00002 * NativeAtomic64.hpp
    00003 *
    00004 * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
    00005 *
    00006 * Oracle is a registered trademarks of Oracle Corporation and/or its
    00007 * affiliates.
    00008 *
    00009 * This software is the confidential and proprietary information of Oracle
    00010 * Corporation. You shall not disclose such confidential and proprietary
    00011 * information and shall use it only in accordance with the terms of the
    00012 * license agreement you entered into with Oracle.
    00013 *
    00014 * This notice may not be removed or altered.
    00015 */
    00016 #ifndef COH_NATIVE_ATOMIC_WORD_HPP
    00017 #define COH_NATIVE_ATOMIC_WORD_HPP
    00018
    00019 #include "coherence/lang/compatibility.hpp"
    00020
    00021 COH_OPEN_NAMESPACE2(coherence,native)
    00022
    00023
    00024 /**
    00025 * @internal
    00026 *
    00027 * 64-bit atomic integer, providing JSR-133 volatile memory semantics.
    00028 *
    00029 * @author mf 2007.12.01
    00030 */
    00031 class COH_EXPORT NativeAtomic64
    00032     {
    00033     // ----- constructors ---------------------------------------------------
    00034
    00035     public:
    00036         /**
    00037         * Create a new Atomic64, as Atomic64 is not an Object
    00038         * it is the responsibility of the caller to eventually
    00039         * destroy this object.
    00040         *
    00041         * @param lValue   the initial value
    00042         * @param fAtomic  true if the initial assignment needs synchronization
    00043         *
    00044         * @return a pointer to the new Atomic64
    00045         */
    00046         NativeAtomic64(int64_t lValue = 0, bool fAtomic = true)
    00047             {
    00048             if (fAtomic)
    00049                 {
    00050                 set(lValue);
    00051                 }
    00052             else
    00053                 {
    00054                 poke(lValue);
    00055                 }
    00056             }
    00057
    00058
    00059     // ----- Atomic64 interface ---------------------------------------------
    00060
    00061     public:
    00062         /**
    00063         * Return the current value.
    00064         *
    00065         * @return the current value
    00066         */
    00067         int64_t get() const;
    00068
    00069         /**
    00070         * Return the assumed value without performing any memory
    00071         * synchronization. This value should not be trusted, but is suitable
    00072         * as an assumed value to be passed to update, which will validate if
    00073         * it is correct before allowing any associated change to occur.
    00074         *
    00075         * @return the assumed value
    00076         */
    00077         int64_t peek() const
    00078             {
    00079             return m_lAtomic;
    00080             }
    00081
    00082         /**
    00083         * Unconditionally set the value in a thread-safe manor.
    00084         *
    00085         * @param  lValue the new value
    00086         */
    00087         void set(int64_t lValue);
    00088
    00089         /**
    00090         * Unconditionally (and in a non thread-safe manor) set the value.
    00091         *
    00092         * @param  lValue the new value
    00093         */
    00094         void poke(int64_t lValue)
    00095             {
    00096             m_lAtomic = lValue;
    00097             }
    00098
    00099         /**
    00100         * Set the value so long as the current value matches the expected value.
    00101         *
    00102         * @param lAssume  the expected current value
    00103         * @param lValue   the new value
    00104         *
    00105         * @return the prior actual value, if the returned value
    00106         *         does is not equal to the supplied assumed
    00107         *         value then update did not take place
    00108         */
    00109         int64_t update(int64_t lAssume, int64_t lValue);
    00110
    00111         /**
    00112         * Set the value so long as the current value matches the expected value.
    00113         *
    00114         * This version of the update method supports conditionally performing
    00115         * the update in an unsafe manor. The unsafe update is performed
    00116         * without any form of synchronization and should only be used when it
    00117         * is known that the object is referenced by a single thread.
    00118         *
    00119         * @param lAssume  the expected current value
    00120         * @param lValue   the new value
    00121         * @param fAtomic  perform a safe update operation which can be used
    00122         *                 across threads
    00123         *
    00124         * @return the prior actual value, if the returned value
    00125         *         does is not equal to the supplied assumed
    00126         *         value then update did not take place
    00127         */
    00128         int64_t update(int64_t lAssume, int64_t lValue, bool fAtomic)
    00129             {
    00130             if (fAtomic)
    00131                 {
    00132                 return update(lAssume, lValue);
    00133                 }
    00134
    00135             int64_t lOld = peek();
    00136             if (lOld == lAssume)
    00137                 {
    00138                 poke(lValue);
    00139                 }
    00140             return lOld;
    00141             }
    00142
    00143         /**
    00144         * Adjust the NativeAtomic64 by the specified value.
    00145         *
    00146         * @param c      the amount to adjust the atomic by
    00147         * @param fSafe  to provide overflow protection
    00148         *
    00149         * @return the old value
    00150         */
    00151         int64_t postAdjust(int64_t c, bool fSafe = true)
    00152             {
    00153             int64_t cAssume;
    00154             int64_t cActual = peek();
    00155             do
    00156                 {
    00157                 cAssume = cActual;
    00158                 if (fSafe &&
    00159                     ((c > 0 && cAssume + c < cAssume) ||
    00160                      (c < 0 && cAssume + c > cAssume)))
    00161                     {
    00162                     // would overflow
    00163                     coh_throw_illegal_argument("NativeAtomic64 overflow");
    00164                     }
    00165                 cActual = update(cAssume, cAssume + c);
    00166                 }
    00167             while (cAssume != cActual);
    00168             return cAssume;
    00169             }
    00170
    00171         /**
    00172         * Adjust the NativeAtomic64 by the specified value.
    00173         *
    00174         * @param c  the amount to adjust the atomic by
    00175         * @param fSafe  to provide overflow protection
    00176         *
    00177         * @return the adjusted value
    00178         */
    00179         int64_t adjust(int64_t c, bool fSafe = true)
    00180             {
    00181             return postAdjust(c, fSafe) + c;
    00182             }
    00183
    00184
    00185     // ----- data members ---------------------------------------------------
    00186
    00187     private:
    00188         /**
    00189         * The atomically accessed value.
    00190         */
    00191         int64_t m_lAtomic;
    00192     };
    00193
    00194 COH_CLOSE_NAMESPACE2
    00195
    00196 #endif // COH_NATIVE_ATOMIC_WORD_HPP

Copyright © 2000, 2010, Oracle and/or its affiliates. All rights reserved.