Home | History | Annotate | Download | only in inc
      1 
      2 /*
      3  * Copyright (C) Texas Instruments - http://www.ti.com/
      4  *
      5  * This library is free software; you can redistribute it and/or
      6  * modify it under the terms of the GNU Lesser General Public
      7  * License as published by the Free Software Foundation; either
      8  * version 2.1 of the License, or (at your option) any later version.
      9  *
     10  *
     11  * This library is distributed in the hope that it will be useful,
     12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14  * Lesser General Public License for more details.
     15  *
     16  *
     17  * You should have received a copy of the GNU Lesser General Public
     18  * License along with this library; if not, write to the Free Software
     19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
     20  */
     21 /* This headerdescribes the external PERF interface */
     22 #ifndef __PERF_H__
     23 #define __PERF_H__
     24 
     25 /* global flag */
     26 #ifdef __PERF_INSTRUMENTATION__
     27 
     28 /** Compile-tempTime configuration options
     29 *
     30 *   In order to facilitate more flexible configuration options,
     31 *   yet maintain run-tempTime performance, we allow the following
     32 *   configuration options:
     33 *
     34 *   __PERF_CUSTOMIZABLE__
     35 *
     36 *   If enabled, we allow customized implementation of the
     37 *   performance interface, e.g. unbuffered debug prints to find
     38 *   the point of a program crash. For more information on the
     39 *   specific features supported, see perf_custom.h.
     40 *
     41 *   If disabled, all instrumentation calls are hard-coded to be
     42 *   logged into a logging buffer.
     43 * */
     44 
     45 #if defined(__PERF_LOG_LOCATION__)
     46     #define __PERF_Location(hObject) \
     47         __PERF_FN(Location) (hObject,__FILE__,__LINE__,__func__);
     48 #elif defined(__PERF_LOCATE__)
     49     #define __PERF_Location(hObject) \
     50         fprintf(stderr,"PERF in [%s:%d func:%s]:",__FILE__,__LINE__,__func__);
     51 #else
     52     #define __PERF_Location(hObject)
     53 #endif
     54 
     55 #ifdef __PERF_CUSTOMIZABLE__
     56     #define __PERF_FN(a) __PERF_CUSTOM_##a
     57 #else
     58     #define __PERF_FN(a) __PERF_LOG_##a
     59 #endif
     60 
     61 /*=============================================================================
     62     Overall API methodology.
     63 
     64     Since this is an instrumentation API, other than the create call, no
     65     other methods return any value, so there is no error checking
     66     requirements.
     67 
     68     If the create call encounters any errors, or if the instrumentation is run-
     69     tempTime disabled, it will return NULL.  All other API-s must handle a NULL
     70     argument, and will do nothing in such case.
     71 =============================================================================*/
     72 
     73 /* Four CC calculations from characters and string */
     74 
     75 #define PERF_FOURCC(a,b,c,d)                   \
     76     ( ((((unsigned long) (a)) & 0xFF) << 24) | \
     77       ((((unsigned long) (b)) & 0xFF) << 16) | \
     78       ((((unsigned long) (c)) & 0xFF) << 8)  | \
     79        (((unsigned long) (d)) & 0xFF) )
     80 
     81 #define PERF_FOURS(id) \
     82       PERF_FOURCC((id)[0], (id)[1], (id)[2], (id)[3])
     83 
     84 #define PERF_FOUR_CHARS(i) \
     85       (char) (((i) >> 24) & 0xFF), (char) (((i) >> 16) & 0xFF), \
     86       (char) (((i) >> 8)  & 0xFF), (char) ((i) & 0xFF)
     87 
     88 #define PREF(a,b) ((a) ? (a)->b : 0)
     89 
     90 /*=============================================================================
     91     ENUMERATIONS
     92 =============================================================================*/
     93 
     94 /*-----------------------------------------------------------------------------
     95     PERF_BOUNDARYTYPE
     96 
     97     The phase of execution for the Boundary callback
     98 -----------------------------------------------------------------------------*/
     99 typedef enum PERF_BOUNDARYTYPE
    100 {
    101     /* UC phase boundary type */
    102     PERF_BoundaryStart      = 0,
    103     PERF_BoundaryComplete   = 0x10000,
    104 
    105     /* UC phase type */
    106     PERF_BoundarySetup = 1,   /* UC initialization */
    107     PERF_BoundaryCleanup,     /* UC cleanup */
    108     PERF_BoundarySteadyState, /* UC is in 'steady state' - optional */
    109 
    110     PERF_BoundaryMax,
    111     PERF_BoundaryMask   = 3,
    112 } PERF_BOUNDARYTYPE;
    113 
    114 #ifdef __PERF_PRINT_C__
    115 
    116 char const * const PERF_BoundaryTypes[] = {"NONE", "Setup", "Cleanup", "Steady"};
    117 
    118 #endif
    119 
    120 #define PERF_IsComplete(x) ((x) & PERF_BoundaryComplete)
    121 #define PERF_IsStarted(x)  (!PERF_IsComplete(x))
    122 
    123 /*-----------------------------------------------------------------------------
    124     PERF_MODULETYPE
    125 
    126     Type of module when creating the component, or when specifying source
    127     or destination of buffer transfers and/or commands
    128 -----------------------------------------------------------------------------*/
    129 
    130 /* These flags are also used for the LOG commands */
    131 #define PERF_FlagSending     0x10000000ul   /* This is used for LOG */
    132 #define PERF_FlagSent        0x30000000ul   /* This is used for LOG */
    133 #define PERF_FlagRequesting  0x20000000ul   /* This is used for LOG */
    134 #define PERF_FlagReceived    0x00000000ul   /* This is used for LOG */
    135 #define PERF_FlagSendFlags   0x30000000ul
    136 #define PERF_FlagXfering     0x40000000ul   /* This is used for LOG */
    137                                             /* = Received + Sending */
    138 #define PERF_FlagFrame       0x08000000ul
    139 #define PERF_FlagBuffer      0x00000000ul
    140 #define PERF_FlagMultiple    0x80000000ul
    141 #define PERF_FlagSingle      0x00000000ul
    142 
    143 #define PERF_GetSendRecv(x) ((x) & PERF_FlagSent)
    144 #define PERF_GetXferSendRecv(x) ((x) & (PERF_FlagSendFlags | PERF_FlagXfering))
    145 #define PERF_GetFrameBuffer(x)     PERF_IsFrame(x)
    146 #define PERF_GetMultipleSingle(x)  PERF_IsMultiple(x)
    147 
    148 #define PERF_IsFrame(x)     ((x) & PERF_FlagFrame)
    149 #define PERF_IsBuffer(x)    (!PERF_IsFrame(x))
    150 #define PERF_IsSending(x)   ((x) & PERF_FlagSending)
    151 #define PERF_IsReceived(x)  (!PERF_IsSending(x))
    152 #define PERF_IsXfering(x)   ((x) & PERF_FlagXfering)
    153 #define PERF_IsMultiple(x)  ((x) & PERF_FlagMultiple)
    154 #define PERF_IsSingle(x)    (!PERF_IsMultiple(x))
    155 
    156 typedef enum PERF_MODULETYPE
    157 {
    158     PERF_ModuleApplication,  /* application */
    159     PERF_ModuleSystem,       /* system components */
    160     PERF_ModuleService,      /* service or server */
    161     PERF_ModuleHLMM,         /* high-level multimedia, e.g. MMF */
    162     PERF_ModuleLLMM,         /* low-level multimedia, e.g. MDF, OMX */
    163     PERF_ModuleComponent,    /* multimedia component */
    164     PERF_ModuleCommonLayer,  /* common layer */
    165     PERF_ModuleSocketNode,   /* socket-node (e.g. on DSP) */
    166     PERF_ModuleAlgorithm,    /* algorithm (for possible future needs) */
    167     PERF_ModuleHardware,     /* hardware (e.g. speaker, microphone) */
    168     PERF_ModuleMemory,       /* memory or unspecified modules */
    169     PERF_ModuleMemoryMap,    /* memory mapping */
    170     PERF_ModuleMax,
    171     PERF_ModuleBits = 4,
    172     PERF_ModuleMask = (1 << PERF_ModuleBits) - 1,
    173 
    174     /* module functional types used for selectively enabling instrumentation */
    175     PERF_ModuleDomains     = 1 << (1 << PERF_ModuleBits),
    176     PERF_ModuleAudioDecode = PERF_ModuleDomains,
    177     PERF_ModuleAudioEncode = PERF_ModuleAudioDecode << 1,
    178     PERF_ModuleVideoDecode = PERF_ModuleAudioEncode << 1,
    179     PERF_ModuleVideoEncode = PERF_ModuleVideoDecode << 1,
    180     PERF_ModuleImageDecode = PERF_ModuleVideoEncode << 1,
    181     PERF_ModuleImageEncode = PERF_ModuleImageDecode << 1,
    182 } PERF_MODULETYPE;
    183 
    184 #ifdef __PERF_PRINT_C__
    185 
    186 char const * const PERF_ModuleTypes[] = {
    187     "Application", "System",    "Service",     "HLMM",
    188     "LLMM",        "Component", "CommonLayer", "SocketNode",
    189     "Algorithm",   "Hardware",  "Memory",      "MemoryMap"
    190 };
    191 
    192 #endif
    193 
    194 /*-----------------------------------------------------------------------------
    195     PERF_SYNCOPTYPE
    196 
    197     Type of module phase of execution for the cbBoundary callback
    198 -----------------------------------------------------------------------------*/
    199 typedef enum PERF_SYNCOPTYPE
    200 {
    201     PERF_SyncOpNone,
    202     PERF_SyncOpDropVideoFrame,   /* drop a video frame */
    203     PERF_SyncOpMax,
    204 } PERF_SYNCOPTYPE;
    205 
    206 #ifdef __PERF_PRINT_C__
    207 
    208 char const *PERF_SyncOpTypes[] = {
    209     "none", "drop_video_frame"
    210 };
    211 
    212 #endif
    213 
    214 /*-----------------------------------------------------------------------------
    215     PERF_COMMANDTYPE
    216 
    217     PERF commands
    218 -----------------------------------------------------------------------------*/
    219 typedef enum PERF_COMMANDTYPE
    220 {
    221     PERF_CommandMax,
    222     PERF_CommandStatus = 0x10000000,
    223 } PERF_COMMANDTYPE;
    224 
    225 #ifdef __PERF_PRINT_C__
    226 
    227 char const *PERF_CommandTypes[] = {
    228     "none"
    229 };
    230 
    231 #endif
    232 
    233 
    234 /*=============================================================================
    235     CREATION INTERFACE
    236 =============================================================================*/
    237 typedef struct PERF_OBJTYPE *PERF_OBJHANDLE;
    238 
    239 /** PERF_Create method is the is used to create an
    240 *   instrumentation object for a component.
    241 *
    242 *   NOTE: It's arguments may depend on the operating system, as
    243 *   the PERF object may need access to system resource
    244 *   (terminal, file system).  For now, we assume that all
    245 *   interfaces are accessible from system calls.
    246 *
    247 *   This operation may include allocating resources from the
    248 *   system, to create any structures required for managing the
    249 *   data collected during instrumentation, but our aim is to
    250 *   have these resources be minimal.
    251 *
    252 *   Most options are run-tempTime configurable.  See perf_config.h
    253 *   for such options.
    254 *
    255 *   In case of error - or if performance instrumentation is
    256 *   run-tempTime disabled, PERF_Create will return a NULL handle,
    257 *   and all resource allocations will be undone.
    258 *
    259 *   @param ulComponent
    260 *       FourCC component ID.
    261 *   @param eModule
    262 *       ModuleType.
    263 *   @return hObject
    264 *       Handle to the instrumentation object.
    265  */
    266 
    267 PERF_OBJHANDLE PERF_Create(
    268                           unsigned long ulComponentName,
    269                           PERF_MODULETYPE eModule);
    270 
    271 /** The PERF_Done method is called at the end of the component
    272 *   life cycle.
    273 *   @param hObject
    274 *       Handle to the PERF object.  This must be an lvalue, as
    275 *       it will be deleted and set to NULL upon return.
    276 * */
    277 #define PERF_Done(           \
    278         hObject)             \
    279     do {                     \
    280     __PERF_Location(hObject) \
    281     __PERF_Done(hObject);    \
    282     } while (0)
    283 
    284 
    285 /*=============================================================================
    286     INSTRUMENTATION INTERFACE
    287 =============================================================================*/
    288 
    289 /** The PERF_Boundary callback must be called by the component
    290 *   at specific phases of the component.
    291 *   @param hObject
    292 *       Handle to the PERF object.
    293 *   @param eBoundary
    294 *       Boundary (phase) that is reached by the application.
    295 * */
    296 
    297 #define PERF_Boundary(       \
    298         hObject,             \
    299         eBoundary)           \
    300     do {                     \
    301     __PERF_Location(hObject) \
    302     __PERF_FN(Boundary)(hObject, eBoundary); \
    303     } while (0)
    304 
    305 /** The PERF_SendingBuffer(s) and PERF_SendingFrame(s) method is
    306 *   used to mark when a buffer (or frame) is to be sent to
    307 *   another module.
    308 *
    309 *   @param hObject
    310 *       Handle to the PERF object.
    311 *   @param ulAddress or ulAddress1 and ulAddress2
    312 *       Buffer (or frame) address(es).
    313 *   @param ulSize
    314 *       size of buffer(s) that is sent regardless if it is sent
    315 *       by pointer exchange or memory copy.
    316 *   @param eModuleTo
    317 *       Type of module that is receiving the data.
    318 * */
    319 #define PERF_SendingBuffer(                                             \
    320         hObject,                                                        \
    321         ulAddress,                                                      \
    322         ulSize,                                                         \
    323         eModuleTo)                                                      \
    324   do {                                                                  \
    325   __PERF_Location(hObject)                                              \
    326   __PERF_FN(Buffer)(hObject,                                            \
    327                     PERF_FlagSending, PERF_FlagSingle, PERF_FlagBuffer, \
    328                     ulAddress, NULL, ulSize, eModuleTo, 0);             \
    329   } while(0)
    330 
    331 #define PERF_SendingFrame(                                             \
    332         hObject,                                                       \
    333         ulAddress,                                                     \
    334         ulSize,                                                        \
    335         eModuleTo)                                                     \
    336   do {                                                                 \
    337   __PERF_Location(hObject)                                             \
    338   __PERF_FN(Buffer)(hObject,                                           \
    339                     PERF_FlagSending, PERF_FlagSingle, PERF_FlagFrame, \
    340                     ulAddress, NULL, ulSize, eModuleTo, 0);            \
    341   } while (0)
    342 
    343 #define PERF_SendingBuffers(                                              \
    344         hObject,                                                          \
    345         ulAddress1,                                                       \
    346         ulAddress2,                                                       \
    347         ulSize,                                                           \
    348         eModuleTo)                                                        \
    349   do {                                                                    \
    350   __PERF_Location(hObject)                                                \
    351   __PERF_FN(Buffer)(hObject,                                              \
    352                     PERF_FlagSending, PERF_FlagMultiple, PERF_FlagBuffer, \
    353                     ulAddress1, ulAddress2, ulSize, eModuleTo, 0);        \
    354   } while (0)
    355 
    356 #define PERF_SendingFrames(                                              \
    357         hObject,                                                         \
    358         ulAddress1,                                                      \
    359         ulAddress2,                                                      \
    360         ulSize,                                                          \
    361         eModuleTo)                                                       \
    362   do {                                                                   \
    363   __PERF_Location(hObject)                                               \
    364   __PERF_FN(Buffer)(hObject,                                             \
    365                     PERF_FlagSending, PERF_FlagMultiple, PERF_FlagFrame, \
    366                     ulAddress1, ulAddress2, ulSize, eModuleTo, 0);       \
    367   } while (0)
    368 
    369 /** The PERF_SendingCommand method is used to mark when a
    370 *   command is to be sent to another module.
    371 *
    372 *   @param hObject
    373 *       Handle to the PERF object.
    374 *   @param ulCommand
    375 *       Command.
    376 *   @param eModuleTo
    377 *       Type of module that is receiving the data.
    378 * */
    379 #define PERF_SendingCommand(  \
    380         hObject,              \
    381         ulCommand,            \
    382         ulArgument,           \
    383         eModuleTo)            \
    384   do {                        \
    385   __PERF_Location(hObject)    \
    386   __PERF_FN(Command)(hObject, \
    387                      PERF_FlagSending, ulCommand, ulArgument, eModuleTo); \
    388   } while (0)
    389 
    390 /** The PERF_SentBuffer(s) and PERF_SentFrame(s) method is
    391 *   used to mark when a buffer (or frame) has been sent to
    392 *   another module.
    393 *
    394 *   @param hObject
    395 *       Handle to the PERF object.
    396 *   @param ulAddress or ulAddress1 and ulAddress2
    397 *       Buffer (or frame) address(es).
    398 *   @param ulSize
    399 *       size of buffer(s) that is sent regardless if it is sent
    400 *       by pointer exchange or memory copy.
    401 *   @param eModuleTo
    402 *       Type of module that is receiving the data.
    403 * */
    404 #define PERF_SentBuffer(                                             \
    405         hObject,                                                     \
    406         ulAddress,                                                   \
    407         ulSize,                                                      \
    408         eModuleTo)                                                   \
    409   do {                                                               \
    410   __PERF_Location(hObject)                                           \
    411   __PERF_FN(Buffer)(hObject,                                         \
    412                     PERF_FlagSent, PERF_FlagSingle, PERF_FlagBuffer, \
    413                     ulAddress, NULL, ulSize, eModuleTo, 0);          \
    414   } while(0)
    415 
    416 #define PERF_SentFrame(                                             \
    417         hObject,                                                    \
    418         ulAddress,                                                  \
    419         ulSize,                                                     \
    420         eModuleTo)                                                  \
    421   do {                                                              \
    422   __PERF_Location(hObject)                                          \
    423   __PERF_FN(Buffer)(hObject,                                        \
    424                     PERF_FlagSent, PERF_FlagSingle, PERF_FlagFrame, \
    425                     ulAddress, NULL, ulSize, eModuleTo, 0);         \
    426   } while (0)
    427 
    428 #define PERF_SentBuffers(                                              \
    429         hObject,                                                       \
    430         ulAddress1,                                                    \
    431         ulAddress2,                                                    \
    432         ulSize,                                                        \
    433         eModuleTo)                                                     \
    434   do {                                                                 \
    435   __PERF_Location(hObject)                                             \
    436   __PERF_FN(Buffer)(hObject,                                           \
    437                     PERF_FlagSent, PERF_FlagMultiple, PERF_FlagBuffer, \
    438                     ulAddress1, ulAddress2, ulSize, eModuleTo, 0);     \
    439   } while (0)
    440 
    441 #define PERF_SentFrames(                                              \
    442         hObject,                                                      \
    443         ulAddress1,                                                   \
    444         ulAddress2,                                                   \
    445         ulSize,                                                       \
    446         eModuleTo)                                                    \
    447   do {                                                                \
    448   __PERF_Location(hObject)                                            \
    449   __PERF_FN(Buffer)(hObject,                                          \
    450                     PERF_FlagSent, PERF_FlagMultiple, PERF_FlagFrame, \
    451                     ulAddress1, ulAddress2, ulSize, eModuleTo, 0);    \
    452   } while (0)
    453 
    454 /** The PERF_SentCommand method is used to mark when a
    455 *   command has been sent to another module.
    456 *
    457 *   @param hObject
    458 *       Handle to the PERF object.
    459 *   @param ulCommand
    460 *       Command.
    461 *   @param eModuleTo
    462 *       Type of module that is receiving the data.
    463 * */
    464 #define PERF_SentCommand(     \
    465         hObject,              \
    466         ulCommand,            \
    467         ulArgument,           \
    468         eModuleTo)            \
    469   do {                        \
    470   __PERF_Location(hObject)    \
    471   __PERF_FN(Command)(hObject, \
    472                      PERF_FlagSent, ulCommand, ulArgument, eModuleTo); \
    473   } while (0)
    474 
    475 /** The PERF_RequestingBuffer(s) and PERF_RequestingFrame(s) method
    476 *   is used to mark when a buffer (or frame) is beeing requested
    477 *   from another module. These go hand-in-hand with
    478 *   ReceivedBuffer and ReceivedFrame, if one wants to measure
    479 *   the time spent waiting (pending) for a buffer/frame.  Note,
    480 *   that the buffer address or size may not be known upon
    481 *   calling this method, in which case -1 should be used.
    482 *   @param hAPI
    483 *       Handle to the PERF object.
    484 *   @param ulAddress
    485 *       Buffer (or frame) address.
    486 *   @param ulSize
    487 *       size of buffer(s) that is sent regardless if it is sent
    488 *       by pointer exchange or memory copy.
    489 *   @param eModuleFrom
    490 *       Type of module that is sending the data.
    491 * */
    492 #define PERF_RequestingBuffer(                                             \
    493         hObject,                                                           \
    494         ulAddress,                                                         \
    495         ulSize,                                                            \
    496         eModuleFrom)                                                       \
    497   do {                                                                     \
    498   __PERF_Location(hObject)                                                 \
    499   __PERF_FN(Buffer)(hObject,                                               \
    500                     PERF_FlagRequesting, PERF_FlagSingle, PERF_FlagBuffer, \
    501                     ulAddress, NULL, ulSize, eModuleFrom, 0);              \
    502   } while (0)
    503 
    504 #define PERF_RequestingFrame(                                             \
    505         hObject,                                                          \
    506         ulAddress,                                                        \
    507         ulSize,                                                           \
    508         eModuleFrom)                                                      \
    509   do {                                                                    \
    510   __PERF_Location(hObject)                                                \
    511   __PERF_FN(Buffer)(hObject,                                              \
    512                     PERF_FlagRequesting, PERF_FlagSingle, PERF_FlagFrame, \
    513                     ulAddress, NULL, ulSize, eModuleFrom, 0);             \
    514   } while (0)
    515 
    516 #define PERF_RequestingBuffers(                                              \
    517         hObject,                                                             \
    518         ulAddress1,                                                          \
    519         ulAddress2,                                                          \
    520         ulSize,                                                              \
    521         eModuleFrom)                                                         \
    522   do {                                                                       \
    523   __PERF_Location(hObject)                                                   \
    524   __PERF_FN(Buffer)(hObject,                                                 \
    525                     PERF_FlagRequesting, PERF_FlagMultiple, PERF_FlagBuffer, \
    526                     ulAddress1, ulAddress2, ulSize, eModuleFrom, 0);         \
    527   } while (0)
    528 
    529 #define PERF_RequestingFrames(                                              \
    530         hObject,                                                            \
    531         ulAddress1,                                                         \
    532         ulAddress2,                                                         \
    533         ulSize,                                                             \
    534         eModuleFrom)                                                        \
    535   do {                                                                      \
    536   __PERF_Location(hObject)                                                  \
    537   __PERF_FN(Buffer)(hObject,                                                \
    538                     PERF_FlagRequesting, PERF_FlagMultiple, PERF_FlagFrame, \
    539                     ulAddress1, ulAddress2, ulSize, eModuleFrom, 0);        \
    540   } while (0)
    541 
    542 /** The PERF_RequestingCommand method is used to mark when a
    543 *   command is being requested from another module.  This method
    544 *   goes in hand with the PERF_ReceivedCommand to measure the
    545 *   time the application is "pending" for the command.  Note,
    546 *   that the command is most likely not known when calling this
    547 *   method, in which case -1 should be used.
    548 *
    549 *   @param hObject
    550 *       Handle to the PERF object.
    551 *   @param ulCommand
    552 *       Command.
    553 *   @param eModuleTo
    554 *       Type of module that sent the data.
    555 * */
    556 #define PERF_RequestingCommand( \
    557         hObject,                \
    558         ulCommand,              \
    559 		ulArgument,             \
    560         eModuleFrom)            \
    561   do {                          \
    562   __PERF_Location(hObject)      \
    563   __PERF_FN(Command)(hObject,   \
    564                      PERF_FlagRequesting, ulCommand, ulArgument, eModuleFrom); \
    565   } while (0)
    566 
    567 
    568 /** The PERF_ReceivedBuffer(s) and PERF_ReceivedFrame(s) method
    569 *   is used to mark when a buffer (or frame) is received from
    570 *   another module. These go hand-in-hand with SendingBuffer and
    571 *   SendingFrame, if instrumentation is implemented at all
    572 *   module boundaries.
    573 *   @param hAPI
    574 *       Handle to the PERF object.
    575 *   @param ulAddress
    576 *       Buffer (or frame) address.
    577 *   @param ulSize
    578 *       size of buffer(s) that is sent regardless if it is sent
    579 *       by pointer exchange or memory copy.
    580 *   @param eModuleFrom
    581 *       Type of module that is sending the data.
    582 * */
    583 #define PERF_ReceivedBuffer(                                             \
    584         hObject,                                                         \
    585         ulAddress,                                                       \
    586         ulSize,                                                          \
    587         eModuleFrom)                                                     \
    588   do {                                                                   \
    589   __PERF_Location(hObject)                                               \
    590   __PERF_FN(Buffer)(hObject,                                             \
    591                     PERF_FlagReceived, PERF_FlagSingle, PERF_FlagBuffer, \
    592                     ulAddress, NULL, ulSize, eModuleFrom, 0);            \
    593   } while (0)
    594 
    595 #define PERF_ReceivedFrame(                                             \
    596         hObject,                                                        \
    597         ulAddress,                                                      \
    598         ulSize,                                                         \
    599         eModuleFrom)                                                    \
    600   do {                                                                  \
    601   __PERF_Location(hObject)                                              \
    602   __PERF_FN(Buffer)(hObject,                                            \
    603                     PERF_FlagReceived, PERF_FlagSingle, PERF_FlagFrame, \
    604                     ulAddress, NULL, ulSize, eModuleFrom, 0);           \
    605   } while (0)
    606 
    607 #define PERF_ReceivedBuffers(                                              \
    608         hObject,                                                           \
    609         ulAddress1,                                                        \
    610         ulAddress2,                                                        \
    611         ulSize,                                                            \
    612         eModuleFrom)                                                       \
    613   do {                                                                     \
    614   __PERF_Location(hObject)                                                 \
    615   __PERF_FN(Buffer)(hObject,                                               \
    616                     PERF_FlagReceived, PERF_FlagMultiple, PERF_FlagBuffer, \
    617                     ulAddress1, ulAddress2, ulSize, eModuleFrom, 0);       \
    618   } while (0)
    619 
    620 #define PERF_ReceivedFrames(                                              \
    621         hObject,                                                          \
    622         ulAddress1,                                                       \
    623         ulAddress2,                                                       \
    624         ulSize,                                                           \
    625         eModuleFrom)                                                      \
    626   do {                                                                    \
    627   __PERF_Location(hObject)                                                \
    628   __PERF_FN(Buffer)(hObject,                                              \
    629                     PERF_FlagReceived, PERF_FlagMultiple, PERF_FlagFrame, \
    630                     ulAddress1, ulAddress2, ulSize, eModuleFrom, 0);      \
    631   } while (0)
    632 
    633 /** The PERF_ReceivedCommand method is used to mark when a
    634 *   command is received from another module.
    635 *
    636 *   @param hObject
    637 *       Handle to the PERF object.
    638 *   @param ulCommand
    639 *       Command.
    640 *   @param eModuleTo
    641 *       Type of module that sent the data.
    642 * */
    643 #define PERF_ReceivedCommand( \
    644         hObject,              \
    645         ulCommand,            \
    646 		ulArgument,           \
    647         eModuleFrom)          \
    648   do {                        \
    649   __PERF_Location(hObject)    \
    650   __PERF_FN(Command)(hObject, \
    651                      PERF_FlagReceived, ulCommand, ulArgument, eModuleFrom); \
    652   } while (0)
    653 
    654 /** The PERF_XferingBuffer(s) and PERF_XferingFrame(s)
    655 *   method is used to mark when a buffer (or frame) is to be
    656 *   transferred from one module to another.  This is shortcut
    657 *   for PERF_Received followed by PERF_Sending
    658 *
    659 *   @param hObject
    660 *       Handle to the PERF object.
    661 *   @param ulAddress or ulAddress1 and ulAddress2
    662 *       Buffer (or frame) address(es).
    663 *   @param ulSize
    664 *       size of buffer(s) that is sent regardless if it is sent
    665 *       by pointer exchange or memory copy.
    666 *   @param eModuleFrom
    667 *       Type of module that is sending the data.
    668 *   @param eModuleTo
    669 *       Type of module that is receiving the data.
    670 * */
    671 #define PERF_XferingBuffer(                                             \
    672         hObject,                                                        \
    673         ulAddress,                                                      \
    674         ulSize,                                                         \
    675         eModuleFrom,                                                    \
    676         eModuleTo)                                                      \
    677   do {                                                                  \
    678   __PERF_Location(hObject)                                              \
    679   __PERF_FN(Buffer)(hObject,                                            \
    680                     PERF_FlagXfering, PERF_FlagSingle, PERF_FlagBuffer, \
    681                     ulAddress, NULL, ulSize, eModuleFrom, eModuleTo);   \
    682   } while (0)
    683 
    684 #define PERF_XferingFrame(                                             \
    685         hObject,                                                       \
    686         ulAddress,                                                     \
    687         ulSize,                                                        \
    688         eModuleFrom,                                                   \
    689         eModuleTo)                                                     \
    690   do {                                                                 \
    691   __PERF_Location(hObject)                                             \
    692   __PERF_FN(Buffer)(hObject,                                           \
    693                     PERF_FlagXfering, PERF_FlagSingle, PERF_FlagFrame, \
    694                     ulAddress, NULL, ulSize, eModuleFrom, eModuleTo);  \
    695   } while (0)
    696 
    697 #define PERF_XferingBuffers(                                              \
    698         hObject,                                                          \
    699         ulAddress1,                                                       \
    700         ulAddress2,                                                       \
    701         ulSize,                                                           \
    702         eModuleFrom,                                                      \
    703         eModuleTo)                                                        \
    704   do {                                                                    \
    705   __PERF_Location(hObject)                                                \
    706   __PERF_FN(Buffer)(hObject,                                              \
    707                     PERF_FlagXfering, PERF_FlagMultiple, PERF_FlagBuffer, \
    708                     ulAddress1, ulAddress2, ulSize, eModuleFrom, eModuleTo);\
    709   } while (0)
    710 
    711 #define PERF_XferingFrames(                                              \
    712         hObject,                                                         \
    713         ulAddress1,                                                      \
    714         ulAddress2,                                                      \
    715         ulSize,                                                          \
    716         eModuleFrom,                                                     \
    717         eModuleTo)                                                       \
    718   do {                                                                   \
    719   __PERF_Location(hObject)                                               \
    720   __PERF_FN(Buffer)(hObject,                                             \
    721                     PERF_FlagXfering, PERF_FlagMultiple, PERF_FlagFrame, \
    722                     ulAddress1, ulAddress2, ulSize, eModuleFrom, eModuleTo);\
    723   } while (0)
    724 
    725 /** The PERF_SyncData method shall be called by a module that
    726 *   synchronizes audio/video streams.  It informs the
    727 *   instrumentation module about the tempTime stamps of the two
    728 *   streams, as well as the operation (if any) to restore
    729 *   synchronization.
    730 *   @param hObject
    731 *       Handle to the PERF object.
    732 *   @param pfTimeAudio
    733 *       Time stamp of audio frame
    734 *   @param pfTimeVideo
    735 *       Time stamp of video frame
    736 *   @param eSyncOperation
    737 *       Synchronization operation that is being taken to get
    738 *       streams in sync.
    739 * */
    740 #define PERF_SyncAV(       \
    741         hObject,           \
    742         fTimeAudio,        \
    743         fTimeVideo,        \
    744         eSyncOperation)    \
    745   do {                     \
    746   __PERF_Location(hObject) \
    747     __PERF_FN(SyncAV)(hObject, fTimeAudio, fTimeVideo, eSyncOperation); \
    748   } while (0)
    749 
    750 /** The PERF_TheadCreated method shall be called after creating
    751 *   a new thread.
    752 *   @param hObject
    753 *       Handle to the PERF object.
    754 *   @param pfTimeAudio
    755 *       Time stamp of audio frame
    756 *   @param pfTimeVideo
    757 *       Time stamp of video frame
    758 *   @param eSyncOperation
    759 *       Synchronization operation that is being taken to get
    760 *       streams in sync.
    761 * */
    762 #define PERF_ThreadCreated( \
    763         hObject,            \
    764         ulThreadID,         \
    765         ulThreadName)       \
    766   do {                      \
    767   __PERF_Location(hObject)  \
    768     __PERF_FN(ThreadCreated)(hObject, ulThreadID, ulThreadName); \
    769   }  while (0)
    770 
    771 /** The PERF_Log method can be called to log 3 values into the
    772 *   log.  The 1st argument is capped at 28 bits.
    773 *   @param hObject
    774 *       Handle to the PERF object.
    775 *   @param ulData1, ulData2, ulData3
    776 *       Data to be logged
    777 * */
    778 #define PERF_Log( \
    779         hObject,  \
    780         ulData1,  \
    781         ulData2,  \
    782         ulData3)  \
    783   do {            \
    784   __PERF_Location(hObject) \
    785     __PERF_FN(Log)(hObject, ulData1, ulData2, ulData3);\
    786   } while (0)
    787 
    788 /* define PERF_OBJ and the used __PERF macros */
    789 #include "perf_obj.h"
    790 
    791 #endif /* __PERF_INSTURMENTATION__ */
    792 
    793 #endif /* __PERF_H__ */
    794 
    795 
    796