1 /*!
2 * ======== Registry ========
3 * Register modules that are not statically configured
4 *
5 * This module provides a mechanism by which legacy C code can have its own
6 * module logging support, including having a name and its own diags mask.
7 *
8 * Without the `Registry`, all logging done by legacy C code is handled by the
9 * `xdc.runtime.Main` module. This means that all `{@link Log}` events will
10 * be marked as coming from "`xdc.runtime.Main`", and there is only a single
11 * diagnostics mask for the runtime control of logging across all legacy C
12 * code. The `Registry` module allows legacy C code to have the same granular
13 * control over logging as statically defined RTSC modules.
14 *
15 * To use the `Registry` module, legacy code must define the symbol
16 * `Registry_CURDESC` to be the name of an externally declared
17 * `Registery_Desc` structure. This symbol must be defined before the
18 * inclusion of any `xdc/runtime` header files. If any `xdc/runtime` header
19 * files are included before the definition of this symbol, the `Registry`
20 * module may not function properly.
21 *
22 * Note: by defining this symbol on the compile line, rather than in the
23 * file, one can easily compile code to be used in one of two environments:
24 * @p(nlist) 25 * - a fixed configuration environment where modules are registered
26 * via `{@link #addModule Registry_addModule()}`, or
27 *
28 * - a "normal" configurable environment in which this code is
29 * assumed to be part of the `{@link Main}` module.
30 * @p 31 * The `Registry_Desc` structure must then be registered by calling
32 * `{@link #addModule Registry_addModule()}`. The structure is typically
33 * registered and initialized within `main()`.
34 *
35 * For example:
36 *
37 * @p(code) 38 * //Define the required symbol, Registry_CURDESC, to this file's
39 * //Registry_Desc object
40 * #define Registry_CURDESC mainDesc
41 * #include <xdc/runtime/Registry.h>
42 *
43 * //Declare the Registry_Desc object, the name is unimportant
44 * Registry_Desc mainDesc;
45 *
46 * Int main(Int argc, String argv[]) {
47 *
48 * //Register this file as a module "main"
49 * Registry_addModule(&mainDesc, "main");
50 * @p 51 *
52 * Once registered, the legacy code may call `{@link Log}` APIs without any
53 * other change and the formatted `Log` events will show as coming from the
54 * registered modules. Also, the logging by the legacy code is now filtered
55 * by its own diagnostic mask. The bits of this mask can be set using
56 * `{@link Diags#setMask Diags_setMask}`.
57 *
58 * Continuing the previous example:
59 * @p(code) 60 * //Initialize the legacy code's diags mask to enable USER1.
61 * Diags_setMask("main=1");
62 * @p 63 *
64 * All events logged by registered modules will be sent to the logger
65 * configured for the `Registry` module. For example, to configure the
66 * logger for use by all modules managed by `Registry`:
67 * @p(code) 68 * Registry.common$.logger = LoggerBuf.create();
69 * @p 70 *
71 * Since the registered modules are not known until runtime, it is not
72 * possible to statically configure the diagnostics masks for individual
73 * registered modules. However, it is possible to configure diagnostics
74 * categories to be permanently off or on for ALL registered modules. This
75 * is done by configuring the diagnostic mask for the `Registry` module.
76 * Diagnostic categories set to `{@link Diags#ALWAYS_OFF Diags.ALWAYS_OFF}`
77 * will be permanently off for all `Registry` modules. Categories set to
78 * `{@link Diags#ALWAYS_ON Diags.ALWAYS_ON}` will be permanently on for all
79 * modules managed by `Registry`.
80 *
81 * In order to enable runtime configuration of individual `Registry` module
82 * masks, all relevant diagnostic categories must be set to
83 * `{@link Diags#RUNTIME_OFF Diags.RUNTIME_OFF}` or
84 * `{@link Diags#RUNTIME_ON Diags.RUNTIME_ON}` in the `Registry` module's
85 * mask.
86 */
87 @CustomHeader
88 @DirectCall
89 module Registry
90 {
91 /*!
92 * ======== RegisteredModuleView ========
93 * @_nodoc 94 * View element for the 'Registered Modules' ROV view.
95 */
96 metaonlystruct RegisteredModuleView {
97 String modName;
98 Int id;
99 String mask;
100 Ptr descAddr;
101 }
102
103 /*!
104 * ======== rovViewInfo ========
105 * @_nodoc 106 */
107 @Facet
108 metaonlyconfig xdc.rov.ViewInfo.Instance rovViewInfo =
109 xdc.rov.ViewInfo.create({
110 viewMap: [
111 ['Registered Modules',
112 {
113 type: xdc.rov.ViewInfo.MODULE_DATA,
114 viewInitFxn: 'viewInitRegisteredModules',
115 structName: 'RegisteredModuleView'
116 }
117 ]
118 ]
119 });
120
121 /*!
122 * ======== Result ========
123 * Status codes
124 */
125 enum Result {
126 SUCCESS, /*! The module was added successfully */
127 ALLOC_FAILED, /*! reserved */
128 ALREADY_ADDED, /*! The module has already been added or another
129 * module with the same name is present
130 */
131 ALL_IDS_USED /*! No more module ids available for new modules */
132 };
133
134 /*!
135 * ======== RegDesc ========
136 * Registry module descriptor
137 */
138 typedef Types.RegDesc Desc;
139
140 /*!
141 * ======== addModule ========
142 * Add a runtime module to the registry with the specified name
143 *
144 * The `desc` parameter and the `modName` string provided must both be
145 * permanent since the `Registry` will maintain references to both of
146 * these.
147 *
148 * @param(desc) non-`NULL` pointer to a `{#Desc Registry_Desc}`
149 * structure.
150 * @param(modName) non-`NULL` string name of the module being registered.
151 *
152 * @a(returns) 153 * `Registry_addModule` returns one of the following
154 * `{@link #Result Result}` status values indicating success or the
155 * cause of failure:
156 * @p(blist) 157 * - `{@link #SUCCESS SUCCESS}`
158 * - `{@link #ALREADY_ADDED ALREADY_ADDED}`
159 * - `{@link #ALL_IDS_USED ALL_IDS_USED}` There are a total of 16,384 - 1
160 * module ids available for use by `Registry`.
161 * @p 162 */
163 Result addModule(Desc *desc, CString modName);
164
165 /*!
166 * ======== findByName ========
167 * Find the registered module with the given name
168 *
169 * @param(modName) non-`NULL` string name of a registered module
170 *
171 * @a(returns) 172 * If the name `modName` is registered via
173 * `{@link #addModule Registry_addModule()}`, this function
174 * returns the pointer to the registered `Registry_Desc` structure;
175 * otherwise it returns `NULL`.
176 */
177 Desc *findByName(CString modName);
178
179 /*!
180 * ======== findByNamePattern ========
181 * @_nodoc 182 * Find all registered modules matching the specified pattern.
183 *
184 * This API is intended for use by Diags_setMask.
185 *
186 * The name pattern can be an exact module name or it can contain '%'
187 * as a wildcard. The `len` parameter is the string length of the pattern.
188 *
189 * This function returns one module at a time, but can be called
190 * repeatedly to find all modules matching the pattern. On the first
191 * call, pass `NULL` as the `prev` parameter. In all following calls,
192 * pass the last returned descriptor. This function returns `NULL` when
193 * it can't find any more modules matching the name pattern.
194 */
195 Desc *findByNamePattern(CString namePat, Int len, Desc *prev);
196
197 /*!
198 * ======== findById ========
199 * Find registered module's descriptor from its module ID
200 *
201 * @param(mid) any module id
202 *
203 * @a(returns) 204 * If the ID `mid` is registered via
205 * `{@link #addModule Registry_addModule()}`, this function
206 * returns the pointer to the registered `Registry_Desc` structure;
207 * otherwise it returns `NULL`.
208 */
209 Desc *findById(Types.ModuleId mid);
210
211 /*!
212 * ======== getMask ========
213 * Get the specified module's diagnostic mask
214 *
215 * @param(modName) non-`NULL` string name of a registered module
216 * @param(mask) non-`NULL` pointer to a mask to be initialized
217 * to the the current state of the diagnostics mask
218 * associated with `modName`
219 *
220 * @a(returns) 221 * The function returns `TRUE` if `name` identifies a registered module;
222 * otherwise, it return `FALSE`.
223 */
224 Bool getMask(CString name, Types.DiagsMask *mask);
225
226 /*!
227 * ======== isMember ========
228 * Determines if the specified module ID belongs to a registered module
229 *
230 * @param(mid) any module id
231 *
232 * @a(returns) 233 * This function returns `TRUE` if and only if the specified module id
234 * is a valid `Registry` module id. It does not search registered
235 * module ids, but simply checks if the id is within the range of valid
236 * `Registry` module ids.
237 */
238 Bool isMember(Types.ModuleId mid);
239
240 /*!
241 * ======== getNextModule ========
242 * Scan the current list of registered modules
243 *
244 * This function used to scan the list of all `Registry_Desc` structures
245 * currently being managed by the `Registry` module.
246 *
247 * @param(desc) optionally `NULL` pointer to a `Registry_Desc`
248 * structure. If `desc` is `NULL`, a pointer to the
249 * first structure is returned. If `desc` is non-`NULL`
250 * and equal to a previous return value of this function,
251 * a pointer to the "next" `Registry_Desc` structure
252 * is returned.
253 *
254 * @a(returns) 255 * This function returns a non-`NULL` pointer to one of the
256 * `Registry_Desc` structures added via `Registry_Desc` structures or
257 * `NULL` in the case that
258 * @p(blist) 259 * - there are no more module's in the list after `desc`, or
260 * - there are no modules registered
261 * @p 262 */
263 Desc *getNextModule(Desc *desc);
264
265 /*!
266 * ======== getModuleName ========
267 * Get the module name associated with a specified module descriptor
268 *
269 * @param(desc) non-`NULL` pointer to a `{#Desc Registry_Desc}`
270 * structure.
271 *
272 * @a(returns) 273 * If the specified module descriptor has been initialized via a
274 * successful call to `{@link #addModule Registry_addModule()}`, this
275 * function returns the module name passed `Registry_addModule()`;
276 * otherwise, its return value is indeterminate.
277 */
278 CString getModuleName(Desc *desc);
279
280 /*!
281 * ======== getModuleId ========
282 * Get the module id associated with a specified module descriptor
283 *
284 * @param(desc) non-`NULL` pointer to a `{#Desc Registry_Desc}`
285 * structure.
286 *
287 * @a(returns) 288 * If the specified module descriptor has been initialized via a
289 * successful call to `{@link #addModule Registry_addModule()}`, this
290 * function returns the module id assigned by `Registry_addModule()`;
291 * otherwise, its return value is indeterminate.
292 */
293 Types.ModuleId getModuleId(Desc *desc);
294
295 internal:
296
297 Desc *findByNameInList(CString name, Desc *listHead);
298 Void newModule(Desc *desc, CString modName);
299 Bool matchPattern(CString pattern, Int len, CString modName);
300
301 /* Functions for accessing the Registry at ROV-time. */
302 function isMemberRov(modId);
303 function lookupModIdRov(modId);
304
305 /*
306 * ======== Module_State ========
307 */
308 struct Module_State {
309 Desc *listHead;
310 Types.ModuleId curId;
311 }
312 }
313 /*
314 * @(#) xdc.runtime; 2, 1, 0,0; 4-24-2015 12:34:13; /db/ztree/library/trees/xdc/xdc-A71/src/packages/
315 */
316