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     *  ======== LoggerBuf ========
    19     *  A logger which stores `Log` events in a buffer.
    20     *
    21     *  This module provides a logger which captures `{@link Log}` events to a
    22     *  buffer in realtime. The `Log` events stored in the buffer are
    23     *  unformatted; `Log` event formatting is deferred until some client reads
    24     *  the raw event data from the buffer. You can use
    25     *  `{@link #flush LoggerBuf_flush()}` to process the `Log` events stored
    26     *  in the buffer and stream the formatted output to stdout
    27     *  (via `{@link System#printf}`).  Alternatively, you can read a raw event
    28     *  (via `{@link #getNextEntry}`) and send it to another client that
    29     *  has the resources to format the event for display.
    30     *
    31     *  The implementation of this logger is fast with minimal stack usage
    32     *  making it appropriate for a realtime application.
    33     *  This logger writes all `Log` events to a circular buffer.  As a
    34     *  result, the execution time of all `Log` methods bound to this type
    35     *  of logger are deterministic (and quite short) because there are no
    36     *  additional memory allocation calls after the circular buffer was
    37     *  allocated.
    38     *
    39     *  If this logger is used in a preemptive environment, then an appropriate
    40     *  gate must be assigned to the module. For example, if events are generated
    41     *  from an interrupt context, then a gate that disables interrupts
    42     *  must be used.
    43     *
    44     *  @p(code)
    45     *  var LoggerBuf = xdc.useModule('xdc.runtime.LoggerBuf');
    46     *  LoggerBuf.common$.gate = ...some gate instance...
    47     *  @p
    48     *
    49     *  If the buffer type is circular, the log buffer of size
    50     *  `{@link #numEntries}` contains the last `numEntries` of `Log` events. If
    51     *  the buffer type is fixed, the log buffer contains the first
    52     *  `numEntries` events.
    53     *
    54     *  LoggerBuf supports routing of 'STATUS' events (errors and warnings) to a
    55     *  separate ILogger instance. This is helpful in preserving these critical
    56     *  events, which may otherwise be overwritten by lower priority events. This 
    57     *  feature is disabled by default. See {@link #statusLogger}.
    58     *
    59     *  LoggerBuf implements the {@link IFilterLogger} interface and 
    60     *  optionally supports filtering of events based on their detail level. This
    61     *  feature is disabled by default. See {@link IFilterLogger}.
    62     *
    63     *  @a(Examples)
    64     *  Configuration example: The following XDC configuration statements
    65     *  create a logger instance, assign it as the default logger for all
    66     *  modules, and enable `USER1` logging in all modules of the package
    67     *  `my.pkg`. See the `{@link Diags#setMaskMeta Diags.setMaskMeta()}` function
    68     *  for details on specifying the module names.
    69     *
    70     *  @p(code)
    71     *  var Defaults = xdc.useModule('xdc.runtime.Defaults');
    72     *  var Diags = xdc.useModule('xdc.runtime.Diags');
    73     *  var LoggerBuf = xdc.useModule('xdc.runtime.LoggerBuf');
    74     *
    75     *  LoggerBuf.enableFlush = true;
    76     *  var LoggerBufParams = new LoggerBuf.Params();
    77     *  LoggerBufParams.exitFlush = true;
    78     *  Defaults.common$.logger = LoggerBuf.create(LoggerBufParams);
    79     *  Diags.setMaskMeta("my.pkg.%", Diags.USER1, Diags.RUNTIME_ON);
    80     *  @p
    81     */
    82    
    83    @ModuleStartup      /* Initialize static instances */
    84    @InstanceFinalize   /* this mod has cleanup fxn when instances are deleted */
    85    @InstanceInitError  /* instance create can fail */
    86    @Gated
    87    
    88    module LoggerBuf inherits IFilterLogger {
    89    
    90        /*!
    91         *  ======== BufType ========
    92         *  Type of log buffer
    93         */
    94        enum BufType {
    95            BufType_CIRCULAR,  /*! The log buffer wraps, overwriting old entries */
    96            BufType_FIXED      /*! The log buffer halts collection when full */
    97        };
    98    
    99        metaonly struct BasicView {
   100            String label;
   101            Int lastSerial;
   102            Int numEntries;
   103            String type;
   104            Bool enabledFlag;  
   105        };
   106    
   107        metaonly struct RecordView {
   108            Int     serial;
   109            Long    timestampRaw;
   110            String  modName;
   111            String  text;
   112            Int     eventId;
   113            String  eventName;
   114            IArg    arg0;
   115            IArg    arg1;
   116            IArg    arg2;
   117            IArg    arg3;
   118            IArg    arg4;
   119            IArg    arg5;
   120            IArg    arg6;
   121            IArg    arg7;
   122        }
   123    
   124        /*!
   125         *  ======== rovViewInfo ========
   126         *  @_nodoc
   127         */
   128        @Facet
   129        metaonly config xdc.rov.ViewInfo.Instance rovViewInfo = 
   130            xdc.rov.ViewInfo.create({
   131                viewMap: [
   132                    ['Basic', 
   133                        {
   134                            type: xdc.rov.ViewInfo.INSTANCE,
   135                            viewInitFxn: 'viewInitBasic',
   136                            structName: 'BasicView'
   137                        }
   138                    ],
   139                    ['Records', 
   140                        {
   141                            type: xdc.rov.ViewInfo.INSTANCE_DATA,
   142                            viewInitFxn: 'viewInitRecords',
   143                            structName: 'RecordView'
   144                        }
   145                    ]
   146                ]
   147            });
   148    
   149        /*!
   150         *  ======== StopModeData ========
   151         *  This data is added to the RTA MetaData file to support stop mode RTA.
   152         */
   153        @XmlDtd metaonly struct StopModeData {
   154            String bufferSymbol;
   155            Int bufferSize;
   156        }
   157        
   158        /*! Error raised if get or setFilterLevel receive a bad level value */
   159        config Error.Id E_badLevel = 
   160            {msg: "E_badLevel: Bad filter level value: %d"};
   161        
   162        /*!
   163         *  ======== TimestampProxy ========
   164         *  User supplied time-stamp proxy
   165         *
   166         *  This proxy allows `LoggerBuf` to use a timestamp server different
   167         *  from the server used by `{@link xdc.runtime.Timestamp}`. However, if
   168         *  not supplied by a user, this proxy defaults to whichever timestamp
   169         *  server is used by `Timestamp`.
   170         */
   171        proxy TimestampProxy inherits ITimestampClient;
   172    
   173        /*!
   174         *  ======== enableFlush ========
   175         *  Flush all logs at system exit
   176         */
   177        config Bool enableFlush = false;
   178        
   179        /*!
   180         *  ======== statusLogger ========
   181         *  Route all 'STATUS' (error and warning) events to this logger.
   182         *
   183         *  If a statusLogger is specified, all LoggerBuf instances will check to 
   184         *  determine if any of the events they receive are errors or warnings (if 
   185         *  their diags mask includes the STATUS category), and will log these 
   186         *  events to the statusLogger. 
   187         *
   188         *  Error events are infrequent, but it's generally critical that they be 
   189         *  seen. In a typical system, non-error events easily outnumber any error
   190         *  events, and the logger is likely to wrap, overwriting any error events.
   191         *  To protect these events from being overwritten and lost, they can be 
   192         *  sent to their own separate logger to preserve them.
   193         *
   194         *  The default value is null, indicating that the STATUS events will just
   195         *  be logged by the logger they were sent to.
   196         */
   197        config ILogger.Handle statusLogger = null;
   198        
   199        /*!
   200         *  ======== level1Mask ========
   201         *  Mask of diags categories whose initial filtering level is Diags.LEVEL1
   202         *
   203         *  See '{@link #level4Mask}' for details.
   204         */
   205        config Diags.Mask level1Mask = 0;
   206        
   207        /*!
   208         *  ======== level2Mask ========
   209         *  Mask of diags categories whose initial filtering level is Diags.LEVEL2
   210         *
   211         *  See '{@link #level4Mask}' for details.
   212         */
   213        config Diags.Mask level2Mask = 0;
   214        
   215        /*!
   216         *  ======== level3Mask ========
   217         *  Mask of diags categories whose initial filtering level is Diags.LEVEL3
   218         *
   219         *  See '{@link #level4Mask}' for details.
   220         */
   221        config Diags.Mask level3Mask = 0;
   222        
   223        /*!
   224         *  ======== level4Mask ========
   225         *  Mask of diags categories whose initial filtering level is Diags.LEVEL4
   226         *
   227         *  If 'filterByLevel' is true, then all LoggerBuf instances will filter
   228         *  incoming events based on their event level.
   229         *
   230         *  The LoggerBuf module allows for specifying a different filter level for
   231         *  every Diags bit. These filtering levels are module wide; LoggerBuf does
   232         *  not support specifying the levels on a per-instance basis.
   233         *
   234         *  The setFilterLevel API can be used to change the filtering levels at 
   235         *  runtime.
   236         *
   237         *  The default filtering levels are assigned using the 'level1Mask' -
   238         *  'level4Mask' config parameters. These are used to specify, for each of
   239         *  the four event levels, the set of bits which should filter at that 
   240         *  level by default.
   241         *
   242         *  The default filtering configuration sets the filter level to 
   243         *  Diags.LEVEL4 for all logging-related diags bits so that all events are
   244         *  logged by default.
   245         */
   246        config Diags.Mask level4Mask = Diags.ALL_LOGGING;
   247        
   248        /*!
   249         *  ======== flushAll ========
   250         *  Flush logs of all instances of `LoggerBuf` which set exitFlush to true.
   251         *
   252         *  The user is responsible for making sure that no `LoggerBuf` instances
   253         *  are created or deleted while in this API, by using an appropriate gate.
   254         */
   255        Void flushAll();
   256    
   257        /*!
   258         *  ======== flushAllInternal ========
   259         *  @_nodoc
   260         */
   261        Void flushAllInternal(Int stat);
   262    
   263        /*!
   264         * @_nodoc
   265         *  ======== initDecoder ========
   266         *  Initialize the LoggerBufDecoder for use in the LoggerBuf 'Records' ROV
   267         *  view.
   268         */
   269        function initDecoder();
   270        
   271    instance:
   272        /*!
   273         *  ======== create ========
   274         *  Create a `LoggerBuf` logger
   275         *
   276         *  @see LoggerBuf#Params
   277         */
   278        create();
   279    
   280        /*!
   281         *  ======== numEntries ========
   282         *  Number of entries in buffer
   283         *
   284         *  Each entry is large enough to store one `Log` event containing up to
   285         *  4 optional arguments.  Events containing more than 4 arguments (such
   286         *  as those from `{@link Log#write5}`) use 2 entries.
   287         *
   288         *  `numEntries` must be a power of 2.
   289         */
   290        config Int numEntries = 64;
   291    
   292        /*!
   293         *  ======== bufType ========
   294         *  Log buffer type
   295         */
   296        config BufType bufType = BufType_CIRCULAR;
   297    
   298        /*!
   299         *  ======== exitFlush ========
   300         *  Flush log at system exit
   301         *
   302         *  Only used when module parameter `{@link #enableFlush}` is `true`.
   303         */
   304        config Bool exitFlush = false;
   305    
   306        /*!
   307         *  ======== bufSection ========
   308         *  Section name for the buffer managed by the static instance.
   309         *
   310         *  The default section is the 'dataSection' in the platform.
   311         */
   312        metaonly config String bufSection = null;
   313    
   314        /*!
   315         *  ======== bufHeap ========
   316         *  The heap that contains the `Log` buffer for dynamic instances.
   317         *
   318         *  The default value `null` means the buffer will be allocated from
   319         *  the `{@link Memory#defaultHeapInstance}` heap.
   320         */
   321        config IHeap.Handle bufHeap = null;
   322    
   323        /*!
   324         *  ======== reset ========
   325         *  Reset a log to empty state and enable it
   326         *
   327         *  @a(WARNING)  This method is not synchronized with other instance
   328         *  methods and, as a result, it must never be called when there is a
   329         *  chance that another instance method is currently in operation or
   330         *  when another method on this instance may preempt this call.
   331         */
   332        Void reset();
   333    
   334        /*!
   335         *  ======== flush ========
   336         *  Read, clear, and output the contents of the log
   337         *
   338         *  This method reads, clears, and "prints" each `Log` event (via
   339         *  `{@link System#printf}`) in the log.
   340         */
   341        Void flush();
   342    
   343        /*!
   344         *  ======== getNextEntry ========
   345         *  Fills the passed `{@link Log#EventRec}` with the next entry in the log.
   346         *
   347         *  This function is used to read and clear `Log` events from the
   348         *  buffer maintained by the `LoggerBuf` instance. The `Log` event can
   349         *  then be transmitted and displayed on a host.
   350         *
   351         *  A read pointer is maintained in the `LoggerBuf` instance and
   352         *  points to the next record to read.  Entries are not necessarily
   353         *  returned in chronological order, since buffers of type
   354         *  `{@link #BufType_CIRCULAR}` can wrap.
   355         *
   356         *  @param(evtRec) pointer to a supplied `EventRec` object where the next
   357         *                 entry in the log is copied to
   358         *
   359         *  @a(returns)
   360         *  This function reports the number of entries actually read. The only
   361         *  values that can be returned are:
   362         *  @p(blist)
   363         *      - 0   no more entries to read
   364         *      - 1 or 2 read a complete entry written by `write4` or `write8`
   365         *      - -1  cleared an incomplete/overwritten entry, more entries to read
   366         */
   367        Int getNextEntry(Log.EventRec *evtRec);
   368        
   369    internal:
   370    
   371        Bool filterOutEvent(Diags.Mask mask);
   372    
   373        const Int8 FULL = -1;
   374        const Int8 WRAP = 0;
   375    
   376        const Int8 NEXT = 1;
   377    
   378        struct Entry {
   379            Types.Timestamp64 tstamp;
   380            Bits32 serial;
   381            Types.Event evt;
   382            IArg arg1;
   383            IArg arg2;
   384            IArg arg3;
   385            IArg arg4;
   386        };
   387        
   388        struct Module_State {
   389            Diags.Mask level1;
   390            Diags.Mask level2;
   391            Diags.Mask level3;
   392        };
   393    
   394        struct Instance_State {
   395            IHeap.Handle bufHeap;
   396            Entry entryArr[];
   397            Entry *curEntry;
   398            Entry *endEntry;
   399            Entry *readEntry;
   400            Bits32 serial;
   401            Int16 numEntries;
   402            Int8 advance;
   403            Bool enabled;
   404            Bool flush;
   405        };
   406    
   407    }
   408    /*
   409     *  @(#) xdc.runtime; 2, 1, 0,298; 1-12-2011 10:12:28; /db/ztree/library/trees/xdc/xdc-v55x/src/packages/
   410     */
   411