Oracle® Fusion Middleware C++ API Reference for Oracle Coherence
12c (12.2.1.2.0)

E77779-01

coherence/lang/LifeCycle.hpp

00001 /*
00002 * LifeCycle.hpp
00003 *
00004 * Copyright (c) 2000, 2016, 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_LIFE_CYCLE_HPP
00017 #define COH_LIFE_CYCLE_HPP
00018 
00019 #include "coherence/lang/compatibility.hpp"
00020 
00021 COH_OPEN_NAMESPACE2(coherence,lang)
00022 
00023 
00024 /**
00025 * @internal
00026 *
00027 * LifeCycle is a data structure which maintains the reference counts and
00028 * other key pieces of information related to an Object's life.
00029 *
00030 * This class is used as a snapshot of the multiple NativeAtomic32s representing the
00031 * Object's life-cycle. It is therefore safe to perform multiple
00032 * unsynchronized reads/writes against the individual fields. The snapshot
00033 * can then be written back to the Object's NativeAtomic32 state.
00034 *
00035 * The specific layout of the bit-field is non-public and is subject to
00036 * change.
00037 *
00038 * @author mf 2008.01.28
00039 */
00040 struct LifeCycle
00041     {
00042     // ---- constructors ----------------------------------------------------
00043 
00044     /**
00045     * Construct a LifeCycle object from a raw int32_t, allowing
00046     * initialization from a NativeAtomic32.
00047     *
00048     * @param nState  the 32-bit representation of the state portion of LifeCycle
00049     * @param nRefs   the 32-bit representation of the refs portion of LifeCycle
00050     */
00051     LifeCycle(const int32_t nState = 0, const int32_t nRefs = 0)
00052         : state(nState), refs(nRefs)
00053         {
00054         }
00055 
00056     // ----- constants ------------------------------------------------------
00057 
00058     /**
00059     * Field identifiers.
00060     */
00061     typedef enum
00062         {
00063         life_state,               // Object life state
00064         escape_state,             // Object thread-escape state
00065         monitor_state,            // Monitor inflation state
00066         weak_reference_state,     // WeakReference inflation state
00067         handle_count,             // Handle reference count
00068         view_count,               // View reference count
00069         member_lock_state,        // read/write lock state
00070         member_lock_reader_count  // read/write lock active reader count
00071         } FieldId;
00072 
00073     /**
00074     * Monitor/WeakReference state constants.
00075     */
00076     typedef enum
00077         {
00078         constructing = 0, // pre onInit
00079         initializing = 1, // inside onInit()
00080         initialized  = 2, // post onInit()
00081         destructing  = 3  // in delete
00082         } LifeStage;
00083 
00084     /**
00085     * Monitor/WeakReference state constants.
00086     */
00087     typedef enum
00088         {
00089         flat      = 0, // lazy element does not exist
00090         inflating = 1, // lazy initialization in progress
00091         inflated  = 2  // lazy element is usable
00092         } InflationState;
00093 
00094     /**
00095     * Member read/write lock state.
00096     */
00097     typedef enum
00098         {
00099         gate_open    = 0, // read locks may be acquired
00100         gate_closing = 1, // no new read locks may be acquired
00101         gate_closed  = 2  // no read locks held, no new read locks may be acquired
00102         } MemberLockState;
00103 
00104     /**
00105     * The per-attachment count for escaped handles.
00106     */
00107     enum
00108         {
00109         escaped_increment = 2
00110         };
00111 
00112     /**
00113     * Limits.
00114     */
00115     enum
00116         {
00117         max_read_locks = 0xFF,   // maximum number of reader threads, before blocking
00118         max_handles    = 0x7FFF, // maximum number of handles to an Object
00119         max_views      = 0x7FFF  // maximum number of views to an Object
00120         };
00121 
00122 
00123     // ----- data members ---------------------------------------------------
00124 
00125     // Note this is broken into two 32 bit atomics rather then one 64 bit
00126     // atomic as performance testing (at least on Solaris x86) has demonstrated
00127     // that a 64 bit CAS in a 32 bit build is significantly slower then a
00128     // 32 bit CAS.  As most operations on LifeCycle don't access all parts of
00129     // the LifeCycle object breaking it up into two 32 bit structs provides
00130     // better performance.
00131 
00132     union State
00133         {
00134         State(const int32_t n = 0) : raw(n) {}
00135 
00136         /**
00137         * Bit-field representation of state.
00138         */
00139         struct
00140             {
00141             /**
00142             * The stage of life the object is in.
00143             */
00144             unsigned int nLifeStage : 2;
00145 
00146             /**
00147             * The thread-escape state of the object.
00148             */
00149             unsigned int fEscaped : 1;
00150 
00151             /**
00152             * The InflationState of the Object's monitor.
00153             *
00154             * @see InflationState
00155             */
00156             unsigned int nMonitor : 2;
00157 
00158             /**
00159             * The MemberLockState for the Object.
00160             *
00161             * @see MemberLockState
00162             */
00163             unsigned int nMemberWriteLockState: 2;
00164 
00165             /**
00166             * The number of member read locks held.
00167             *
00168             * A value of max_read_locks indicates that there are too many
00169             * readers and a new reader thread must wait even if the lock is
00170             * currently gate_open.
00171             */
00172             unsigned int cMemberReadLock : 8; // if changed update max_read_locks
00173             } value;
00174 
00175         // ----- operators ------------------------------------------------------
00176 
00177         /**
00178         * Compare two LifeCycles for equality.
00179         *
00180         * @param that  the LifeCycle to compare against
00181         *
00182         * @return true if the LifeCycles are equal
00183         */
00184         bool operator==(const LifeCycle::State& that)
00185             {
00186             return raw == that.raw;
00187             }
00188 
00189         /**
00190         * Compare two LifeCycles for equality.
00191         *
00192         * @param that  the LifeCycle to compare against
00193         *
00194         * @return true if the LifeCycles are not equal
00195         */
00196         bool operator!=(const LifeCycle::State& that)
00197             {
00198             return raw != that.raw;
00199             }
00200 
00201         /**
00202         * Automatic type conversion to int32_t, allowing a LifeCycle::State instance
00203         * to be stored within a NativeAtomic32.
00204         *
00205         * @return the int32_t representation of the LifeCycle::State
00206         */
00207         operator int32_t() const
00208             {
00209             return raw;
00210             }
00211 
00212         /**
00213         * Raw uninterpreted bit field representation of value
00214         */
00215         int32_t raw;
00216         } state;
00217 
00218     union Refs
00219         {
00220         Refs(const int32_t n = 0) : raw(n) {}
00221 
00222         /**
00223         * Bit-field representation of reference counts.
00224         */
00225         struct
00226             {
00227             /**
00228             * The InflationState of the Object's WeakReference.
00229             *
00230             * @see InflationState
00231             */
00232             unsigned int nWeakReference : 2;
00233 
00234             // Note: The maximum ref count limit is fairly low and if this ever becomes an
00235             // issue we can likely allievate it by having an overlflow space in another
00236             // int32_t.  When either of these hit their max value we could push a large
00237             // portion of their current value into the overflow space which would then only
00238             // need to be evaluated when these hit escaped_increment at which point we could
00239             // pull a portion of the overflow count back in to the atomic count.  That being
00240             // said this doesn't appear to be necessary at this point as the reference chaining
00241             // which doesn't impact these counters should give us quite a bit of headroom.
00242 
00243             /**
00244             * The number of Handles to the Object.
00245             *
00246             * A value of max_handles is considered invalid and is used to
00247             * detect roll over.
00248             */
00249             unsigned int cHandle : 15; // if changed update max_handles
00250 
00251             /**
00252             * The number of Views to the Object.
00253             *
00254             * A value of max_views is considered invalid and is used to
00255             * detect roll over.
00256             */
00257             unsigned int cView : 15; // if changed update max_views
00258             } value;
00259 
00260 
00261         // ----- operators ------------------------------------------------------
00262 
00263         /**
00264         * Compare two LifeCycles for equality.
00265         *
00266         * @param that  the LifeCycle to compare against
00267         *
00268         * @return true if the LifeCycles are equal
00269         */
00270         bool operator==(const LifeCycle::Refs& that)
00271             {
00272             return raw == that.raw;
00273             }
00274 
00275         /**
00276         * Compare two LifeCycles for equality.
00277         *
00278         * @param that  the LifeCycle to compare against
00279         *
00280         * @return true if the LifeCycles are not equal
00281         */
00282         bool operator!=(const LifeCycle::Refs& that)
00283             {
00284             return raw != that.raw;
00285             }
00286 
00287         /**
00288         * Automatic type conversion to int32_t, allowing a LifeCycle::Refs instance
00289         * to be stored within a NativeAtomic32.
00290         *
00291         * @return the int32_t representation of the LifeCycle::Refs
00292         */
00293         operator int32_t() const
00294             {
00295             return raw;
00296             }
00297 
00298         /**
00299         * Raw uninterpreted bit field representation of value
00300         */
00301         int32_t raw;
00302         } refs;
00303     };
00304 
00305 COH_CLOSE_NAMESPACE2
00306 
00307 #endif // COH_LIFE_CYCLE_HPP
Copyright © 2000, 2016, Oracle and/or its affiliates. All rights reserved.