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    @RomConsts
    64    
    65    module Gate {
    66    
    67        /*!
    68         *  ======== Ref ========
    69         *  Opaque reference to an allocated gate instance
    70         */
    71        @Encoded typedef xdc.runtime.IGateProvider.Handle Ref;
    72    
    73        /*!
    74         *  ======== allocInstance ========
    75         *  Allocate a gate instance from the current module's gate
    76         *
    77         *  This method is used by modules to create gates at runtime using
    78         *  the same `IGateProvider` that was used to create the module
    79         *  level gate.  The parameters passed to the `IGateProvider` are
    80         *  specified at configuration time via the
    81         * `{@link Types#Common$ Types.Common$.gateParams}`
    82         *  configuration parameter.
    83         *
    84         *  @param(eb)  `Error` block pointer
    85         *
    86         *      If `NULL`, any error in creating the instance will terminate
    87         *      the application.
    88         *
    89         *  @a(returns)
    90         *  Non-`NULL` instance handle is returned if no error occurs; otherwise
    91         *  an error is raised in `eb` and `NULL` is returned.
    92         *
    93         *  @see IGateProvider
    94         *  @see Error
    95         */
    96        @Macro Ref allocInstance(Error.Block *eb);
    97    
    98        /*!
    99         *  ======== freeInstance ========
   100         *  Free a gate instance to the current module's gatekeeper
   101         *
   102         *  @param(gate) non-`NULL` return value from a prior call to
   103         *               `{@link #allocInstance}`.
   104         *
   105         *  @see #allocInstance
   106         */
   107        @Macro Void freeInstance(Ref gate);
   108    
   109        /*!
   110         *  ======== enterInstance ========
   111         *  Enter a critical section protected by this gate instance
   112         *
   113         *  @param(gate) non-`NULL` return value from a prior call to
   114         *               `{@link #allocInstance}`.
   115         *
   116         *  @a(returns)
   117         *  Returns a "key" value that must be used to leave `gate`
   118         *  via `{@link #leaveInstance()}`.
   119         *
   120         */
   121        @Macro IArg enterInstance(Ref gate);
   122    
   123        /*!
   124         *  ======== enterModule ========
   125         *  Enter a critical section protected by the current module's gate
   126         *
   127         *  @a(returns)
   128         *  Returns a "key" value that must be used to leave the current module
   129         *  gate via `{@link #leaveModule()}`.
   130         *
   131         *  @see #leaveModule
   132         */
   133        @Macro IArg enterModule();
   134    
   135        /*!
   136         *  ======== enterSystem ========
   137         *  Enter a critical section protected by the global System gate
   138         *
   139         *  @a(returns)
   140         *  Returns a "key" value that must be used to leave the `{@link System}`
   141         *  gate via `{@link #leaveSystem()}`.
   142         *
   143         *  @see #leaveSystem
   144         */
   145        IArg enterSystem();
   146    
   147        /*!
   148         *  ======== leaveInstance ========
   149         *  Leave a critical section protected by a gate
   150         *
   151         *  @param(gate) non-`NULL` return value from a prior call to
   152         *               `{@link #allocInstance}`.
   153         *  @param(key) the return value of a prior call to
   154         *              `{@link #enterInstance}`
   155         *
   156         *  @see #enterInstance
   157         *  @see #allocInstance
   158         */
   159        @Macro Void leaveInstance(Ref gate, IArg key);
   160    
   161        /*!
   162         *  ======== leaveModule ========
   163         *  Leave a critical section protected by the current module's gate
   164         *
   165         *  @param(key) the return value of a prior call to `{@link #enterModule}`
   166         *
   167         *  @see #enterModule
   168         */
   169        @Macro Void leaveModule(IArg key);
   170    
   171        /*!
   172         *  ======== leaveSystem ========
   173         *  Leave a critical section protected by the global System gate
   174         *
   175         *  @param(key) the return value of a prior call to `{@link #enterSystem}`
   176         *
   177         *  @see #enterSystem
   178         */
   179        Void leaveSystem(IArg key);
   180    
   181        /*!
   182         *  ======== canBlock ========
   183         *  Check if the module level gate can block threads
   184         *
   185         *  This type of gate should never be called by clients that must never
   186         *  call a "blocking" RTOS operation; e.g., interrupt service
   187         *  routines
   188         *
   189         *  @a(returns) Returns `TRUE` if the underlying gatekeeper's gate can
   190         *              block
   191         */
   192        @Macro Bool canBlock();
   193    
   194        /*!
   195         *  ======== canBePreempted ========
   196         *  Check if the module level gate allows thread preemption
   197         *
   198         *  This type of gate should always be used by clients that protect
   199         *  a data structure whose updates require more than a small
   200         *  constant amount of time; e.g., update of a memory allocator's free
   201         *  list.
   202         *
   203         *  @a(returns) Returns `TRUE` if the underlying gate does not disable
   204         *              thread preemption.
   205         */
   206        @Macro Bool canBePreempted();
   207        
   208        /*!
   209         *  ======== staticAlloc ========
   210         *  Assign a statically-allocated gate instance to a state-object field 
   211         *
   212         *  This method is used to create a gate for static instance objects
   213         *  that require a gate.
   214         *
   215         *  @param(stateObj)    the state object for the instance being created
   216         *  @param(fldName)     a name of a field within the state object
   217         *
   218         *      This parameter names a field that will point to the created gate
   219         *      instance to be created. It is a caller's responsibility
   220         *      to ensure that the type of `fldName` is a handle to an 
   221         *      `IGateProvider` instance.
   222         */
   223        metaonly Void staticAlloc(Any stateObj, String fldName);
   224    }
   225    /*
   226     *  @(#) xdc.runtime; 2, 1, 0,0; 7-26-2016 11:46:12; /db/ztree/library/trees/xdc/xdc-B21/src/packages/
   227     */
   228