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