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,282; 6-23-2010 14:03:16; /db/ztree/library/trees/xdc/xdc-v41x/src/packages/
224 */
225