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        metaonly struct BasicView {
    92            String label;
    93            Int lastSerial;
    94            Bool enabledFlag;
    95        };
    96    
    97        metaonly struct 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        metaonly config 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        metaonly config 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