C++ Client API Reference for Oracle Coherence
14c (14.1.2.0.0)

F79659-03

coherence/lang/LifeCycle.hpp

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