1    /* 
     2     *  Copyright (c) 2008 Texas Instruments. All rights reserved.
     3     *  This program and the accompanying materials are made available under the 
     4     *  terms of the Eclipse Public License v1.0 and Eclipse Distribution License
     5     *  v. 1.0 which accompanies this distribution. The Eclipse Public License is
     6     *  available at http://www.eclipse.org/legal/epl-v10.html and the Eclipse
     7     *  Distribution License is available at
     8     *  http://www.eclipse.org/org/documents/edl-v10.php.
     9     *
    10     *  Contributors:
    11     *      Texas Instruments - initial implementation
    12     * */
    13    package xdc.runtime;
    14    
    15    /*!
    16     *  ======== Gate ========
    17     *  Critical section support
    18     *
    19     *  Gates are used by clients to protect concurrent access to critical
    20     *  data structures.  Critical data structures are those that must be
    21     *  updated by at most one thread at a time.  All code that needs access
    22     *  to a critical data structure "enters" a gate (that's associated with the
    23     *  data structure) prior to accessing the data, modifies the data structure,
    24     *  then "leaves" the gate.
    25     *
    26     *  A gate is responsible for ensuring that at most one thread at a time
    27     *  can enter and execute "inside" the gate.  There are several
    28     *  implementations of gates, with different system executation times and
    29     *  latency tradoffs.  In addition, some gates must not be entered by certain
    30     *  thread types; e.g., a gate that is implemented via a "blocking" semaphore
    31     *  must not be called by an interrupt service routine (ISR).
    32     *
    33     *  A module can be declared "gated" by adding the `@Gated` attribute to the
    34     *  module's XDC spec file.  A "gated" module is assigned a module-level gate
    35     *  at the configuration time, and that gate is then used to protect critical
    36     *  sections in the module's target code. A module-level gate is an instance of
    37     *  a module implementing `{@link IGateProvider}` interface. However, gated
    38     *  modules do not access their module-level gates directly. They use this
    39     *  module to access transparently their module-level gate. 
    40     *
    41     *  Application code that is not a part of any module also has a
    42     *  module-level gate, configured through the module `{@link Main}`.
    43     *
    44     *  Each gated module can optionally create gates on an adhoc basis at
    45     *  runtime using the same gate module that was used to create the module
    46     *  level gate.
    47     *
    48     *  Gates that work by disabling all preemption while inside a gate can be
    49     *  used to protect data structures accessed by ISRs and other
    50     *  threads.  But, if the time required to update the data structure is not
    51     *  a small constant, this type of gate may violate a system's real-time
    52     *  requirements.
    53     *
    54     *  Gates have two orthogonal attributes: "blocking" and "preemptible".
    55     *  In general, gates that are "blocking" can not be use by code that is
    56     *  called by ISRs and gates that are not "preemptible" should only be used to
    57     *  to protect data manipulated by code that has small constant execution
    58     *  time.
    59     *
    60     */
    61    @CustomHeader
    62    @DirectCall
    63    module Gate {
    64    
    65        /*!
    66         *  ======== Ref ========
    67         *  Opaque reference to an allocated gate instance
    68         */
    69        @Encoded typedef xdc.runtime.IGateProvider.Handle Ref;
    70    
    71        /*!
    72         *  ======== allocInstance ========
    73         *  Allocate a gate instance from the current module's gate
    74         *
    75         *  This method is used by modules to create gates at runtime using
    76         *  the same `IGateProvider` that was used to create the module
    77         *  level gate.  The parameters passed to the `IGateProvider` are
    78         *  specified at configuration time via the
    79         * `{@link Types#Common$ Types.Common$.gateParams}`
    80         *  configuration parameter.
    81         *
    82         *  @param(eb)  `Error` block pointer
    83         *
    84         *      If `NULL`, any error in creating the instance will terminate
    85         *      the application.
    86         *
    87         *  @a(returns)
    88         *  Non-`NULL` instance handle is returned if no error occurs; otherwise
    89         *  an error is raised in `eb` and `NULL` is returned.
    90         *
    91         *  @see IGateProvider
    92         *  @see Error
    93         */
    94        @Macro Ref allocInstance(Error.Block *eb);
    95    
    96        /*!
    97         *  ======== freeInstance ========
    98         *  Free a gate instance to the current module's gatekeeper
    99         *
   100         *  @param(gate) non-`NULL` return value from a prior call to
   101         *               `{@link #allocInstance}`.
   102         *
   103         *  @see #allocInstance
   104         */
   105        @Macro Void freeInstance(Ref gate);
   106    
   107        /*!
   108         *  ======== enterInstance ========
   109         *  Enter a critical section protected by this gate instance
   110         *
   111         *  @param(gate) non-`NULL` return value from a prior call to
   112         *               `{@link #allocInstance}`.
   113         *
   114         *  @a(returns)
   115         *  Returns a "key" value that must be used to leave `gate`
   116         *  via `{@link #leaveInstance()}`.
   117         *
   118         */
   119        @Macro IArg enterInstance(Ref gate);
   120    
   121        /*!
   122         *  ======== enterModule ========
   123         *  Enter a critical section protected by the current module's gate
   124         *
   125         *  @a(returns)
   126         *  Returns a "key" value that must be used to leave the current module
   127         *  gate via `{@link #leaveModule()}`.
   128         *
   129         *  @see #leaveModule
   130         */
   131        @Macro IArg enterModule();
   132    
   133        /*!
   134         *  ======== enterSystem ========
   135         *  Enter a critical section protected by the global System gate
   136         *
   137         *  @a(returns)
   138         *  Returns a "key" value that must be used to leave the `{@link System}`
   139         *  gate via `{@link #leaveSystem()}`.
   140         *
   141         *  @see #leaveSystem
   142         */
   143        IArg enterSystem();
   144    
   145        /*!
   146         *  ======== leaveInstance ========
   147         *  Leave a critical section protected by a gate
   148         *
   149         *  @param(gate) non-`NULL` return value from a prior call to
   150         *               `{@link #allocInstance}`.
   151         *  @param(key) the return value of a prior call to
   152         *              `{@link #enterInstance}`
   153         *
   154         *  @see #enterInstance
   155         *  @see #allocInstance
   156         */
   157        @Macro Void leaveInstance(Ref gate, IArg key);
   158    
   159        /*!
   160         *  ======== leaveModule ========
   161         *  Leave a critical section protected by the current module's gate
   162         *
   163         *  @param(key) the return value of a prior call to `{@link #enterModule}`
   164         *
   165         *  @see #enterModule
   166         */
   167        @Macro Void leaveModule(IArg key);
   168    
   169        /*!
   170         *  ======== leaveSystem ========
   171         *  Leave a critical section protected by the global System gate
   172         *
   173         *  @param(key) the return value of a prior call to `{@link #enterSystem}`
   174         *
   175         *  @see #enterSystem
   176         */
   177        Void leaveSystem(IArg key);
   178    
   179        /*!
   180         *  ======== canBlock ========
   181         *  Check if the module level gate can block threads
   182         *
   183         *  This type of gate should never be called by clients that must never
   184         *  call a "blocking" RTOS operation; e.g., interrupt service
   185         *  routines
   186         *
   187         *  @a(returns) Returns `TRUE` if the underlying gatekeeper's gate can
   188         *              block
   189         */
   190        @Macro Bool canBlock();
   191    
   192        /*!
   193         *  ======== canBePreempted ========
   194         *  Check if the module level gate allows thread preemption
   195         *
   196         *  This type of gate should always be used by clients that protect
   197         *  a data structure whose updates require more than a small
   198         *  constant amount of time; e.g., update of a memory allocator's free
   199         *  list.
   200         *
   201         *  @a(returns) Returns `TRUE` if the underlying gate does not disable
   202         *              thread preemption.
   203         */
   204        @Macro Bool canBePreempted();
   205        
   206        /*!
   207         *  ======== staticAlloc ========
   208         *  Assign a statically-allocated gate instance to a state-object field 
   209         *
   210         *  This method is used to create a gate for static instance objects
   211         *  that require a gate.
   212         *
   213         *  @param(stateObj)    the state object for the instance being created
   214         *  @param(fldName)     a name of a field within the state object
   215         *
   216         *      This parameter names a field that will point to the created gate
   217         *      instance to be created. It is a caller's responsibility
   218         *      to ensure that the type of `fldName` is a handle to an 
   219         *      `IGateProvider` instance.
   220         */
   221        metaonly Void staticAlloc(Any stateObj, String fldName);
   222    }
   223    /*
   224     *  @(#) xdc.runtime; 2, 1, 0,0; 2-8-2017 14:15:54; /db/ztree/library/trees/xdc/xdc-D05/src/packages/
   225     */
   226