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 /*
14 * ======== LoggerBuf.xdc ========
15 *
16 */
17
18 /*!
19 * ======== LoggerBuf ========
20 * A logger which stores `Log` events in a buffer.
21 *
22 * This module provides a logger which captures `{@link Log}` events to a
23 * buffer in realtime. The `Log` events stored in the buffer are
24 * unformatted; `Log` event formatting is deferred until some client reads
25 * the raw event data from the buffer. You can use
26 * `{@link #flush LoggerBuf_flush()}` to process the `Log` events stored
27 * in the buffer and stream the formatted output to stdout
28 * (via `{@link System#printf}`). Alternatively, you can read a raw event
29 * (via `{@link #getNextEntry}`) and send it to another client that
30 * has the resources to format the event for display.
31 *
32 * The implementation of this logger is fast with minimal stack usage
33 * making it appropriate for a realtime application.
34 * This logger writes all `Log` events to a circular buffer. As a
35 * result, the execution time of all `Log` methods bound to this type
36 * of logger are deterministic (and quite short) because there are no
37 * additional memory allocation calls after the circular buffer was
38 * allocated.
39 *
40 * If this logger is used in a preemptive environment, then an appropriate
41 * gate must be assigned to the module. For example, if events are generated
42 * from an interrupt context, then a gate that disables interrupts
43 * must be used.
44 *
45 * @p(code) 46 * var LoggerBuf = xdc.useModule('xdc.runtime.LoggerBuf');
47 * LoggerBuf.common$.gate = ...some gate instance...
48 * @p 49 *
50 * If the buffer type is circular, the log buffer of size
51 * `{@link #numEntries}` contains the last `numEntries` of `Log` events. If
52 * the buffer type is fixed, the log buffer contains the first
53 * `numEntries` events.
54 *
55 * @a(Examples) 56 * Configuration example: The following XDC configuration statements
57 * create a logger instance, assign it as the default logger for all
58 * modules, and enable `USER1` logging in all modules of the package
59 * `my.pkg`. See the `{@link Diags#setMaskMeta Diags.setMaskMeta()}` function
60 * for details on specifying the module names.
61 *
62 * @p(code) 63 * var Defaults = xdc.useModule('xdc.runtime.Defaults');
64 * var Diags = xdc.useModule('xdc.runtime.Diags');
65 * var LoggerBuf = xdc.useModule('xdc.runtime.LoggerBuf');
66 *
67 * LoggerBuf.enableFlush = true;
68 * var LoggerBufParams = new LoggerBuf.Params();
69 * LoggerBufParams.exitFlush = true;
70 * Defaults.common$.logger = LoggerBuf.create(LoggerBufParams);
71 * Diags.setMaskMeta("my.pkg.%", Diags.USER1, Diags.RUNTIME_ON);
72 * @p 73 */
74
75 @ModuleStartup /* Initialize static instances */
76 @InstanceFinalize /* this mod has cleanup fxn when instances are deleted */
77 @InstanceInitError /* instance create can fail */
78 @Gated
79
80 module LoggerBuf inherits ILogger {
81
82 /*!
83 * ======== BufType ========
84 * Type of log buffer
85 */
86 enum BufType {
87 BufType_CIRCULAR, /*! The log buffer wraps, overwriting old entries */
88 BufType_FIXED /*! The log buffer halts collection when full */
89 };
90
91 metaonlystruct BasicView {
92 String label;
93 Int lastSerial;
94 Bool enabledFlag;
95 };
96
97 metaonlystruct RecordView {
98 Int serial;
99 Int timestamp;
100 String modName;
101 String text;
102 Int eventId;
103 String eventName;
104 IArg arg0;
105 IArg arg1;
106 IArg arg2;
107 IArg arg3;
108 }
109
110 /*!
111 * ======== rovViewInfo ========
112 * @_nodoc 113 */
114 @Facet
115 metaonlyconfig xdc.rov.ViewInfo.Instance rovViewInfo =
116 xdc.rov.ViewInfo.create({
117 viewMap: [
118 ['Basic',
119 {
120 type: xdc.rov.ViewInfo.INSTANCE,
121 viewInitFxn: 'viewInitBasic',
122 structName: 'BasicView'
123 }
124 ],
125 ['Records',
126 {
127 type: xdc.rov.ViewInfo.INSTANCE_DATA,
128 viewInitFxn: 'viewInitRecords',
129 structName: 'RecordView'
130 }
131 ]
132 ]
133 });
134
135 /*!
136 * ======== TimestampProxy ========
137 * User supplied time-stamp proxy
138 *
139 * This proxy allows `LoggerBuf` to use a timestamp server different
140 * from the server used by `{@link xdc.runtime.Timestamp}`. However, if
141 * not supplied by a user, this proxy defaults to whichever timestamp
142 * server is used by `Timestamp`.
143 */
144 proxy TimestampProxy inherits ITimestampClient;
145
146 /*!
147 * ======== enableFlush ========
148 * Flush all logs at system exit
149 */
150 config Bool enableFlush = false;
151
152 /*!
153 * ======== flushAll ========
154 * Flush logs of all instances of `LoggerBuf`
155 *
156 * The user is responsible for making sure that no `LoggerBuf` instances
157 * are created or deleted while in this API, by using an appropriate gate.
158 */
159 Void flushAll();
160
161 /*!
162 * ======== flushAllInternal ========
163 * @_nodoc 164 */
165 Void flushAllInternal(Int stat);
166
167 instance:
168 /*!
169 * ======== create ========
170 * Create a `LoggerBuf` logger
171 *
172 * @see LoggerBuf#Params
173 */
174 create();
175
176 /*!
177 * ======== numEntries ========
178 * Number of entries in buffer
179 *
180 * Each entry is large enough to store one `Log` event containing up to
181 * 4 optional arguments. Events containing more than 4 arguments (such
182 * as those from `{@link Log#write5}`) use 2 entries.
183 *
184 * `numEntries` must be a power of 2.
185 */
186 config Int numEntries = 64;
187
188 /*!
189 * ======== bufType ========
190 * Log buffer type
191 */
192 config BufType bufType = BufType_CIRCULAR;
193
194 /*!
195 * ======== exitFlush ========
196 * Flush log at system exit
197 *
198 * Only used when module parameter `{@link #enableFlush}` is `true`.
199 */
200 config Bool exitFlush = false;
201
202 /*!
203 * ======== bufSection ========
204 * Section name for the buffer managed by the static instance.
205 *
206 * The default section is the 'dataSection' in the platform.
207 */
208 metaonlyconfig String bufSection = null;
209
210 /*!
211 * ======== bufHeap ========
212 * The heap that contains the `Log` buffer for dynamic instances.
213 *
214 * The default value `null` means the buffer will be allocated from
215 * the `{@link Memory#defaultHeapInstance}` heap.
216 */
217 config IHeap.Handle bufHeap = null;
218
219 /*!
220 * ======== enable ========
221 * Enable a log
222 *
223 * @a(returns) 224 * The function returns the state of the log (`TRUE` if enabled,
225 * `FALSE` if disabled) before the call. That allow clients to restore
226 * the previous state.
227 */
228 Bool enable();
229
230 /*!
231 * ======== disable ========
232 * Disable a log
233 *
234 * Events written to a disabled log are silently discarded.
235 *
236 * @a(returns) 237 * The function returns the state of the log (`TRUE` if enabled,
238 * `FALSE` if disabled) before the call. That allow clients to restore
239 * the previous state.
240 */
241 Bool disable();
242
243 /*!
244 * ======== reset ========
245 * Reset a log to empty state and enable it
246 *
247 * @a(WARNING) This method is not synchronized with other instance
248 * methods and, as a result, it must never be called when there is a
249 * chance that another instance method is currently in operation or
250 * when another method on this instance may preempt this call.
251 */
252 Void reset();
253
254 /*!
255 * ======== flush ========
256 * Read, clear, and output the contents of the log
257 *
258 * This method reads, clears, and "prints" each `Log` event (via
259 * `{@link System#printf}`) in the log.
260 */
261 Void flush();
262
263 /*!
264 * ======== getNextEntry ========
265 * Fills the passed `{@link Log#EventRec}` with the next entry in the log.
266 *
267 * This function is used to read and clear `Log` events from the
268 * buffer maintained by the `LoggerBuf` instance. The `Log` event can
269 * then be transmitted and displayed on a host.
270 *
271 * A read pointer is maintained in the `LoggerBuf` instance and
272 * points to the next record to read. Entries are not necessarily
273 * returned in chronological order, since buffers of type
274 * `{@link #BufType_CIRCULAR}` can wrap.
275 *
276 * @param(evtRec) pointer to a supplied `EventRec` object where the next
277 * entry in the log is copied to
278 *
279 * @a(returns) 280 * This function reports the number of entries actually read. The only
281 * values that can be returned are:
282 * @p(blist) 283 * - 0 no more entries to read
284 * - 1 or 2 read a complete entry written by `write4` or `write8`
285 * - -1 cleared an incomplete/overwritten entry, more entries to read
286 */
287 Int getNextEntry(Log.EventRec *evtRec);
288
289 internal:
290
291 const Int8 FULL = -1;
292 const Int8 WRAP = 0;
293
294 const Int8 NEXT = 1;
295
296 struct Entry {
297 Types.Timestamp64 tstamp;
298 Bits32 serial;
299 Types.Event evt;
300 IArg arg1;
301 IArg arg2;
302 IArg arg3;
303 IArg arg4;
304 };
305
306 struct Instance_State {
307 IHeap.Handle bufHeap;
308 Entry entryArr[];
309 Entry *curEntry;
310 Entry *endEntry;
311 Entry *readEntry;
312 Bits32 serial;
313 Int16 numEntries;
314 Int8 advance;
315 Bool enabled;
316 Bool flush;
317 };
318
319 }
320 /*
321 * @(#) xdc.runtime; 2, 0, 0, 0,207; 6-9-2009 20:10:18; /db/ztree/library/trees/xdc-t50x/src/packages/
322 */
323