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