Home | History | Annotate | Download | only in src
      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 /* NOTE: This source file should be only included from perf.c */
     22 
     23 /*=============================================================================
     24     CUSTOMIZABLE INTERFACES
     25 =============================================================================*/
     26 
     27 #include "perf_config.h"
     28 #include "perf_print.h"
     29 #include "perf_rt.h"
     30 
     31 void __PERF_CUSTOM_setup_for_log_only(PERF_OBJHANDLE hObject);
     32 void __PERF_CUSTOM_setup_common(PERF_OBJHANDLE hObject);
     33 
     34 /*=============================================================================
     35     time stamp methods
     36 =============================================================================*/
     37 
     38 INLINEORSTATIC
     39 void get_time(PERF_Private *me)
     40 {
     41     /* get replay tempTime if replaying */
     42     if (me->uMode & PERF_Mode_Replay) return;
     43 
     44     /* otherwise, get time of the day */
     45     TIME_GET(me->time);
     46 }
     47 
     48 /** Customizable PERF interfaces for logging only.  These
     49  *  correspond -- and are wrappers -- to the __PERF macros */
     50 static
     51 void __log_Boundary(PERF_OBJHANDLE hObject,
     52                     PERF_BOUNDARYTYPE eBoundary)
     53 {
     54     __PERF_LOG_Boundary(hObject, eBoundary);
     55 }
     56 
     57 static
     58 void __log_Buffer(PERF_OBJHANDLE hObject,
     59                   unsigned long ulAddress1,
     60                   unsigned long ulAddress2,
     61                   unsigned long ulSize,
     62                   unsigned long ulModuleAndFlags)
     63 {
     64     __PERF_LOG_Buffer(hObject,
     65                       PERF_GetXferSendRecv(ulModuleAndFlags),
     66                       ulModuleAndFlags & PERF_FlagMultiple,
     67                       ulModuleAndFlags & PERF_FlagFrame,
     68                       ulAddress1,
     69                       ulAddress2,
     70                       ulSize,
     71                       ulModuleAndFlags & PERF_ModuleMask,
     72 					  (ulModuleAndFlags >> PERF_ModuleBits) & PERF_ModuleMask);
     73 }
     74 
     75 static
     76 void __log_Command(PERF_OBJHANDLE hObject,
     77                    unsigned long ulCommand,
     78 				   unsigned long ulArgument,
     79                    unsigned long ulModuleAndFlags)
     80 {
     81     __PERF_LOG_Command(hObject,
     82                        PERF_GetSendRecv(ulModuleAndFlags),
     83                        ulCommand,
     84 					   ulArgument,
     85                        ulModuleAndFlags & PERF_ModuleMask);
     86 }
     87 
     88 static
     89 void __log_Log(PERF_OBJHANDLE hObject,
     90                unsigned long ulData1,
     91                unsigned long ulData2,
     92                unsigned long ulData3)
     93 {
     94     __PERF_LOG_Log(hObject, ulData1, ulData2, ulData3);
     95 }
     96 
     97 static
     98 void __log_SyncAV(PERF_OBJHANDLE hObject,
     99                   float fTimeAudio,
    100                   float fTimeVideo,
    101                   PERF_SYNCOPTYPE eSyncOperation)
    102 {
    103     __PERF_LOG_SyncAV(hObject, fTimeAudio, fTimeVideo, eSyncOperation);
    104 }
    105 
    106 static
    107 void __log_ThreadCreated(PERF_OBJHANDLE hObject,
    108                          unsigned long ulThreadID,
    109                          unsigned long ulThreadName)
    110 {
    111     __PERF_LOG_ThreadCreated(hObject, ulThreadID, ulThreadName);
    112 }
    113 
    114 /** Customizable PERF interfaces for all operations other than
    115  *  logging only. These correspond to the __PERF macros */
    116 
    117 static
    118 void __common_Boundary(PERF_OBJHANDLE hObject,
    119                        PERF_BOUNDARYTYPE eBoundary)
    120 {
    121     PERF_Private *me  = get_Private(hObject);
    122 
    123     if (me->pLog)
    124     {   /* perform log specific operations */
    125         __log_Boundary(hObject, eBoundary);
    126     }
    127     else
    128     {   /* we need to get the time stamp to print */
    129         get_time(me);
    130     }
    131 
    132     if (me->cip.pDebug)
    133     {
    134         __print_Boundary(me->cip.pDebug->fDebug,
    135                          me, eBoundary);
    136     }
    137 
    138     if (me->cip.pRT)
    139     {
    140         __rt_Boundary(me, eBoundary);
    141     }
    142 }
    143 
    144 static
    145 void __common_Buffer(PERF_OBJHANDLE hObject,
    146                      unsigned long ulAddress1,
    147                      unsigned long ulAddress2,
    148                      unsigned long ulSize,
    149                      unsigned long ulModuleAndFlags)
    150 {
    151     PERF_Private *me  = get_Private(hObject);
    152 
    153     if (me->pLog)
    154     {   /* perform log specific operations */
    155         __log_Buffer(hObject, ulAddress1, ulAddress2, ulSize, ulModuleAndFlags);
    156     }
    157     else
    158     {   /* we need to get the time stamp to print */
    159         get_time(me);
    160     }
    161 
    162     if (me->cip.pDebug && me->cip.pDebug->fPrint)
    163     {
    164         __print_Buffer(me->cip.pDebug->fPrint,
    165                        me, ulAddress1, ulAddress2, ulSize, ulModuleAndFlags);
    166     }
    167 
    168     if (me->cip.pRT)
    169     {
    170         __rt_Buffer(me, ulAddress1, ulAddress2, ulSize, ulModuleAndFlags);
    171     }
    172 }
    173 
    174 static
    175 void __common_Command(PERF_OBJHANDLE hObject,
    176                       unsigned long ulCommand,
    177 					  unsigned long ulArgument,
    178                       unsigned long ulModuleAndFlags)
    179 {
    180     PERF_Private *me  = get_Private(hObject);
    181 
    182     if (me->pLog)
    183     {   /* perform log specific operations */
    184         __log_Command(hObject, ulCommand, ulArgument, ulModuleAndFlags);
    185     }
    186     else
    187     {   /* we need to get the time stamp to print */
    188         get_time(me);
    189     }
    190 
    191     if (me->cip.pDebug && me->cip.pDebug->fDebug)
    192     {
    193         __print_Command(me->cip.pDebug->fDebug,
    194                         me, ulCommand, ulArgument, ulModuleAndFlags);
    195     }
    196 
    197     if (me->cip.pRT)
    198     {
    199         __rt_Command(me, ulCommand, ulArgument, ulModuleAndFlags);
    200     }
    201 }
    202 
    203 static
    204 void __common_Log(PERF_OBJHANDLE hObject,
    205                   unsigned long ulData1,
    206                   unsigned long ulData2,
    207                   unsigned long ulData3)
    208 {
    209     PERF_Private *me  = get_Private(hObject);
    210 
    211     if (me->pLog)
    212     {   /* perform log specific operations */
    213         __log_Log(hObject, ulData1, ulData2, ulData3);
    214     }
    215     else
    216     {   /* we need to get the time stamp to print */
    217         get_time(me);
    218     }
    219 
    220     if (me->cip.pDebug && me->cip.pDebug->fDebug)
    221     {
    222         __print_Log(me->cip.pDebug->fDebug,
    223                     me, ulData1, ulData2, ulData3);
    224     }
    225 
    226     if (me->cip.pRT)
    227     {
    228         __rt_Log(me, ulData1, ulData2, ulData3);
    229     }
    230 }
    231 
    232 static
    233 void __common_SyncAV(PERF_OBJHANDLE hObject,
    234                      float pfTimeAudio,
    235                      float pfTimeVideo,
    236                      PERF_SYNCOPTYPE eSyncOperation)
    237 {
    238     PERF_Private *me  = get_Private(hObject);
    239 
    240     if (me->pLog)
    241     {   /* perform log specific operations */
    242         __log_SyncAV(hObject, pfTimeAudio, pfTimeVideo, eSyncOperation);
    243     }
    244     else
    245     {   /* we need to get the time stamp to print */
    246         get_time(me);
    247     }
    248 
    249     if (me->cip.pDebug && me->cip.pDebug->fDebug)
    250     {
    251         __print_SyncAV(me->cip.pDebug->fDebug,
    252                        me, pfTimeAudio, pfTimeVideo, eSyncOperation);
    253     }
    254 
    255     if (me->cip.pRT)
    256     {
    257         __rt_SyncAV(me, pfTimeAudio, pfTimeVideo, eSyncOperation);
    258     }
    259 }
    260 
    261 static
    262 void __common_ThreadCreated(PERF_OBJHANDLE hObject,
    263                             unsigned long ulThreadID,
    264                             unsigned long ulThreadName)
    265 {
    266     PERF_Private *me  = get_Private(hObject);
    267 
    268     if (me->pLog)
    269     {   /* perform log specific operations */
    270         __log_ThreadCreated(hObject, ulThreadID, ulThreadName);
    271     }
    272     else
    273     {   /* we need to get the time stamp to print */
    274         get_time(me);
    275     }
    276 
    277     if (me->cip.pDebug && me->cip.pDebug->fDebug)
    278     {
    279         __print_ThreadCreated(me->cip.pDebug->fDebug,
    280                               me, ulThreadID, ulThreadName);
    281     }
    282 
    283     if (me->cip.pRT)
    284     {
    285         __rt_ThreadCreated(me, ulThreadID, ulThreadName);
    286     }
    287 }
    288 
    289 #ifdef __PERF_LOG_LOCATION__
    290 static
    291 void __log_Location(PERF_OBJHANDLE hObject,
    292                    char const *szFile,
    293 				   unsigned long ulLine,
    294                    char const *szFunc)
    295 {
    296     __PERF_LOG_Location(hObject,
    297                         szFile,
    298                         ulLine,
    299                         szFunc);
    300 }
    301 
    302 static
    303 void __common_Location(PERF_OBJHANDLE hObject,
    304                             char const *szFile,
    305 				   unsigned long ulLine,
    306                    char const *szFunc)
    307 {
    308     PERF_Private *me  = get_Private(hObject);
    309 
    310     if (me->pLog)
    311     {   /* perform log specific operations */
    312         __log_Location(hObject, szFile, ulLine, szFunc);
    313     }
    314 
    315     if (me->cip.pDebug && me->cip.pDebug->fDebug)
    316     {
    317         __print_Location(me, szFile, ulLine, szFunc);
    318     }
    319 }
    320 #endif
    321 
    322 
    323 void
    324 __PERF_CUSTOM_setup_common(PERF_OBJHANDLE hObject)
    325 {
    326     hObject->ci.Boundary      = __common_Boundary;
    327     hObject->ci.Buffer        = __common_Buffer;
    328     hObject->ci.Command       = __common_Command;
    329     hObject->ci.Log           = __common_Log;
    330     hObject->ci.SyncAV        = __common_SyncAV;
    331     hObject->ci.ThreadCreated = __common_ThreadCreated;
    332 #ifdef __PERF_LOG_LOCATION__
    333     hObject->ci.Location      = __common_Location;
    334 #endif
    335 }
    336 
    337 void
    338 __PERF_CUSTOM_setup_for_log_only(PERF_OBJHANDLE hObject)
    339 {
    340     hObject->ci.Boundary      = __log_Boundary;
    341     hObject->ci.Buffer        = __log_Buffer;
    342     hObject->ci.Command       = __log_Command;
    343     hObject->ci.Log           = __log_Log;
    344     hObject->ci.SyncAV        = __log_SyncAV;
    345     hObject->ci.ThreadCreated = __log_ThreadCreated;
    346 #ifdef __PERF_LOG_LOCATION__
    347     hObject->ci.Location      = __log_Location;
    348 #endif
    349 }
    350 
    351 void
    352 __PERF_CUSTOM_create(PERF_OBJHANDLE hObject, PERF_Config *config,
    353                      PERF_MODULETYPE eModule)
    354 {
    355     PERF_Private *me = get_Private(hObject);
    356 
    357     /* initialize custom fields of the PERF_Private */
    358     me->cip.pDebug = NULL;
    359     me->cip.pRT = NULL;
    360 
    361     /* add replay flag and set log file to the replay file so that replayed
    362        prints are saved into the log (replay) file */
    363     if (config->replay_file)
    364     {
    365         me->uMode |= PERF_Mode_Replay;
    366 
    367         if (config->log_file) free(config->log_file);
    368         config->log_file    = config->replay_file;
    369         config->replay_file = NULL;
    370 
    371         /** we need to get time stamps set up before we continue
    372             at the 2nd call, replay_file is already NULL so we will
    373             proceed */
    374         return;
    375     }
    376 
    377     /* handle correct output (debug and debug log) */
    378     if (config->log_file || config->debug || config->detailed_debug)
    379     {
    380         /* check if we could create the print structure */
    381         if (!PERF_PRINT_create(me, config, eModule))
    382         {
    383             /* if not, delete replay flag */
    384             me->uMode &= ~PERF_Mode_Replay;
    385         }
    386     }
    387 
    388     /* handle correct output (debug and debug log) */
    389     if (config->realtime)
    390     {
    391         /* check if we could create the print structure */
    392         PERF_RT_create(me, config, eModule);
    393     }
    394 
    395     /* THIS has to be done at the end:
    396        if we are only logging, we set up the function table to the log shortcut
    397        interface for speed.  Otherwise, we set them to the common interface */
    398     if (me->uMode == PERF_Mode_Log)
    399     {
    400         __PERF_CUSTOM_setup_for_log_only(hObject);
    401     }
    402     else
    403     {
    404         __PERF_CUSTOM_setup_common(hObject);
    405     }
    406 }
    407 
    408 void __PERF_CUSTOM_done(PERF_Private *me)
    409 {
    410     if (me->uMode & PERF_Mode_Log)
    411     {   /* close log */
    412         __PERF_LOG_done(me);
    413     }
    414     else
    415     {
    416         get_time(me);
    417     }
    418 
    419     /* Complete any debug structures */
    420     if (me->cip.pDebug)
    421     {
    422 		if (me->cip.pDebug->fDebug) __print_Done(me->cip.pDebug->fDebug, me);
    423         PERF_PRINT_done(me);
    424     }
    425 
    426     if (me->cip.pRT)
    427     {
    428         __rt_Done(me);
    429         PERF_RT_done(me);
    430     }
    431 }
    432 
    433