1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
33
34
35 36 37
38 import xdc.runtime.ILogger;
39 import ti.uia.runtime.ILoggerSnapshot;
40 import xdc.rov.ViewInfo;
41 import xdc.runtime.Log;
42 import xdc.runtime.Diags;
43 import xdc.runtime.Types;
44 import xdc.runtime.Log;
45 import xdc.runtime.Error;
46
47 /*!
48 * ======== LoggerStreamer2 ========
49 * This general purpose logger is useful in situations where the application
50 * wants to manage the buffers used to store and transmit events. This
51 * includes managing the sending of the buffers to an instrumentation host
52 * (e.g. System Analyzer in CCS). The logger is named "LoggerStreamer2"
53 * because it is designed to enable the application to send a stream of
54 * packets containing UIA event data to the instrumentation host, and it is
55 * an enhancement of LoggerStreamer, allowing multiple instances.
56 *
57 * The difference between LoggerStreamer2 and LoggerStreamer, is that each
58 * LoggerStreamer2 instance has its own buffers for events logged to that
59 * instance. By including the header file, ti/uia/runtime/LogUC.h, you
60 * can specify the LoggerStreamer2 instance that you want the event logged
61 * to.
62 *
63 * The application is responsible for providing the buffers that
64 * LoggerStreamer2 loggers use. There are two ways to accomplish this.
65 * @p(blist)
66 * - Provide a prime callback function via the `{@link #primeFxn}`
67 * configuration parameter.
68 * - Call the `{@link #prime}` API once.
69 * @p
70 *
71 * The logger stores the events in a UIAPacket event packet structure that
72 * allows them to be sent directly to System Analyzer (e.g. via UDP), enabling
73 * efficient streaming of the data from the target to the host. The first
74 * four 32-bit words contain a `{@link UIAPacket#Hdr}` structure. This struct
75 * is used by the host (e.g. System Analyzer in CCS) to help decode the
76 * data (e.g. endianess, length of data, etc.). The `{@link UIAPacket#Hdr}`
77 * structure is initialized via the `{@link #initBuffer}` API. All buffers
78 * given to LoggerStreamer2 loggers (via priming or exchange) must be
79 * initialized via `{@link #initBuffer}`.
80 *
81 * The size of the buffer includes the UIAPacket_Hdr.
82 * LoggerStreamer2 treats the buffer as a UInt32 array, so the application
83 * must guarantee the buffers are aligned on word addresses. Alignment on
84 * cache line boundaries is recommended for best performance.
85 *
86 * When the buffer is filled, LoggerStreamer2 will hand it off to the
87 * application using an application-provided exchange function (`{@link #exchangeFxn}`).
88 * The exchange function must be of type `{@link #ExchangeFxnType}`. The
89 * exchange function takes the Log instance as a parameter.
90 *
91 * The exchange function is called within the context of a Log call, so the
92 * exchange function should be designed to be fast. Since the exchange
93 * function is called within the context of the Log call, LoggerStreamer2
94 * guarantees no Log records are dropped (i.e. LoggerStreamer2 is lossless).
95 *
96 * LoggerStreamer2 was designed to have as minimal impact as possible on an
97 * application when calling a Log function. There are several configuration
98 * parameters that allow an application to get the optimal performance in
99 * exchange for certain restrictions.
100 *
101 * Interrupts are disabled during the duration of the log call including
102 * when the exchange function is called. LoggerStreamer2 will ignore any
103 * log events generated during the exchangeFxn (e.g. posting a semaphore).
104 *
105 * NOTE: You can use LoggingSetup, but you will need to set the loggers
106 * first. LoggingSetup cannot create LoggerStreamer2 instances, since it
107 * does not know what config parameters to use. See example of LoggingSetup
108 * use below.
109 *
110 * @a(Examples)
111 * The following XDC configuration statements
112 * create a logger module, and assign it as the default logger for all
113 * modules.
114 *
115 * @p(code)
116 * var Defaults = xdc.useModule('xdc.runtime.Defaults');
117 * var Diags = xdc.useModule('xdc.runtime.Diags');
118 * var LoggerStreamer2 = xdc.useModule('ti.uia.sysbios.LoggerStreamer2');
119 *
120 * LoggerStreamer2.isTimestampEnabled = true;
121 *
122 * var loggerParams = new LoggerStreamer2.Params();
123 * loggerParams.primeFxn = '&prime';
124 * loggerParams.exchangeFxn = '&exchange';
125 * loggerParams.context = 0;
126 *
127 * Program.global.logger0 = LoggerStreamer2.create(loggerParams);
128 * Defaults.common$.logger = Program.global.logger0;
129 *
130 * loggerParams.context = 1;
131 * Program.global.logger1 = LoggerStreamer2.create(loggerParams);
132 *
133 * @p
134 *
135 * @a(Examples)
136 * The following C code demonstrates basic prime and exchange functions,
137 * and logging to different LoggerStreamer2 instances.
138 * A real implementation would send the buffer to an instrumentation
139 * host (e.g. System Analyzer in CCS) via a transport such as UDP.
140 *
141 * @p(code)
142 * #include <xdc/std.h>
143 * #include <xdc/runtime/Diags.h>
144 * #include <xdc/runtime/Log.h>
145 *
146 * #include <ti/uia/runtime/LogUC.h>
147 *
148 * UInt32 buffer_0[2][BUFSIZE_0];
149 * UInt32 buffer_1[2][BUFSIZE_1];
150 *
151 * Int main(Int argc, String argv[])
152 * {
153 * Log_iwriteUC0(logger0, LoggerStreamer2_L_test);
154 * Log_iwriteUC1(logger1, LoggerStreamer2_L_test, 0x1000);
155 * }
156 *
157 * Ptr prime(LoggerStreamer2_Object *log)
158 * {
159 * UInt32 id = (UInt32)LoggerStreamer2_getContext(log);
160 *
161 * if (id == 0) {
162 * LoggerStreamer2_initBuffer(buffer_0[0], 0);
163 * LoggerStreamer2_initBuffer(buffer_0[1], 0);
164 * return ((Ptr)buffer_0[0]);
165 * }
166 * if (id == 1) {
167 * LoggerStreamer2_initBuffer(buffer_1[0], 0);
168 * LoggerStreamer2_initBuffer(buffer_1[1], 0);
169 * return ((Ptr)(buffer_1[0]));
170 * }
171 *
172 * return (NULL); // Error
173 * }
174 *
175 * Ptr exchange(LoggerStreamer2_Object *log, Ptr *full)
176 * {
177 * UInt32 id = (UInt32)LoggerStreamer2_getContext(log);
178 *
179 * if (id == 0) {
180 * count_0++;
181 * // Ping-pong between the two buffers
182 * return ((Ptr*)buffer_0[count_0 & 1]);
183 * }
184 * if (id == 1) {
185 * count_1++;
186 * // Ping-pong between the two buffers
187 * return ((Ptr*)buffer_1[count_1 & 1]);
188 * }
189 * return (NULL); // Error
190 * }
191 * @p
192 *
193 * @a(Examples)
194 * The following XDC configuration statements show how to use LoggingSetup
195 * with LoggerStreamer2.
196 *
197 * @p(code)
198 *
199 * var LoggingSetup = xdc.useModule('ti.uia.sysbios.LoggingSetup');
200 * LoggingSetup.eventUploadMode = LoggingSetup.UploadMode_STREAMER2;
201 * LoggingSetup.mainLogger = Program.global.logger0;
202 * LoggingSetup.sysbiosLogger = Program.global.logger0;
203 *
204 * @p
205 */
206
207 @ModuleStartup
208 @Template("./LoggerStreamer2.xdt")
209 @CustomHeader
210 module LoggerStreamer2 inherits ILoggerSnapshot {
211
212 /*!
213 * ======== TransportType ========
214 * Used to specify the type of transport to use
215 *
216 * This enum is used by the instrumentation host to determine what
217 * the transport is. It is not used by the target code.
218 */
219 enum TransportType {
220 TransportType_UART = 0,
221 TransportType_USB = 1,
222 TransportType_ETHERNET = 2,
223 TransportType_CUSTOM = 3
224 };
225
226 /*!
227 * @_nodoc
228 * ======== ModuleView ========
229 */
230 metaonly struct ModuleView {
231 Bool isEnabled;
232 Bool isTimestampEnabled;
233 String transportType;
234 String customTransport;
235 }
236
237 /*!
238 * @_nodoc
239 * ======== InstanceView ========
240 */
241 metaonly struct InstanceView {
242 String label;
243 Bool enabled;
244 Int bufferSize;
245 String primeFunc;
246 String exchangeFunc;
247 SizeT maxEventSize;
248 UArg context;
249 }
250
251 metaonly struct RecordView {
252 Int sequence;
253 Long timestampRaw;
254 String modName;
255 String text;
256 Int eventId;
257 String eventName;
258 IArg arg0;
259 IArg arg1;
260 IArg arg2;
261 IArg arg3;
262 IArg arg4;
263 IArg arg5;
264 IArg arg6;
265 IArg arg7;
266 }
267
268 /*!
269 * @_nodoc
270 * ======== rovViewInfo ========
271 */
272 @Facet
273 metaonly config ViewInfo.Instance rovViewInfo =
274 ViewInfo.create({
275 viewMap: [
276 ['Module',
277 {
278 type: ViewInfo.MODULE,
279 viewInitFxn: 'viewInitModule',
280 structName: 'ModuleView'
281 }
282 ],
283 ['Instances',
284 {
285 type: ViewInfo.INSTANCE,
286 viewInitFxn: 'viewInitInstances',
287 structName: 'InstanceView'
288 }
289 ],
290 ['Records',
291 {
292 type: xdc.rov.ViewInfo.MODULE_DATA,
293 viewInitFxn: 'viewInitRecords',
294 structName: 'RecordView'
295 }
296 ]
297 ]
298 });
299
300 /*!
301 * ======== RtaData ========
302 * Data added to the RTA MetaData file to support System Analyzer
303 */
304 @XmlDtd metaonly struct RtaData {
305 Int instanceId;
306 }
307
308 /*!
309 * ======== ExchangeFxnType ========
310 * Typedef for the exchange function pointer.
311 * The LoggerStreamer2 object and a pointer to the full
312 * buffer are passed as arguments. If using the same exchange function
313 * for multiple LoggerStreamer2 instances, getContext() can be
314 * called within the exchange function to determine which buffer to
315 * exchange.
316 */
317 typedef Ptr (*ExchangeFxnType)(Object *, Ptr);
318
319 /*!
320 * ======== PrimeFxnType ========
321 * Typedef for the exchange function pointer.
322 */
323 typedef Ptr (*PrimeFxnType)(Object *);
324
325 /*!
326 * ======== transportType ========
327 * Transport used to send the records to an instrumentation host
328 *
329 * This parameter is used to specify the transport that the
330 * `{@link #exchangeFxn}` function will use to send the buffer to
331 * an instrumentation host (e.g. System Analyzer in CCS).
332 *
333 * This parameter is placed into the generated UIA XML file. The
334 * instrumentation host can use the XML file to help it auto-detect as
335 * much as possible and act accordingly.
336 *
337 * If the desired transport is not in the `{@link #TransportType}` enum,
338 * select `{@link #TransportType_CUSTOM}` and set the
339 * `{@link #customTransportType}` string with the desired string.
340 */
341 metaonly config TransportType transportType = TransportType_ETHERNET;
342
343 /*!
344 * ======== customTransportType ========
345 * Custom transport used to send the records to an instrumentation host
346 *
347 * If the desired transport is not in the `{@link #TransportType}` enum,
348 * and `{@link #transportType}` is set to `{@link #TransportType_CUSTOM}`,
349 * this parameter must be filled in with the correct transport name.
350 *
351 * If `{@link #transportType}` is NOT set to
352 * `{@link #TransportType_CUSTOM}`, this parameter is ignored.
353 */
354 config String customTransportType = null;
355
356 /*!
357 * ======== isTimestampEnabled ========
358 * Enable or disable logging the 64b local CPU timestamp
359 * at the start of each event
360 *
361 * Having a timestamp allows an instrumentation host (e.g.
362 * System Analyzer) to display events with the correct system time.
363 */
364 config Bool isTimestampEnabled = false;
365
366 /*!
367 * @_nodoc
368 * ======== isBadPacketDetectionEnabled ========
369 * Enable or disable checking that the event contents in the packet are
370 * properly formatted with no data errors
371 *
372 * If enabled, a breakpoint can be placed in the code to detect when
373 * a bad packet is found.
374 */
375 config Bool isBadPacketDetectionEnabled = false;
376
377 /*!
378 * ======== supportLoggerDisable ========
379 * Allow LoggerStreamer2 instances to be enabled/disabled during runtime.
380 */
381 config Bool supportLoggerDisable = false;
382
383 /*!
384 * ======== testForNullWrPtr ========
385 * Protect against log calls during the exchange function.
386 */
387 config Bool testForNullWrPtr = true;
388
389 /*!
390 * ======== statusLogger ========
391 * This configuration option is not supported by this logger and should
392 * be left null.
393 */
394 config xdc.runtime.IFilterLogger.Handle statusLogger = null;
395
396 /*!
397 * ======== level1Mask ========
398 * Mask of diags categories whose initial filtering level is Diags.LEVEL1
399 *
400 * See '{@link #level4Mask}' for details.
401 */
402 config Diags.Mask level1Mask = 0;
403
404 /*!
405 * ======== level2Mask ========
406 * Mask of diags categories whose initial filtering level is Diags.LEVEL2
407 *
408 * See '{@link #level4Mask}' for details.
409 */
410 config Diags.Mask level2Mask = 0;
411
412 /*!
413 * ======== level3Mask ========
414 * Mask of diags categories whose initial filtering level is Diags.LEVEL3
415 *
416 * See '{@link #level4Mask}' for details.
417 */
418 config Diags.Mask level3Mask = 0;
419
420 /*!
421 * ======== level4Mask ========
422 * Mask of diags categories whose initial filtering level is Diags.LEVEL4
423 *
424 * If 'filterByLevel' is true, then all LoggerBuf instances will filter
425 * incoming events based on their event level.
426 *
427 * The LoggerCircBuf module allows for specifying a different filter level
428 * for every Diags bit. These filtering levels are module wide; LoggerBuf
429 * does not support specifying the levels on a per-instance basis.
430 *
431 * The setFilterLevel API can be used to change the filtering levels at
432 * runtime.
433 *
434 * The default filtering levels are assigned using the 'level1Mask' -
435 * 'level4Mask' config parameters. These are used to specify, for each of
436 * the four event levels, the set of bits which should filter at that
437 * level by default.
438 *
439 * The default filtering configuration sets the filter level to
440 * Diags.LEVEL4 for all logging-related diags bits so that all events are
441 * logged by default.
442 */
443 config Diags.Mask level4Mask = Diags.ALL_LOGGING;
444
445 /*!
446 * ======== moduleToRouteToStatusLogger ========
447 * This configuration option is not supported by this logger and should
448 * be left unconfigured.
449 */
450 metaonly config String moduleToRouteToStatusLogger;
451
452 /*!
453 * ======== setModuleIdToRouteToStatusLogger ========
454 * This function is provided for compatibility with the ILoggerSnapshot
455 * interface only and simply returns when called.
456 */
457 @DirectCall
458 Void setModuleIdToRouteToStatusLogger(Types.ModuleId mid);
459
460 /*!
461 * @_nodoc
462 * ======== L_test ========
463 * Event used to benchmark write0.
464 */
465 config xdc.runtime.Log.Event L_test = {
466 mask: xdc.runtime.Diags.USER1,
467 msg: "Test"
468 };
469
470 /*!
471 * @_nodoc
472 * ======== E_badLevel ========
473 * Error raised if get or setFilterLevel receive a bad level value
474 */
475 config Error.Id E_badLevel = {
476 msg: "E_badLevel: Bad filter level value: %d"
477 };
478
479 /*!
480 * ======== A_invalidBuffer ========
481 * Assert raised when the buffer parameter is NULL
482 */
483 config xdc.runtime.Assert.Id A_invalidBuffer =
484 {msg: "LoggerStreamer2_create's buffer returned by primeFxn is NULL"};
485
486 instance:
487
488 /*!
489 * ======== create ========
490 * Create a `LoggerStreamer2` logger
491 */
492 create();
493
494 /*!
495 * ======== initBuffer ========
496 * Initializes the UIA packet header.
497 *
498 * This API is used to initialize a buffer before it is given to
499 * LoggerStreamer2 (via priming or exchange). The function initializes
500 * the UIAPacket portion of the buffer.
501 *
502 * @param(buffer) Pointer to the buffer that LoggerStreamer2 will
503 * fill with Log events. The first four 32-bit words
504 * will contain the UIAPacket_Hdr structure.
505 *
506 * @param(src) Used to initialize the UIA source address. For
507 * a single core device, this will generally be 0.
508 * For multi-core devices, it generally corresponds
509 * to the DNUM (on C6xxxx deviecs) or the Ipc
510 * MultiProc id. It must be unique for all cores and
511 * match the configuration in the System Analyzer
512 * endpoint configuration.
513 */
514 Void initBuffer(Ptr buffer, UInt16 src);
515
516 /*!
517 * ======== flush ========
518 * Force LoggerStreamer2 to call the exchange function
519 *
520 * This API makes LoggerStreamer2 call the application provided
521 * `{@link #exchangeFxn}` function if there are Log events present
522 * in the buffer.
523 *
524 * The call to the `{@link #exchangeFxn}` function is called in the
525 * context of the flush call.
526 */
527 Void flush();
528
529 /*!
530 * ======== prime =========
531 * If PrimeFxn is not set the user must call prime with the first buffer.
532 */
533 Bool prime(Ptr buffer);
534
535 /*!
536 * @_nodoc
537 * ======== validatePacket ========
538 * if isBadPacketDetectionEnabled is configured as true, this function is
539 * called prior to the exchange function being called.
540 *
541 * Returns null if the packet is ok, else returns the address of a string
542 * that describes the error.
543 */
544 @DirectCall
545 Char* validatePacket(UInt32 *writePtr, UInt32 numBytesInPacket);
546
547 /*!
548 * ======== context ========
549 * Context that can be used in exchangeFxn and primeFxn. This can be
550 * set to null if using a different exchangeFxn and primeFxn for each
551 * LoggerStreamer2 instance. The context can be changed at run-time
552 * via setContext().
553 */
554 config UArg context = null;
555
556 /*!
557 * ======== primeFxn ========
558 * Function pointer to the prime function.
559 */
560 config PrimeFxnType primeFxn = null;
561
562 /*!
563 * ======== exchangeFxn ========
564 * Function pointer to the exchange function.
565 *
566 * The exchange function must return a pointer to a buffer that is word
567 * aligned, initialized with a UIA header and the correct size. This is
568 * called in the context of a log so generally the exchange function
569 * should be quick to execute.
570 */
571 config ExchangeFxnType exchangeFxn = null;
572
573 /*!
574 * ======== instanceId ========
575 * Unique id of the LoggerStreamer2 instance.
576 */
577 config Int16 instanceId = 1;
578
579 /*!
580 * ======== maxEventSize ========
581 * The maximum event size (in Maus) that can be written with a single
582 * event. Must be less than or equal to bufSize - 64.
583 *
584 * The writeMemoryRange API checks to see if the event size required to
585 * write the block of memory is larger than maxEventSize. If so, it will
586 * split the memory range up into a number of smaller blocks and log the
587 * blocks using separate events with a common snapshot ID in order to
588 * allow the events to be collated and the original memory block to be
589 * reconstructed on the host.
590 */
591 config SizeT maxEventSize = 512;
592
593 /*!
594 * ======== bufSize ========
595 * LoggerStreamer2 instance's buffer size in MAUs (Minimum Addressable
596 * Units e.g. Bytes)
597 *
598 * NOTE: the buffer size must contain an integer number of 32b words
599 * (e.g. if a MAU = 1 byte, then the buffer size must be a multiple of 4).
600 * The buffer size must also be at least maxEventSize + 64.
601 */
602 config SizeT bufSize = 1400;
603
604 /*!
605 * ======== write0 ========
606 * Process a log event with 0 arguments and the calling address.
607 *
608 * Same as `write4` except with 0 arguments rather than 4.
609 * @see #write4()
610 */
611 @DirectCall
612 override Void write0(xdc.runtime.Log.Event evt,
613 xdc.runtime.Types.ModuleId mid);
614
615 /*!
616 * ======== write1 ========
617 * Process a log event with 1 arguments and the calling address.
618 *
619 * Same as `write4` except with 1 arguments rather than 4.
620 * @see #write4()
621 */
622 @DirectCall
623 override Void write1(xdc.runtime.Log.Event evt,
624 xdc.runtime.Types.ModuleId mid,
625 IArg a1);
626
627 /*!
628 * ======== write2 ========
629 * Process a log event with 2 arguments and the calling address.
630 *
631 * Same as `write4` except with 2 arguments rather than 4.
632 * @see #write4()
633 */
634 @DirectCall
635 override Void write2(xdc.runtime.Log.Event evt,
636 xdc.runtime.Types.ModuleId mid,
637 IArg a1, IArg a2);
638
639 /*!
640 * ======== write4 ========
641 * Process a log event with 4 arguments and the calling address.
642 *
643 * @see ILogger#write4()
644 */@DirectCall
645 override Void write4(xdc.runtime.Log.Event evt,
646 xdc.runtime.Types.ModuleId mid,
647 IArg a1, IArg a2, IArg a3, IArg a4);
648
649 /*!
650 * ======== write8 ========
651 * Process a log event with 8 arguments and the calling address.
652 *
653 * Same as `write4` except with 8 arguments rather than 4.
654 *
655 * @see #write4()
656 */
657 @DirectCall
658 override Void write8(xdc.runtime.Log.Event evt,
659 xdc.runtime.Types.ModuleId mid,
660 IArg a1, IArg a2, IArg a3, IArg a4,
661 IArg a5, IArg a6, IArg a7, IArg a8);
662
663 /*!
664 * ======== setFilterLevel ========
665 * Sets the level of detail that instances will log.
666 *
667 * Events with the specified level or higher will be logged, events
668 * below the specified level will be dropped.
669 *
670 * Events are filtered first by diags category, then by level. If an
671 * event's diags category is disabled in the module's diags mask, then it
672 * will be filtered out regardless of level. The event will not even be
673 * passed to the logger.
674 *
675 * This API allows for setting the filtering level for more than one
676 * diags category at a time. The mask parameter can be a single category
677 * or multiple categories combined, and the level will be set for all of
678 * those categories.
679 *
680 * @param(mask) The diags categories to set the level for
681 * @param(filterLevel) The new filtering level for the specified
682 * categories
683 */
684 @DirectCall
685 override Void setFilterLevel(Diags.Mask mask, Diags.EventLevel filterLevel);
686
687 /*!
688 * ======== getFilterLevel ========
689 * Returns the mask of diags categories currently set to the specified
690 * level.
691 *
692 * See '{@link #setFilterLevel}' for an explanation of level filtering.
693 */
694 @DirectCall
695 override Diags.Mask getFilterLevel(Diags.EventLevel level);
696
697 /*!
698 * ======== getBufSize ========
699 * Returns the Log's configured buffer size.
700 *
701 * @b(returns) Log's configured buffer size.
702 */
703 @DirectCall
704 SizeT getBufSize();
705
706 /*!
707 * ======== getContext ========
708 * Returns the Log's context
709 *
710 * @b(returns) context
711 */
712 @DirectCall
713 UArg getContext();
714
715 /*!
716 * ======== setContext ========
717 * Set the Log's context.
718 *
719 * @param(context) New value of Log's context
720 */
721 @DirectCall
722 Void setContext(UArg context);
723
724 internal:
725 metaonly config Int maxId = 0;
726
727
728 const Int WRITE0_SIZE_IN_BYTES = 8;
729 const Int WRITE1_SIZE_IN_BYTES = 12;
730 const Int WRITE2_SIZE_IN_BYTES = 16;
731 const Int WRITE4_SIZE_IN_BYTES = 24;
732 const Int WRITE8_SIZE_IN_BYTES = 40;
733
734 const Int TIMESTAMP = 8;
735 const Int NO_TIMESTAMP = 0;
736
737 /*!
738 * ======== filterOutEvent ========
739 */
740 @DirectCall
741 Bool filterOutEvent(Diags.Mask mask);
742
743 744 745 746
747 struct Module_State {
748 Bool enabled;
749 Diags.Mask level1;
750 Diags.Mask level2;
751 Diags.Mask level3;
752 Types.ModuleId moduleIdToRouteToStatusLogger;
753 };
754
755 struct Instance_State {
756 Bool enabled;
757 Int16 instanceId;
758 PrimeFxnType primeFxn;
759 ExchangeFxnType exchangeFxn;
760 UArg context;
761 Bool primeStatus;
762 UInt32 bufSize;
763 UInt32 *buffer;
764 UInt32 *write;
765 UInt32 *end;
766 SizeT maxEventSizeInBits32;
767 SizeT maxEventSize;
768
769 770 771 772
773 Int droppedEvents;
774 UInt16 seqNumber;
775 };
776 }