1    /*
     2     * Copyright (c) 2012, Texas Instruments Incorporated
     3     * All rights reserved.
     4     *
     5     * Redistribution and use in source and binary forms, with or without
     6     * modification, are permitted provided that the following conditions
     7     * are met:
     8     *
     9     * *  Redistributions of source code must retain the above copyright
    10     *    notice, this list of conditions and the following disclaimer.
    11     *
    12     * *  Redistributions in binary form must reproduce the above copyright
    13     *    notice, this list of conditions and the following disclaimer in the
    14     *    documentation and/or other materials provided with the distribution.
    15     *
    16     * *  Neither the name of Texas Instruments Incorporated nor the names of
    17     *    its contributors may be used to endorse or promote products derived
    18     *    from this software without specific prior written permission.
    19     *
    20     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    21     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
    22     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    23     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
    24     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    25     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    26     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
    27     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
    28     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
    29     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
    30     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    31     * */
    32    
    33    /*
    34     * ======== UIAThreadCtx.xdc ========
    35     */
    36    
    37    import xdc.runtime.Types;
    38    import xdc.runtime.Diags;
    39    import ti.uia.events.IUIACtx;
    40    
    41    /*!
    42     * UIA Thread Context Instrumentation
    43     *
    44     * The UIAThreadCtx module defines context change events
    45     * and methods that allow tooling to identify thread context
    46     * switches and to enable thread-aware filtering, trace and
    47     * analysis.
    48     *
    49     * It inherits IUIACtx, which defines a function pointer to
    50     * an isLoggingEnabled function which, if configured to point to
    51     * a function, will evaluate the function prior to logging the context
    52     * change event and will store the return value of the function in
    53     * ti_uia_runtime_CtxFilter_gIsLoggingEnabled, which is used to
    54     * determine whether or not to log events.
    55     *
    56     * The generation of UIAThreadCtx events is also controlled by a module's diagnostics
    57     * mask, which is described in details in `{@link xdc.runtime.Diags}`.
    58     * 'UIAThreadCtx` events are generated only when the Diags.ANALYSIS bit is set
    59     * in the module's diagnostics mask.
    60     *
    61     * The following configuration script demonstrates how the application might
    62     * control the logging of ANALYSIS events embedded in the `Mod` module at configuration
    63     * time. In this case, the configuration script arranges for the `Log`
    64     * statements within modules to always generate ANALYSIS events.
    65     * Without these configuration statements, no ANALYSIS events would be generated
    66     * by any modules.
    67     *
    68     * @a(Examples)
    69     * Example 1: This is part of the XDC configuration file for the application:
    70     *
    71     *  @p(code)
    72     *  var LogCtxChg = xdc.useModule('ti.uia.runtime.LogCtxChg');
    73     *  var Diags = xdc.useModule('xdc.runtime.Diags');
    74     *  var LoggerSys = xdc.useModule('xdc.runtime.LoggerSys');
    75     *  var Defaults = xdc.useModule('xdc.runtime.Defaults');
    76     *  var logger = LoggerSys.create();
    77     *
    78     *  Defaults.common$.diags_ANALYSIS = Diags.ALWAYS_ON;
    79     *  Defaults.common$.logger = logger;
    80     *  @p
    81     *
    82     *  @p(html)
    83     *  <hr />
    84     *  @p
    85     *
    86     * Example 2: The following example configures a module to support logging
    87     * of ANALYSIS events, but defers the actual activation and deactivation of the
    88     * logging until runtime. See the `{@link Diags#setMask Diags_setMask()}`
    89     * function for details on specifying the control string.
    90     *
    91     * This is a part of the XDC configuration file for the application:
    92     *
    93     *  @p(code)
    94     *  var LogCtxChg = xdc.useModule('ti.uia.runtime.LogCtxChg');
    95     *  var Diags = xdc.useModule('xdc.runtime.Diags');
    96     *  var Mod = xdc.useModule('my.pkg.Mod');
    97     *
    98     *  Mod.common$.diags_ANALYSIS = Diags.RUNTIME_OFF;
    99     *  @p
   100     *
   101     *  This is a part of the C code for the application:
   102     *
   103     *  @p(code)
   104     *  // turn on logging of ANALYSIS events in the module
   105     *  Diags_setMask("my.pkg.Mod+Z");
   106     *
   107     *  // turn off logging of ANALYSIS events in the module
   108     *  Diags_setMask("my.pkg.Mod-Z");
   109     *  @p
   110     */
   111    @CustomHeader
   112    module UIAThreadCtx inherits IUIACtx {
   113    
   114        /*!
   115         *  ======== ctxChg ========
   116         *  threadSwitch Context Change event
   117         *
   118         *  Used to log a thread switch
   119         *  Note that the previous thread Id is logged automatically by the ti_uia_runtime_LogCtxChg_thread
   120         *  API.
   121         *  If ti_uia_events_UIAThreadCtx_isLoggingEnabledFxn is not NULL
   122         *  it is called and its return value determines whether logging is enabled or not.
   123         *
   124         *  @a(Example)
   125         *   The following C code shows how to log a Thread Context Change
   126         *   event that identifies a new thread using a BIOS task switch hook function
   127         *
   128         *  @p(code)
   129         *  #include <ti/uia/runtime/LogCtxChg.h>
   130         *  ...
   131         *  Void  tskSwitchHook(Task_Handle hOldTask,Task_Handle hNewTask){
   132         *          LogCtxChg_thread("thread: new = 0x%x",(Int)hNewTask);
   133         *  }
   134         *  @p
   135         *  This event prints the Log call site (%$F) and a format string (%$S)
   136         *  which is recursively formatted with any addition arguments.
   137         *  The following text is an example of what will be displayed for the event:
   138         *  @p(code)
   139         *  "Thread Ctx Change at Line 123 in demo.c [Prev. thread ID=0x1234] New thread ID=0x1235"
   140         *
   141         *  @param(fmt)   a constant string that describes the context change and provides a format specifier for newThreadId
   142         *  @param(newThreadId)   an integer which uniquely identifies the new context
   143         */
   144        config xdc.runtime.Log.Event ctxChg = {
   145            mask: Diags.ANALYSIS,
   146            msg: "Thread Ctx Change at %$F [Prev. thread ID = 0x%x] %$S"};
   147    
   148        /*!
   149         *  ======== metaEventThreadCtxChg ========
   150         *  Metadata description of the Thread Context Change event
   151         *
   152         *  @_nodoc
   153         */
   154        metaonly config DvtTypes.MetaEventDescriptor metaEventThreadCtxChg = {
   155            versionId: "2.0",
   156            analysisType: DvtTypes.DvtAnalysisType_CONTEXTCHANGE,
   157            displayText: "Thread Ctx Change",
   158            tooltipText: "Thread Context Change",
   159            numParameters: 5,
   160            paramInfo: [
   161            {   name: '__FILE__',
   162                dataDesc: DvtTypes.DvtDataDesc_FILENAMESTR,
   163                dataTypeName: 'String',
   164                units: 'none',
   165                isHidden: false
   166            },
   167            {   name: '__LINE__',
   168                dataDesc: DvtTypes.DvtDataDesc_LINENUM,
   169                dataTypeName: 'Int',
   170                units: 'none',
   171                isHidden: false
   172            },
   173            {   name: 'Prev. Thread ID',
   174                dataDesc: DvtTypes.DvtDataDesc_THREADID,
   175                dataTypeName: 'Int',
   176                units: 'none',
   177                isHidden: false
   178            },
   179            {   name: 'fmt',
   180                dataDesc: DvtTypes.DvtDataDesc_FMTSTR,
   181                dataTypeName: 'String',
   182                units: 'none',
   183                isHidden: false
   184            },
   185            {   name: 'New Thread ID',
   186                dataDesc: DvtTypes.DvtDataDesc_THREADID,
   187                dataTypeName: 'Int',
   188                units: 'none',
   189                isHidden: false
   190            }]
   191    
   192        };
   193        /*!
   194         *  ======== ctxChgWithFunc ========
   195         *  threadSwitch Context Change event with prempted function and resumed function addresses
   196         *
   197         *  Used to log a thread switch along with function info (preempted function and new function)
   198         *  Note that the previous thread Id is logged automatically by the ti_uia_runtime_LogCtxChg_threadAndFunc
   199         *  API.
   200         *  If ti_uia_events_UIAThreadCtx_isLoggingEnabledFxn is not NULL
   201         *  it is called and its return value determines whether logging is enabled or not.
   202         *
   203         *  @a(Example)
   204         *   The following C code shows how to log a Thread Context Change
   205         *   event that identifies a new thread, the preempted function and the preempting function.
   206         *
   207         *  @p(code)
   208         *  #include <ti/uia/runtime/LogCtxChg.h>
   209         *  ...
   210         *  LogCtxChg_threadAndFunc("New thread ID=0x%x, oldFunc=0x%x, newFunc=0x%x",(Int)hNewTask, (Int)&oldFunc,(Int)&newFunc);
   211         *
   212         *  @p
   213         *  This event prints the Log call site (%$F) and a format string (%$S)
   214         *  which is recursively formatted with any addition arguments.
   215         *  The following text is an example of what will be displayed for the event:
   216         *  @p(code)
   217         *  "Thread CtxChgWithFunc at Line 123 in demo.c [Prev. thread ID=0x1234] New thread ID=0x1235, oldFunc=0x80001200, newFunc=0x80001080"
   218         *
   219         *  @param(fmt)   a constant string that describes the context change and provides a format specifier for newThreadId
   220         *  @param(newThreadId)   an integer which uniquely identifies the new context
   221         *  @param(oldFunc)   the address of the function that was preempted
   222         *  @param(newFunc)   the address of the function that is being resumed
   223         */
   224        config xdc.runtime.Log.Event ctxChgWithFunc = {
   225            mask: Diags.ANALYSIS,
   226            msg: "Thread CtxChgWithFunc at %$F [Prev. threadId = 0x%x] %$S"};
   227    
   228        /*!
   229         *  ======== metaEventThreadCtxChgWithFunc ========
   230         *  Metadata description of the Application Context Change event
   231         *
   232         *  @_nodoc
   233         */
   234        metaonly config DvtTypes.MetaEventDescriptor metaEventThreadCtxChgWithFunc = {
   235            versionId: "2.0",
   236            analysisType: DvtTypes.DvtAnalysisType_CONTEXTCHANGE,
   237            displayText: "Thread Ctx Change with function addresses",
   238            tooltipText: "Thread Context Change with function addresses",
   239            numParameters: 7,
   240            paramInfo: [
   241            {   name: '__FILE__',
   242                dataDesc: DvtTypes.DvtDataDesc_FILENAMESTR,
   243                dataTypeName: 'String',
   244                units: 'none',
   245                isHidden: false
   246            },
   247            {   name: '__LINE__',
   248                dataDesc: DvtTypes.DvtDataDesc_LINENUM,
   249                dataTypeName: 'Int',
   250                units: 'none',
   251                isHidden: false
   252            },
   253            {   name: 'Prev. Thread ID',
   254                dataDesc: DvtTypes.DvtDataDesc_THREADID,
   255                dataTypeName: 'Int',
   256                units: 'none',
   257                isHidden: false
   258            },
   259            {   name: 'fmt',
   260                dataDesc: DvtTypes.DvtDataDesc_FMTSTR,
   261                dataTypeName: 'String',
   262                units: 'none',
   263                isHidden: false
   264            },
   265            {   name: 'New Frame ID',
   266                dataDesc: DvtTypes.DvtDataDesc_THREADID,
   267                dataTypeName: 'Int',
   268                units: 'none',
   269                isHidden: false
   270            },
   271            {   name: 'Preempted Function Address',
   272                dataDesc: DvtTypes.DvtDataDesc_FUNCTIONADRS,
   273                dataTypeName: 'Int',
   274                units: 'none',
   275                isHidden: false
   276            },
   277            {   name: 'Resumed Function Address',
   278                dataDesc: DvtTypes.DvtDataDesc_FUNCTIONADRS,
   279                dataTypeName: 'Int',
   280                units: 'none',
   281                isHidden: false
   282            }
   283            ]
   284    
   285        };
   286        /*!
   287         * ======== getCtxId ========
   288         * Get the ID for the current thread
   289         *
   290         *  @a(returns)
   291         *  returns the thread ID logged by the last call to UIAThreadCtx_logCtxChg.
   292         */
   293        @Macro Int getCtxId();
   294    
   295        /*!
   296         * ======== isLoggingEnabled ========
   297         * returns true if the new context matches the value to enable logging with.
   298         *
   299         *  Default implementation of the IUIACtx_IsLoggingEnabledFxn for user context.
   300         *  To enable context-aware filtering, assign UIAThreadCtx_isLoggingEnabledFxn = &UIAThreadCtx_isLoggingEnabled
   301         *  in the config script or programmatically, or assign your own implementation of this
   302         *  function.
   303         *  @param(newThreadId) the new thread ID
   304         *  @a(returns) true if logging is enabled
   305         */
   306         @DirectCall
   307         Bool isLoggingEnabled(UInt newThreadId);
   308    
   309        /*!
   310         * ======== setOldValue =========
   311         * sets ti_uia_events_UIAThreadCtx_gLastValue to the new value and returns the old value before it was updated.
   312         *
   313         * @param(newValue) the new value to save in the global variable
   314         * @a(return0       the original value of the global variable before it was updated.
   315         */
   316         @DirectCall
   317         UInt setOldValue(UInt newValue);
   318    }